Test a draft without running the bot
Test an unsaved sequence using sample data, inspect selected branches and save examples for later changes.
בעמוד זה
After changing a calculation, adding a branch or extracting a block, test the entire draft with a supplied event and sample service responses before saving it.
Testing evaluates calculations and selects branches from the current draft. Messages, record changes and external requests appear as intended effects. It does not send messages, charge money, invoke real AI or change production collections.
This is a separate editor mode and requires no separate bot. Running a reaction normally in chat still performs real actions.
The editor also supports running a saved reaction for a selected recipient. That run can send a real message and perform production actions. Use draft testing to check unsaved changes with sample data.
Read access lets you check a draft and open saved examples. Creating a new saved example requires write access. Editing temporary test inputs does not change the reaction itself.
Lesson 1. Test an unsaved sequence
- Open a new reaction or edit an existing one. Saving is not required for testing.
- Click Draft check. Set Event type to Text and enter
/confirmin Event text. For a Command event, fill Command without slash, for exampleconfirm. - Choose Channel for this check and fill Context if the flow needs initial values. You can keep the reaction's channel scope.
- Add sample responses for collection reads, HTTP or AI steps used by the sequence, as explained below.
- Click Check with these inputs. Inspect Step inputs and outputs, Selected path and Intended messages and writes.
- Change a condition or draft data and run again. The selected path should reflect the change.
No previous live run or trace ID is required. Testing uses the current form contents, including unsaved changes.
Apply or close an open action or button editor first. For an unfinished number or JSON value, use Correct input. Testing does not replace your text with the last valid value. A new reaction does not need a title or a save just to be checked.
For a first example, use the list price calculation: two input rows contain price and quantity, and the expected amounts are 3000 and 2000. Check the actual rows as well as the overall completion status.
Where test data comes from
There are three sources:
| Source | What to supply |
|---|---|
| Incoming event | Text, command and required user data |
| Initial context | Values available when this reaction starts, such as the selected booking ID |
| Sample step response | What HTTP, AI, a collection read or another external dependency returns |
A sample response is often called a fixture: supplied data replacing a request to the live service. Instead of querying a catalog, supply matching rows. Instead of changing a production booking, use its state in the test's virtual collection.
Context uses literal keys and string values. Encode an array or object as JSON inside a string. For the first list calculation lesson, you can enter:
{
"orders": "[{\"id\":\"o1\",\"customer\":{\"name\":\"Anna\"},\"price\":1500,\"quantity\":2},{\"id\":\"o2\",\"price\":2000,\"quantity\":1}]"
}
If the flow uses {{user_id}}, {{chat_id}} or the person's name, expand Advanced: seed and clock and fill User and conversation data (JSON). For example:
{
"actor": {"ChannelUserID": "guest-1", "FirstName": "Anna"},
"conversation": {"ChannelChatID": "chat-1"}
}
These string IDs describe the sample user and conversation. {{user_id}} reads guest-1 from the event; ctx.user_id in initial context does not replace it. JSON field names are case-sensitive. Use the main fields above for event type, text and command.
For an external step, expand Response fixtures (HTTP, read, AI), choose Response producer, enter the status and body, then click Apply response fixture. Use Simulate a provider error for a technical failure. Select the correct step in its reaction or immutable block version: the same action ID in another block is a different producer. A page/query read needs that action's normalized result, rather than an arbitrary response from another API.
All fixture data (JSON) supports advanced cases and preserves numbers without rounding. Apply or explicitly discard edits in the structured response/collection fields before running. The check does not silently use the old response instead of those edits.
For conditional updates and transactions, supply the collection schema, records and retention rules. Each record needs an ID and creation time, which determine whether it is eligible. Explicitly confirm that the sample describes the entire collection and its rules. An empty list means there are no records; an omitted or partial list means the state is unknown. The latter produces an incomplete test: a few rows cannot reliably prove that a record is absent.
For example, expand Virtual collection fixtures for the booking confirmation case. Enter collection name bookings, then put this in Complete collection metadata:
{
"name": "bookings",
"schema": [
{"name": "state", "type": "text"},
{"name": "guest_id", "type": "text"}
],
"retention": {"max_age_days": 0, "max_records": 0}
}
In Complete records, enter:
[
{
"id": 101,
"data": {"state": "new", "guest_id": "guest-1"},
"created_at": "2026-10-25T12:00:00Z"
}
]
This is a complete one-record sample collection with no deduplication keys or retention limit. Confirm completeness and click Apply complete collection fixture. Under Advanced: seed and clock, choose a time after the record was created, such as 2026-10-25T13:00:00Z. Use record ID 101 and the same owner guest-1 in the action being checked. For your own case, replace the schema, records and retention rules accordingly. Record IDs are positive whole numbers, not strings; created_at includes the date, time and time zone.
If a transaction includes a confirmation message, also supply the assumed channel capabilities: destination, allowed format and text size. These are test assumptions. They do not prove the bot has permission in the live channel or that a message was delivered.
Later actions receive earlier results: a calculation processes supplied rows, a branch checks the calculated value and a message shows rendered text. Testing does more than display an earlier recorded path.
If a required fixture is missing, the test is incomplete. The indicated step must not be treated as successfully executed. Supply the missing data and rerun.
Lesson 2. Test confirmation and repeated clicks
Use the action outcomes flow: a conditional update changes a booking from new to confirmed and selects a response.
Prepare three examples:
| Example | Sample data | Expected result |
|---|---|---|
| New booking | Record exists, state=new, matching owner | updated, success response |
| Already changed | Same record with state=confirmed | conflict, no success response |
| Deleted record | Requested ID is absent from the test collection | not_found |
If the flow includes an HTTP step, separately supply a sample technical failure for that step and check its configured error outcome. A record conflict is determined by virtual collection state; an HTTP failure comes from that HTTP step's response fixture.
The initial context ID and sample record ID must match. If the guard compares guest_id with {{user_id}}, use the same sample user in User and conversation data (JSON) and the record. Otherwise the test checks an owner conflict instead of the intended case.
Inspect intended messages and changes. A conflict must produce neither the record change nor “Booking confirmed”. An outcome route ends the current sequence, including an action inside a loop.
For transactions, also test rollback: a conflict in a later operation must leave no earlier changes in the virtual collections. Last-seat exercise.
Each new run starts from the supplied sample state. Changes from the previous test are not carried over automatically. Testing a transaction retry requires explicitly supplied history of its result in the fixtures. Repeating the same invocation should return the previous result without another write or confirmation. Two loop iterations or two separate block calls count as distinct invocations.
Reading the result
- Step data shows what an action received and returned. For lists, inspect completeness too.
- Selected branch shows where execution went. Compare it with the expected case.
- Intended effects show rendered messages and virtual changes. They are a test plan, not proof of a real send or write.
- Pause means the flow waits for an answer. Testing does not create a live dialog.
- Error means a step could not execute correctly.
- Incomplete means a missing fixture, unsupported action or another stated boundary. It does not confirm that the whole sequence works.
A response fixture checks one case; it does not add a permanent schema for arbitrary HTTP JSON. Configure field extraction and available-data selection for nested paths. A live service may return something different, so also test an empty list, a missing field and a technical failure.
If testing stops at a limit
Testing limits input size, step count and computation work. If a limit is reached or the run is cancelled, subsequent steps remain untested. Reduce the sample, process one page or simplify the expression, then rerun it.
JSONPath filter predicates and custom JSONPath procedures are currently unsupported in draft testing. Use list actions to filter data. A limit may also reject an expression with a small final answer: testing checks potential intermediate expansion before computing it.
Input JSON and reports retain numeric values without additional rounding. Formulas still follow the same rules as the live flow. JP and floating-point expressions may lose precision during computation itself. For exact multiplication and sums, use list operations and collection totals.
Lesson 3. Save examples for the next change
- Under Saved examples, fill New example name, such as
booking-new, and click Save new example. No previous recorded execution is required. - Save
booking-conflictandbooking-missingwith their respective inputs. An example contains the flow definitions, event, context, fixtures, seed and clock. - Select a case and click Open selected example. Rerun saved version checks its saved definitions.
- After editing the flow, click Rerun with current draft. This comparison changes definitions only: event, context, fixtures, seed and clock remain those saved in the example. Compare branches, values and intended messages.
To edit an opened example's inputs, choose Copy to a new check. Run a separate check after editing and save it under a new name. A fixture edit must not silently change what a saved-example rerun means.
If an opened example is deleted or access is withdrawn, the editor hides its details and clears the loaded context, user and conversation data, and fixtures. Edits within those inputs are cleared too. Choose Copy to a new check first to work with the inputs independently. A temporary loading error preserves your entered data.
Saved examples are immutable. If another case already uses the name, choose a new one; your entered inputs survive the error. If the same inputs already exist under another name, the server may return that original example. The editor shows and selects its authoritative name instead of creating a duplicate. Examples belong to their project.
The Expires date shows the retention deadline. The normal retention is currently 90 days; use the date returned for the particular example. Refresh the list after expiry. An unavailable example is not a permanent backup that can still be rerun.
Fixed time and seed in advanced settings make date and random-choice tests repeatable. The same flow, inputs and settings should produce the same result. Use another seed or time for an independent case.
Keep production secrets out of sample responses. Saved examples and reports are redacted. Removing a sensitive value can make a rerun incomplete; that does not confirm success. Use ordinary sample values for a reproducible case.
What to check before enabling the reaction
Draft testing checks logic against supplied data. It does not prove that a live service returns the same response or that a channel delivers a message. After saving, check service connectivity and the user journey separately through the connected bot and channel. That run performs the real saved actions.
If the draft changes after testing, the previous report describes the previous version. Rerun it. Also retest after switching project or channel.
Related: actions, list fields, blocks, change history.