@nyaruka/temba-components 0.129.8 → 0.129.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +27 -3
- package/demo/data/flows/sample-flow.json +186 -96
- package/dist/temba-components.js +414 -351
- package/dist/temba-components.js.map +1 -1
- package/out-tsc/src/events.js.map +1 -1
- package/out-tsc/src/excellent/helpers.js +2 -2
- package/out-tsc/src/excellent/helpers.js.map +1 -1
- package/out-tsc/src/flow/CanvasNode.js +25 -7
- package/out-tsc/src/flow/CanvasNode.js.map +1 -1
- package/out-tsc/src/flow/Editor.js +11 -1
- package/out-tsc/src/flow/Editor.js.map +1 -1
- package/out-tsc/src/flow/NodeEditor.js +133 -290
- package/out-tsc/src/flow/NodeEditor.js.map +1 -1
- package/out-tsc/src/flow/actions/add_input_labels.js +40 -0
- package/out-tsc/src/flow/actions/add_input_labels.js.map +1 -1
- package/out-tsc/src/flow/actions/call_llm.js +56 -3
- package/out-tsc/src/flow/actions/call_llm.js.map +1 -1
- package/out-tsc/src/flow/actions/call_webhook.js +1 -1
- package/out-tsc/src/flow/actions/call_webhook.js.map +1 -1
- package/out-tsc/src/flow/actions/open_ticket.js +65 -3
- package/out-tsc/src/flow/actions/open_ticket.js.map +1 -1
- package/out-tsc/src/flow/actions/set_run_result.js +75 -0
- package/out-tsc/src/flow/actions/set_run_result.js.map +1 -1
- package/out-tsc/src/flow/config.js +4 -0
- package/out-tsc/src/flow/config.js.map +1 -1
- package/out-tsc/src/flow/nodes/split_by_llm_categorize.js +227 -0
- package/out-tsc/src/flow/nodes/split_by_llm_categorize.js.map +1 -0
- package/out-tsc/src/flow/nodes/split_by_ticket.js +18 -0
- package/out-tsc/src/flow/nodes/split_by_ticket.js.map +1 -0
- package/out-tsc/src/flow/nodes/wait_for_response.js +27 -1
- package/out-tsc/src/flow/nodes/wait_for_response.js.map +1 -1
- package/out-tsc/src/flow/types.js +0 -65
- package/out-tsc/src/flow/types.js.map +1 -1
- package/out-tsc/src/form/ArrayEditor.js +18 -61
- package/out-tsc/src/form/ArrayEditor.js.map +1 -1
- package/out-tsc/src/form/FieldRenderer.js +305 -0
- package/out-tsc/src/form/FieldRenderer.js.map +1 -0
- package/out-tsc/src/form/FormField.js +3 -3
- package/out-tsc/src/form/FormField.js.map +1 -1
- package/out-tsc/src/form/TextInput.js +1 -1
- package/out-tsc/src/form/TextInput.js.map +1 -1
- package/out-tsc/src/form/select/Select.js +48 -20
- package/out-tsc/src/form/select/Select.js.map +1 -1
- package/out-tsc/src/live/ContactChat.js +39 -13
- package/out-tsc/src/live/ContactChat.js.map +1 -1
- package/out-tsc/src/markdown.js +13 -11
- package/out-tsc/src/markdown.js.map +1 -1
- package/out-tsc/test/ActionHelper.js +2 -0
- package/out-tsc/test/ActionHelper.js.map +1 -1
- package/out-tsc/test/NodeHelper.js +148 -0
- package/out-tsc/test/NodeHelper.js.map +1 -0
- package/out-tsc/test/actions/call_llm.test.js +103 -0
- package/out-tsc/test/actions/call_llm.test.js.map +1 -0
- package/out-tsc/test/nodes/split_by_llm_categorize.test.js +532 -0
- package/out-tsc/test/nodes/split_by_llm_categorize.test.js.map +1 -0
- package/out-tsc/test/nodes/split_by_random.test.js +150 -0
- package/out-tsc/test/nodes/split_by_random.test.js.map +1 -0
- package/out-tsc/test/nodes/wait_for_digits.test.js +150 -0
- package/out-tsc/test/nodes/wait_for_digits.test.js.map +1 -0
- package/out-tsc/test/nodes/wait_for_response.test.js +171 -0
- package/out-tsc/test/nodes/wait_for_response.test.js.map +1 -0
- package/out-tsc/test/temba-add-input-labels.test.js +70 -0
- package/out-tsc/test/temba-add-input-labels.test.js.map +1 -0
- package/out-tsc/test/temba-field-renderer.test.js +296 -0
- package/out-tsc/test/temba-field-renderer.test.js.map +1 -0
- package/out-tsc/test/temba-markdown.test.js +1 -1
- package/out-tsc/test/temba-markdown.test.js.map +1 -1
- package/out-tsc/test/temba-node-editor.test.js +400 -0
- package/out-tsc/test/temba-node-editor.test.js.map +1 -1
- package/out-tsc/test/temba-select.test.js +6 -3
- package/out-tsc/test/temba-select.test.js.map +1 -1
- package/out-tsc/test/temba-webchat.test.js +1 -1
- package/out-tsc/test/temba-webchat.test.js.map +1 -1
- package/package.json +1 -1
- package/screenshots/truth/actions/add_contact_groups/editor/descriptive-group-names.png +0 -0
- package/screenshots/truth/actions/add_contact_groups/editor/long-group-names.png +0 -0
- package/screenshots/truth/actions/add_contact_groups/editor/many-groups.png +0 -0
- package/screenshots/truth/actions/call_llm/editor/information-extraction.png +0 -0
- package/screenshots/truth/actions/call_llm/editor/sentiment-analysis.png +0 -0
- package/screenshots/truth/actions/call_llm/editor/summarization.png +0 -0
- package/screenshots/truth/actions/call_llm/editor/translation-task.png +0 -0
- package/screenshots/truth/actions/call_llm/render/information-extraction.png +0 -0
- package/screenshots/truth/actions/call_llm/render/sentiment-analysis.png +0 -0
- package/screenshots/truth/actions/call_llm/render/summarization.png +0 -0
- package/screenshots/truth/actions/call_llm/render/translation-task.png +0 -0
- package/screenshots/truth/actions/remove_contact_groups/editor/long-descriptive-group-names.png +0 -0
- package/screenshots/truth/actions/remove_contact_groups/editor/many-groups.png +0 -0
- package/screenshots/truth/actions/remove_contact_groups/editor/remove-from-all-groups.png +0 -0
- package/screenshots/truth/actions/send_email/editor/complex-business-email.png +0 -0
- package/screenshots/truth/actions/send_email/editor/multiple-recipients.png +0 -0
- package/screenshots/truth/actions/send_msg/editor/long-quick-replies.png +0 -0
- package/screenshots/truth/actions/send_msg/editor/multiline-text-with-replies.png +0 -0
- package/screenshots/truth/actions/send_msg/editor/simple-text.png +0 -0
- package/screenshots/truth/actions/send_msg/editor/text-with-linebreaks.png +0 -0
- package/screenshots/truth/actions/send_msg/editor/text-with-many-quick-replies.png +0 -0
- package/screenshots/truth/actions/send_msg/editor/text-with-quick-replies.png +0 -0
- package/screenshots/truth/actions/send_msg/editor/text-without-quick-replies.png +0 -0
- package/screenshots/truth/editor/router.png +0 -0
- package/screenshots/truth/editor/send_msg.png +0 -0
- package/screenshots/truth/editor/set_contact_language.png +0 -0
- package/screenshots/truth/editor/set_contact_name.png +0 -0
- package/screenshots/truth/editor/set_run_result.png +0 -0
- package/screenshots/truth/editor/wait.png +0 -0
- package/screenshots/truth/field-renderer/checkbox-checked.png +0 -0
- package/screenshots/truth/field-renderer/checkbox-unchecked.png +0 -0
- package/screenshots/truth/field-renderer/checkbox-with-errors.png +0 -0
- package/screenshots/truth/field-renderer/context-comparison.png +0 -0
- package/screenshots/truth/field-renderer/key-value-with-label.png +0 -0
- package/screenshots/truth/field-renderer/message-editor-with-label.png +0 -0
- package/screenshots/truth/field-renderer/select-multi.png +0 -0
- package/screenshots/truth/field-renderer/select-no-label.png +0 -0
- package/screenshots/truth/field-renderer/select-with-label.png +0 -0
- package/screenshots/truth/field-renderer/text-evaluated.png +0 -0
- package/screenshots/truth/field-renderer/text-no-label.png +0 -0
- package/screenshots/truth/field-renderer/text-with-errors.png +0 -0
- package/screenshots/truth/field-renderer/text-with-label.png +0 -0
- package/screenshots/truth/field-renderer/textarea-evaluated.png +0 -0
- package/screenshots/truth/field-renderer/textarea-with-label.png +0 -0
- package/screenshots/truth/nodes/split_by_llm_categorize/editor/basic-categorization.png +0 -0
- package/screenshots/truth/nodes/split_by_llm_categorize/editor/custom-input-and-result-name.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/editor/many-categories.png +0 -0
- package/screenshots/truth/nodes/split_by_llm_categorize/editor/minimal-categories.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/editor/ab-test-multiple-variants.png +0 -0
- package/screenshots/truth/nodes/split_by_random/editor/sampling-split.png +0 -0
- package/screenshots/truth/nodes/split_by_random/editor/three-way-split.png +0 -0
- package/screenshots/truth/nodes/split_by_random/editor/two-bucket-split.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/editor/basic-digits-wait.png +0 -0
- package/screenshots/truth/nodes/wait_for_digits/editor/phone-number-collection.png +0 -0
- package/screenshots/truth/nodes/wait_for_digits/editor/single-digit-with-timeout.png +0 -0
- package/screenshots/truth/nodes/wait_for_digits/editor/verification-code.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/editor/basic-wait.png +0 -0
- package/screenshots/truth/nodes/wait_for_response/editor/custom-result-name.png +0 -0
- package/screenshots/truth/nodes/wait_for_response/editor/no-timeout.png +0 -0
- package/screenshots/truth/nodes/wait_for_response/editor/short-timeout.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/screenshots/truth/omnibox/selected.png +0 -0
- package/screenshots/truth/select/functions.png +0 -0
- package/screenshots/truth/select/multi-with-endpoint.png +0 -0
- package/screenshots/truth/select/search-enabled.png +0 -0
- package/src/events.ts +8 -1
- package/src/excellent/helpers.ts +2 -2
- package/src/flow/CanvasNode.ts +22 -1
- package/src/flow/Editor.ts +12 -1
- package/src/flow/NodeEditor.ts +186 -374
- package/src/flow/actions/add_input_labels.ts +45 -0
- package/src/flow/actions/call_llm.ts +57 -3
- package/src/flow/actions/call_webhook.ts +1 -1
- package/src/flow/actions/open_ticket.ts +74 -3
- package/src/flow/actions/set_run_result.ts +83 -0
- package/src/flow/config.ts +4 -0
- package/src/flow/nodes/split_by_llm_categorize.ts +277 -0
- package/src/flow/nodes/split_by_ticket.ts +19 -0
- package/src/flow/nodes/wait_for_response.ts +28 -1
- package/src/flow/types.ts +26 -127
- package/src/form/ArrayEditor.ts +34 -82
- package/src/form/FieldRenderer.ts +465 -0
- package/src/form/FormField.ts +3 -3
- package/src/form/TextInput.ts +1 -1
- package/src/form/select/Select.ts +51 -20
- package/src/live/ContactChat.ts +39 -15
- package/src/markdown.ts +19 -11
- package/src/store/flow-definition.d.ts +5 -2
- package/static/api/labels.json +31 -0
- package/static/api/topics.json +24 -9
- package/static/api/users.json +35 -16
- package/static/css/temba-components.css +3 -3
- package/stress-test.js +18 -13
- package/test/ActionHelper.ts +2 -0
- package/test/NodeHelper.ts +184 -0
- package/test/actions/call_llm.test.ts +137 -0
- package/test/nodes/README.md +78 -0
- package/test/nodes/split_by_llm_categorize.test.ts +698 -0
- package/test/nodes/split_by_random.test.ts +177 -0
- package/test/nodes/wait_for_digits.test.ts +176 -0
- package/test/nodes/wait_for_response.test.ts +206 -0
- package/test/temba-add-input-labels.test.ts +87 -0
- package/test/temba-field-renderer.test.ts +482 -0
- package/test/temba-markdown.test.ts +1 -1
- package/test/temba-node-editor.test.ts +496 -0
- package/test/temba-select.test.ts +6 -6
- package/test/temba-webchat.test.ts +1 -1
- package/test-assets/select/llms.json +18 -0
- package/web-dev-mock.mjs +96 -6
- package/web-dev-server.config.mjs +29 -7
- package/test/temba-flow-editor.test.ts.backup +0 -563
- package/test/temba-utils-index.test.ts.backup +0 -1737
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { expect } from '@open-wc/testing';
|
|
2
|
+
import { call_llm } from '../../src/flow/actions/call_llm';
|
|
3
|
+
import { CallLLM } from '../../src/store/flow-definition';
|
|
4
|
+
import { ActionTest } from '../ActionHelper';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Test suite for the call_llm action configuration.
|
|
8
|
+
*/
|
|
9
|
+
describe('call_llm action config', () => {
|
|
10
|
+
const helper = new ActionTest(call_llm, 'call_llm');
|
|
11
|
+
|
|
12
|
+
describe('basic properties', () => {
|
|
13
|
+
helper.testBasicProperties();
|
|
14
|
+
|
|
15
|
+
it('has correct name', () => {
|
|
16
|
+
expect(call_llm.name).to.equal('Call AI');
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
it('has form configuration', () => {
|
|
20
|
+
expect(call_llm.form).to.exist;
|
|
21
|
+
expect(call_llm.form.llm).to.exist;
|
|
22
|
+
expect(call_llm.form.instructions).to.exist;
|
|
23
|
+
expect(call_llm.form.input).to.exist;
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it('has layout configuration', () => {
|
|
27
|
+
expect(call_llm.layout).to.exist;
|
|
28
|
+
expect(call_llm.layout).to.deep.equal(['llm', 'input', 'instructions']);
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it('has data transformation functions', () => {
|
|
32
|
+
expect(call_llm.toFormData).to.be.a('function');
|
|
33
|
+
expect(call_llm.fromFormData).to.be.a('function');
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
describe('data transformations', () => {
|
|
38
|
+
it('converts action to form data correctly', () => {
|
|
39
|
+
const action: CallLLM = {
|
|
40
|
+
uuid: 'test-llm-1',
|
|
41
|
+
type: 'call_llm',
|
|
42
|
+
input: '@input',
|
|
43
|
+
llm: { uuid: 'gpt-4', name: 'GPT 4.1' },
|
|
44
|
+
instructions: 'Translate to French',
|
|
45
|
+
result_name: 'translated_text'
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
const formData = call_llm.toFormData(action);
|
|
49
|
+
|
|
50
|
+
expect(formData.uuid).to.equal('test-llm-1');
|
|
51
|
+
expect(formData.llm).to.deep.equal([{ value: 'gpt-4', name: 'GPT 4.1' }]);
|
|
52
|
+
expect(formData.instructions).to.equal('Translate to French');
|
|
53
|
+
expect(formData.input).to.equal('@input');
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
it('converts form data to action correctly', () => {
|
|
57
|
+
const formData = {
|
|
58
|
+
uuid: 'test-llm-2',
|
|
59
|
+
llm: [{ value: 'gpt-5', name: 'GPT 5' }],
|
|
60
|
+
instructions: 'Summarize the following text',
|
|
61
|
+
input: '@input'
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
const action = call_llm.fromFormData(formData) as CallLLM;
|
|
65
|
+
|
|
66
|
+
expect(action.uuid).to.equal('test-llm-2');
|
|
67
|
+
expect(action.type).to.equal('call_llm');
|
|
68
|
+
expect(action.llm).to.deep.equal({ uuid: 'gpt-5', name: 'GPT 5' });
|
|
69
|
+
expect(action.instructions).to.equal('Summarize the following text');
|
|
70
|
+
expect(action.input).to.equal('@input');
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
it('handles empty form data', () => {
|
|
74
|
+
const formData = {
|
|
75
|
+
uuid: 'test-llm-3',
|
|
76
|
+
llm: [],
|
|
77
|
+
instructions: '',
|
|
78
|
+
input: ''
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
const action = call_llm.fromFormData(formData) as CallLLM;
|
|
82
|
+
|
|
83
|
+
expect(action.llm).to.deep.equal({ uuid: '', name: '' });
|
|
84
|
+
expect(action.instructions).to.equal('');
|
|
85
|
+
expect(action.input).to.equal('@input');
|
|
86
|
+
});
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
describe('action scenarios', () => {
|
|
90
|
+
helper.testAction(
|
|
91
|
+
{
|
|
92
|
+
uuid: 'test-action-1',
|
|
93
|
+
type: 'call_llm',
|
|
94
|
+
llm: { uuid: 'gpt-4', name: 'GPT 4.1' },
|
|
95
|
+
instructions: 'Translate to French',
|
|
96
|
+
input: '@input'
|
|
97
|
+
} as CallLLM,
|
|
98
|
+
'translation-task'
|
|
99
|
+
);
|
|
100
|
+
|
|
101
|
+
helper.testAction(
|
|
102
|
+
{
|
|
103
|
+
uuid: 'test-action-2',
|
|
104
|
+
type: 'call_llm',
|
|
105
|
+
llm: { uuid: 'gpt-5', name: 'GPT 5' },
|
|
106
|
+
instructions:
|
|
107
|
+
'Analyze the sentiment of the following message and classify it as positive, negative, or neutral. Provide a brief explanation for your classification.',
|
|
108
|
+
input: '@input'
|
|
109
|
+
} as CallLLM,
|
|
110
|
+
'sentiment-analysis'
|
|
111
|
+
);
|
|
112
|
+
|
|
113
|
+
helper.testAction(
|
|
114
|
+
{
|
|
115
|
+
uuid: 'test-action-3',
|
|
116
|
+
type: 'call_llm',
|
|
117
|
+
llm: { uuid: 'gpt-4', name: 'GPT 4.1' },
|
|
118
|
+
instructions:
|
|
119
|
+
'Summarize the key points from the conversation above in bullet format.',
|
|
120
|
+
input: '@input'
|
|
121
|
+
} as CallLLM,
|
|
122
|
+
'summarization'
|
|
123
|
+
);
|
|
124
|
+
|
|
125
|
+
helper.testAction(
|
|
126
|
+
{
|
|
127
|
+
uuid: 'test-action-4',
|
|
128
|
+
type: 'call_llm',
|
|
129
|
+
llm: { uuid: 'gpt-5', name: 'GPT 5' },
|
|
130
|
+
instructions:
|
|
131
|
+
'Extract any contact information (phone numbers, email addresses) from the text and format them as a JSON object.',
|
|
132
|
+
input: '@input'
|
|
133
|
+
} as CallLLM,
|
|
134
|
+
'information-extraction'
|
|
135
|
+
);
|
|
136
|
+
});
|
|
137
|
+
});
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# Node Configuration Tests
|
|
2
|
+
|
|
3
|
+
This directory contains tests for node configurations using the `NodeHelper` testing framework.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
Similar to how the `ActionHelper` provides a uniform testing strategy for action configurations, the `NodeHelper` class provides a structured approach to testing node configurations. It handles:
|
|
8
|
+
|
|
9
|
+
1. **Rendering Tests**: Verifies nodes render correctly in the flow editor
|
|
10
|
+
2. **Editor Tests**: Verifies the node editor opens and displays correctly
|
|
11
|
+
3. **Round-trip Conversion**: Tests form data conversion for nodes with `toFormData`/`fromFormData`
|
|
12
|
+
4. **Screenshot Testing**: Captures visual screenshots for regression testing
|
|
13
|
+
|
|
14
|
+
## Test Structure
|
|
15
|
+
|
|
16
|
+
Each node test file follows this pattern:
|
|
17
|
+
|
|
18
|
+
```typescript
|
|
19
|
+
import { expect } from '@open-wc/testing';
|
|
20
|
+
import { node_config } from '../../src/flow/nodes/node_config';
|
|
21
|
+
import { Node } from '../../src/store/flow-definition';
|
|
22
|
+
import { NodeTest } from '../NodeHelper';
|
|
23
|
+
|
|
24
|
+
describe('node_config node config', () => {
|
|
25
|
+
const helper = new NodeTest(node_config, 'node_config');
|
|
26
|
+
|
|
27
|
+
describe('basic properties', () => {
|
|
28
|
+
helper.testBasicProperties();
|
|
29
|
+
|
|
30
|
+
// Additional property tests...
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
describe('node scenarios', () => {
|
|
34
|
+
helper.testNode(nodeData, nodeUI, 'test-name');
|
|
35
|
+
|
|
36
|
+
// More scenarios...
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
// Optional: data transformation tests for nodes with form configuration
|
|
40
|
+
describe('data transformation', () => {
|
|
41
|
+
// Round-trip conversion tests...
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Node Types Covered
|
|
47
|
+
|
|
48
|
+
### Simple Nodes
|
|
49
|
+
|
|
50
|
+
- `wait_for_digits`: Basic node with no form configuration
|
|
51
|
+
- `wait_for_audio`, `wait_for_image`, etc.: Similar wait nodes
|
|
52
|
+
|
|
53
|
+
### Form-Configured Nodes
|
|
54
|
+
|
|
55
|
+
- `wait_for_response`: Node with form fields and data transformation
|
|
56
|
+
- `split_by_llm_categorize`: Complex node with form configuration
|
|
57
|
+
|
|
58
|
+
### Router-Based Nodes
|
|
59
|
+
|
|
60
|
+
- `split_by_random`: Random distribution node
|
|
61
|
+
- Other split nodes with router configurations
|
|
62
|
+
|
|
63
|
+
## Screenshots
|
|
64
|
+
|
|
65
|
+
Screenshots are automatically generated and stored in:
|
|
66
|
+
|
|
67
|
+
- `screenshots/nodes/{node_name}/render/{test_name}.png` - Flow editor rendering
|
|
68
|
+
- `screenshots/nodes/{node_name}/editor/{test_name}.png` - Node editor dialog
|
|
69
|
+
|
|
70
|
+
## Running Tests
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
# Run all node tests
|
|
74
|
+
yarn test test/nodes/*.test.ts --no-watch
|
|
75
|
+
|
|
76
|
+
# Run specific node test
|
|
77
|
+
yarn test test/nodes/wait_for_response.test.ts --no-watch
|
|
78
|
+
```
|