@xano/developer-mcp 1.0.35 → 1.0.37
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/README.md +21 -4
- package/dist/xanoscript.js +40 -5
- package/dist/xanoscript.test.js +9 -2
- package/dist/xanoscript_docs/README.md +46 -42
- package/dist/xanoscript_docs/addons.md +10 -0
- package/dist/xanoscript_docs/agents.md +15 -0
- package/dist/xanoscript_docs/apis.md +45 -24
- package/dist/xanoscript_docs/cheatsheet.md +252 -0
- package/dist/xanoscript_docs/database.md +23 -0
- package/dist/xanoscript_docs/docs_index.json +241 -0
- package/dist/xanoscript_docs/frontend.md +10 -0
- package/dist/xanoscript_docs/functions.md +4 -0
- package/dist/xanoscript_docs/integrations/cloud-storage.md +142 -0
- package/dist/xanoscript_docs/integrations/external-apis.md +201 -0
- package/dist/xanoscript_docs/integrations/redis.md +194 -0
- package/dist/xanoscript_docs/integrations/search.md +242 -0
- package/dist/xanoscript_docs/integrations/utilities.md +331 -0
- package/dist/xanoscript_docs/integrations.md +55 -901
- package/dist/xanoscript_docs/mcp-servers.md +10 -0
- package/dist/xanoscript_docs/performance.md +15 -0
- package/dist/xanoscript_docs/quickstart.md +22 -88
- package/dist/xanoscript_docs/run.md +10 -0
- package/dist/xanoscript_docs/security.md +26 -0
- package/dist/xanoscript_docs/streaming.md +10 -0
- package/dist/xanoscript_docs/syntax.md +56 -0
- package/dist/xanoscript_docs/tables.md +15 -0
- package/dist/xanoscript_docs/tasks.md +11 -0
- package/dist/xanoscript_docs/tools.md +15 -0
- package/dist/xanoscript_docs/triggers.md +57 -192
- package/dist/xanoscript_docs/types.md +4 -0
- package/dist/xanoscript_docs/{testing.md → unit-testing.md} +15 -3
- package/dist/xanoscript_docs/workflow-tests.md +333 -0
- package/package.json +1 -1
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
---
|
|
2
|
+
applyTo: "workflow_test/**/*.xs"
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Workflow Tests
|
|
6
|
+
|
|
7
|
+
End-to-end workflow tests that call Xano constructs (APIs, functions, tasks, etc.) and validate results with assertions. The `stack` block supports all standard XanoScript statements (variables, conditionals, loops, database operations, etc.) in addition to the call functions and assertions documented below.
|
|
8
|
+
|
|
9
|
+
## Quick Reference
|
|
10
|
+
|
|
11
|
+
```xs
|
|
12
|
+
workflow_test "<name>" {
|
|
13
|
+
datasource = "live"
|
|
14
|
+
stack { ... }
|
|
15
|
+
tags = ["tag1", "tag2"]
|
|
16
|
+
}
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
| Property | Required | Default | Description |
|
|
20
|
+
| ------------ | -------- | ------- | ------------------------------------------------ |
|
|
21
|
+
| `datasource` | No | (empty) | Data source to run against: custom name or `"live"` (not recommended — clones entire datasource) |
|
|
22
|
+
| `stack` | Yes | — | Test execution logic using call functions and assertions |
|
|
23
|
+
| `tags` | No | `[]` | Tags for organizing and filtering workflow tests |
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## Call Functions
|
|
28
|
+
|
|
29
|
+
Call functions invoke Xano constructs and capture their results. Each returns a result that can be stored with `as $variable`.
|
|
30
|
+
|
|
31
|
+
| Call Function | Description | Required Properties |
|
|
32
|
+
| ----------------- | ------------------------------ | ------------------------------------ |
|
|
33
|
+
| `api.call` | Call an API endpoint | `api_group`, `verb` (on call), optional `headers` |
|
|
34
|
+
| `addon.call` | Call an addon | — |
|
|
35
|
+
| `function.call` | Call a function | optional `input` |
|
|
36
|
+
| `middleware.call` | Call a middleware | `input` with `vars` and `type` |
|
|
37
|
+
| `task.call` | Call a task | — |
|
|
38
|
+
| `tool.call` | Call a tool | — |
|
|
39
|
+
| `trigger.call` | Call a trigger | `input` with `new`, `old`, `action`, `datasource` |
|
|
40
|
+
|
|
41
|
+
### api.call
|
|
42
|
+
|
|
43
|
+
```xs
|
|
44
|
+
api.call "<endpoint_name>" verb=GET {
|
|
45
|
+
api_group = "<group_name>"
|
|
46
|
+
headers = '["Content-Type: application/json"]'
|
|
47
|
+
} as $result
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### addon.call
|
|
51
|
+
|
|
52
|
+
```xs
|
|
53
|
+
addon.call "<addon_name>" as $result
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### function.call
|
|
57
|
+
|
|
58
|
+
```xs
|
|
59
|
+
function.call "<function_name>" {
|
|
60
|
+
input = { key: "value" }
|
|
61
|
+
} as $result
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### middleware.call
|
|
65
|
+
|
|
66
|
+
```xs
|
|
67
|
+
middleware.call "<middleware_name>" {
|
|
68
|
+
input = {vars: {}, type: "pre"}
|
|
69
|
+
} as $result
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### task.call
|
|
73
|
+
|
|
74
|
+
```xs
|
|
75
|
+
task.call "<task_name>" as $result
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### tool.call
|
|
79
|
+
|
|
80
|
+
```xs
|
|
81
|
+
tool.call "<tool_name>" as $result
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### trigger.call
|
|
85
|
+
|
|
86
|
+
```xs
|
|
87
|
+
trigger.call "<trigger_name>" {
|
|
88
|
+
input = {new: {}, old: {}, action: "", datasource: ""}
|
|
89
|
+
} as $result
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
## Assertions
|
|
95
|
+
|
|
96
|
+
Assertions validate results within the workflow test stack. Each takes a variable reference as the target.
|
|
97
|
+
|
|
98
|
+
### Quick Reference
|
|
99
|
+
|
|
100
|
+
| Assertion | Purpose | Properties |
|
|
101
|
+
| -------------------------- | ----------------------- | ------------------- |
|
|
102
|
+
| `expect.to_be_defined` | Value is defined | — |
|
|
103
|
+
| `expect.to_not_be_defined` | Value is not defined | — |
|
|
104
|
+
| `expect.to_be_empty` | Value is empty | — |
|
|
105
|
+
| `expect.to_be_true` | Value is true | — |
|
|
106
|
+
| `expect.to_be_false` | Value is false | — |
|
|
107
|
+
| `expect.to_be_null` | Value is null | — |
|
|
108
|
+
| `expect.to_not_be_null` | Value is not null | — |
|
|
109
|
+
| `expect.to_be_in_the_past` | Timestamp is in the past| — |
|
|
110
|
+
| `expect.to_be_in_the_future`| Timestamp is in the future| — |
|
|
111
|
+
| `expect.to_equal` | Exact match | `value` |
|
|
112
|
+
| `expect.to_not_equal` | Not equal | `value` |
|
|
113
|
+
| `expect.to_be_greater_than`| Greater than | `value` |
|
|
114
|
+
| `expect.to_be_less_than` | Less than | `value` |
|
|
115
|
+
| `expect.to_be_within` | Within range | `min`, `max` |
|
|
116
|
+
| `expect.to_contain` | Contains value | `value` |
|
|
117
|
+
| `expect.to_start_with` | Starts with string | `value` |
|
|
118
|
+
| `expect.to_end_with` | Ends with string | `value` |
|
|
119
|
+
| `expect.to_match` | Regex match | `value` (pattern) |
|
|
120
|
+
| `expect.to_throw` | Stack throws error | `stack`, `exception` |
|
|
121
|
+
|
|
122
|
+
### No-Property Assertions
|
|
123
|
+
|
|
124
|
+
These take only the target variable:
|
|
125
|
+
|
|
126
|
+
```xs
|
|
127
|
+
expect.to_be_defined ($var)
|
|
128
|
+
expect.to_not_be_defined ($var)
|
|
129
|
+
expect.to_be_empty ($var)
|
|
130
|
+
expect.to_be_true ($var)
|
|
131
|
+
expect.to_be_false ($var)
|
|
132
|
+
expect.to_be_null ($var)
|
|
133
|
+
expect.to_not_be_null ($var)
|
|
134
|
+
expect.to_be_in_the_past ($var)
|
|
135
|
+
expect.to_be_in_the_future ($var)
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### Value Assertions
|
|
139
|
+
|
|
140
|
+
These take a `value` property for comparison. The value can be a literal or a variable reference:
|
|
141
|
+
|
|
142
|
+
```xs
|
|
143
|
+
expect.to_equal ($var) { value = "expected" }
|
|
144
|
+
expect.to_not_equal ($var) { value = $other_var }
|
|
145
|
+
expect.to_be_greater_than ($var) { value = 3 }
|
|
146
|
+
expect.to_be_less_than ($var) { value = $other_var }
|
|
147
|
+
expect.to_contain ($var) { value = "substring" }
|
|
148
|
+
expect.to_start_with ($var) { value = "prefix" }
|
|
149
|
+
expect.to_end_with ($var) { value = "suffix" }
|
|
150
|
+
|
|
151
|
+
// Regex pattern
|
|
152
|
+
expect.to_match ($var) { value = "^\\d+$" }
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### Range Assertion
|
|
156
|
+
|
|
157
|
+
```xs
|
|
158
|
+
expect.to_be_within ($var) {
|
|
159
|
+
min = 1
|
|
160
|
+
max = 100
|
|
161
|
+
}
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
### Error Assertion
|
|
165
|
+
|
|
166
|
+
`expect.to_throw` wraps a `stack` block and checks that it throws a matching exception:
|
|
167
|
+
|
|
168
|
+
```xs
|
|
169
|
+
expect.to_throw {
|
|
170
|
+
stack {
|
|
171
|
+
security.create_uuid as $x1
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
exception = "error"
|
|
175
|
+
}
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
---
|
|
179
|
+
|
|
180
|
+
## Data Sources
|
|
181
|
+
|
|
182
|
+
The `datasource` property controls which data source the test runs against.
|
|
183
|
+
|
|
184
|
+
**Avoid using `datasource = "live"`.** When a workflow test runs, the entire datasource is cloned so that real data is not modified. This cloning step can be slow, especially for large datasources. Prefer running without a datasource or using a smaller custom datasource instead.
|
|
185
|
+
|
|
186
|
+
### Default (No Data Source) — Recommended
|
|
187
|
+
|
|
188
|
+
```xs
|
|
189
|
+
workflow_test "basic_check" {
|
|
190
|
+
stack {
|
|
191
|
+
function.call "health_check" as $result
|
|
192
|
+
expect.to_be_defined ($result)
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
### Custom Data Source
|
|
198
|
+
|
|
199
|
+
```xs
|
|
200
|
+
workflow_test "staging_data_check" {
|
|
201
|
+
datasource = "staging"
|
|
202
|
+
stack {
|
|
203
|
+
function.call "get_products" as $products
|
|
204
|
+
expect.to_be_defined ($products)
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
### Live Data Source (Not Recommended)
|
|
210
|
+
|
|
211
|
+
Using `datasource = "live"` clones the entire live datasource before running the test. Only use this when you specifically need to validate against production data.
|
|
212
|
+
|
|
213
|
+
```xs
|
|
214
|
+
workflow_test "live_data_check" {
|
|
215
|
+
datasource = "live"
|
|
216
|
+
stack {
|
|
217
|
+
function.call "get_active_users" as $users
|
|
218
|
+
expect.to_be_defined ($users)
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
---
|
|
224
|
+
|
|
225
|
+
## Tags
|
|
226
|
+
|
|
227
|
+
Use tags to organize and filter workflow tests:
|
|
228
|
+
|
|
229
|
+
```xs
|
|
230
|
+
workflow_test "checkout_flow" {
|
|
231
|
+
tags = ["checkout", "critical", "e2e"]
|
|
232
|
+
stack {
|
|
233
|
+
function.call "create_cart" as $cart
|
|
234
|
+
expect.to_be_defined ($cart)
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
---
|
|
240
|
+
|
|
241
|
+
## Complete Example
|
|
242
|
+
|
|
243
|
+
This example demonstrates all call functions and all assertion types:
|
|
244
|
+
|
|
245
|
+
```xs
|
|
246
|
+
workflow_test "comprehensive_test" {
|
|
247
|
+
datasource = "live"
|
|
248
|
+
|
|
249
|
+
stack {
|
|
250
|
+
// Call functions
|
|
251
|
+
api.call "test" verb=GET {
|
|
252
|
+
api_group = "test"
|
|
253
|
+
headers = '["Content-Type: application/json"]'
|
|
254
|
+
} as $endpoint1
|
|
255
|
+
|
|
256
|
+
addon.call "my_addon" as $addon1
|
|
257
|
+
function.call "my_function" {
|
|
258
|
+
input = {name: "Justin"}
|
|
259
|
+
} as $function1
|
|
260
|
+
|
|
261
|
+
middleware.call "my_middleware" {
|
|
262
|
+
input = {vars: {}, type: "pre"}
|
|
263
|
+
} as $middleware1
|
|
264
|
+
|
|
265
|
+
task.call "my_task" as $task1
|
|
266
|
+
tool.call "my_tool" as $tool1
|
|
267
|
+
trigger.call "my_trigger" {
|
|
268
|
+
input = {new: {}, old: {}, action: "", datasource: ""}
|
|
269
|
+
} as $trigger1
|
|
270
|
+
|
|
271
|
+
// No-property assertions
|
|
272
|
+
expect.to_be_defined ($endpoint1)
|
|
273
|
+
expect.to_be_empty ($addon1)
|
|
274
|
+
expect.to_be_false ($endpoint1)
|
|
275
|
+
expect.to_be_true ($addon1)
|
|
276
|
+
expect.to_be_null ($middleware1)
|
|
277
|
+
expect.to_not_be_null ($endpoint1)
|
|
278
|
+
expect.to_not_be_defined ($function1)
|
|
279
|
+
expect.to_be_in_the_past ($endpoint1)
|
|
280
|
+
expect.to_be_in_the_future ($endpoint1)
|
|
281
|
+
|
|
282
|
+
// Value assertions
|
|
283
|
+
expect.to_equal ($endpoint1) { value = $endpoint1 }
|
|
284
|
+
expect.to_not_equal ($endpoint1) { value = $addon1 }
|
|
285
|
+
expect.to_be_greater_than ($endpoint1) { value = 3 }
|
|
286
|
+
expect.to_be_less_than ($addon1) { value = $task1 }
|
|
287
|
+
expect.to_contain ($endpoint1) { value = "asdf" }
|
|
288
|
+
expect.to_start_with ($addon1) { value = "f" }
|
|
289
|
+
expect.to_end_with ($addon1) { value = "asdf" }
|
|
290
|
+
|
|
291
|
+
// Regex pattern
|
|
292
|
+
expect.to_match ($endpoint1) { value = ".*" }
|
|
293
|
+
|
|
294
|
+
// Range assertion
|
|
295
|
+
expect.to_be_within ($endpoint1) {
|
|
296
|
+
min = 1
|
|
297
|
+
max = 4
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
// Error assertion
|
|
301
|
+
expect.to_throw {
|
|
302
|
+
stack {
|
|
303
|
+
security.create_uuid as $x1
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
exception = "error"
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
tags = ["a", "b"]
|
|
311
|
+
}
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
---
|
|
315
|
+
|
|
316
|
+
## Best Practices
|
|
317
|
+
|
|
318
|
+
1. **Use descriptive names** — Name tests after the workflow being tested: `user_signup_flow`, `checkout_process`
|
|
319
|
+
2. **Tag for filtering** — Use tags like `critical`, `e2e`, `smoke` to organize test suites
|
|
320
|
+
3. **Avoid `datasource = "live"`** — The entire datasource is cloned before each test run, which can be slow. Use no datasource or a smaller custom datasource instead
|
|
321
|
+
4. **Keep tests independent** — Each workflow test should be self-contained and not depend on other tests
|
|
322
|
+
5. **Use assertions over preconditions** — Prefer `expect.*` assertions for clearer test intent
|
|
323
|
+
|
|
324
|
+
---
|
|
325
|
+
|
|
326
|
+
## Related Topics
|
|
327
|
+
|
|
328
|
+
| Topic | Description |
|
|
329
|
+
| -------------- | ------------------------------------------ |
|
|
330
|
+
| `unit-testing` | Unit tests and assertions within functions |
|
|
331
|
+
| `functions` | Reusable function stacks called in tests |
|
|
332
|
+
| `database` | Database operations used in test stacks |
|
|
333
|
+
| `debugging` | Logging and debugging test execution |
|
package/package.json
CHANGED