testflow-ai 0.5.2 → 0.5.3
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 +83 -74
- package/examples/auth-flow.yaml +34 -10
- package/examples/context.md +9 -7
- package/examples/graphql-flow.yaml +26 -26
- package/examples/rest-crud.yaml +29 -28
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -234,9 +234,8 @@ my-api/
|
|
|
234
234
|
│ ├── index.ts # Test runner
|
|
235
235
|
│ ├── context.md # API context
|
|
236
236
|
│ └── flows/
|
|
237
|
-
│ ├── health-check.yaml
|
|
238
237
|
│ ├── todo-crud.yaml
|
|
239
|
-
│ └── todo-
|
|
238
|
+
│ └── todo-graphql.yaml
|
|
240
239
|
└── package.json
|
|
241
240
|
```
|
|
242
241
|
|
|
@@ -352,14 +351,14 @@ import { TestRunner, FlowExecutor, parseYamlFile, parseContextFile } from 'testf
|
|
|
352
351
|
// Runner with full control
|
|
353
352
|
const runner = new TestRunner({
|
|
354
353
|
contextFile: './context.md',
|
|
355
|
-
testFiles: ['./tests/
|
|
354
|
+
testFiles: ['./tests/todo-crud.yaml'],
|
|
356
355
|
ai: { provider: 'ollama', model: 'mistral:7b' },
|
|
357
356
|
});
|
|
358
357
|
const report = await runner.run();
|
|
359
358
|
|
|
360
359
|
// Manual execution
|
|
361
360
|
const context = await parseContextFile('./context.md');
|
|
362
|
-
const flow = await parseYamlFile('./tests/
|
|
361
|
+
const flow = await parseYamlFile('./tests/todo-crud.yaml');
|
|
363
362
|
const executor = new FlowExecutor(context, true);
|
|
364
363
|
const result = await executor.executeFlow(flow);
|
|
365
364
|
```
|
|
@@ -374,65 +373,65 @@ const result = await executor.executeFlow(flow);
|
|
|
374
373
|
### Basic structure
|
|
375
374
|
|
|
376
375
|
```yaml
|
|
377
|
-
name:
|
|
378
|
-
description: Create and verify
|
|
376
|
+
name: Todo Lifecycle
|
|
377
|
+
description: Create a todo and verify it exists
|
|
379
378
|
tags:
|
|
380
|
-
-
|
|
379
|
+
- todos
|
|
381
380
|
- smoke
|
|
382
381
|
|
|
383
382
|
steps:
|
|
384
|
-
- name: Create
|
|
383
|
+
- name: Create todo
|
|
385
384
|
request:
|
|
386
385
|
method: POST
|
|
387
|
-
url: "{api}/
|
|
386
|
+
url: "{api}/todos"
|
|
388
387
|
headers:
|
|
389
388
|
Content-Type: application/json
|
|
390
389
|
body:
|
|
391
|
-
|
|
392
|
-
|
|
390
|
+
title: "Buy groceries"
|
|
391
|
+
completed: false
|
|
393
392
|
capture:
|
|
394
|
-
- name:
|
|
393
|
+
- name: todoId
|
|
395
394
|
path: data.id
|
|
396
395
|
assertions:
|
|
397
396
|
- path: status
|
|
398
397
|
operator: equals
|
|
399
398
|
value: 201
|
|
400
|
-
- path: data.
|
|
399
|
+
- path: data.title
|
|
401
400
|
operator: equals
|
|
402
|
-
value:
|
|
401
|
+
value: "Buy groceries"
|
|
403
402
|
|
|
404
|
-
- name: Verify
|
|
403
|
+
- name: Verify todo
|
|
405
404
|
request:
|
|
406
405
|
method: GET
|
|
407
|
-
url: "{api}/
|
|
406
|
+
url: "{api}/todos/${todoId}"
|
|
408
407
|
assertions:
|
|
409
408
|
- path: data.id
|
|
410
409
|
operator: equals
|
|
411
|
-
value: "${
|
|
410
|
+
value: "${todoId}"
|
|
412
411
|
```
|
|
413
412
|
|
|
414
413
|
### GraphQL requests
|
|
415
414
|
|
|
416
415
|
```yaml
|
|
417
416
|
steps:
|
|
418
|
-
- name: Query
|
|
417
|
+
- name: Query todo
|
|
419
418
|
request:
|
|
420
419
|
method: POST
|
|
421
420
|
url: "{graphql}"
|
|
422
421
|
graphql:
|
|
423
422
|
query: |
|
|
424
|
-
query
|
|
425
|
-
|
|
423
|
+
query GetTodo($id: ID!) {
|
|
424
|
+
todo(id: $id) {
|
|
426
425
|
id
|
|
427
|
-
|
|
428
|
-
|
|
426
|
+
title
|
|
427
|
+
completed
|
|
429
428
|
}
|
|
430
429
|
}
|
|
431
430
|
variables:
|
|
432
|
-
id: "${
|
|
431
|
+
id: "${todoId}"
|
|
433
432
|
capture:
|
|
434
|
-
- name:
|
|
435
|
-
path: data.
|
|
433
|
+
- name: todoTitle
|
|
434
|
+
path: data.todo.title
|
|
436
435
|
```
|
|
437
436
|
|
|
438
437
|
### Variable capture and interpolation
|
|
@@ -441,25 +440,29 @@ Variables captured in one step are available in all subsequent steps:
|
|
|
441
440
|
|
|
442
441
|
```yaml
|
|
443
442
|
steps:
|
|
444
|
-
- name:
|
|
443
|
+
- name: Create todo
|
|
445
444
|
request:
|
|
446
445
|
method: POST
|
|
447
|
-
url: "{api}/
|
|
446
|
+
url: "{api}/todos"
|
|
447
|
+
headers:
|
|
448
|
+
Content-Type: application/json
|
|
448
449
|
body:
|
|
449
|
-
|
|
450
|
-
|
|
450
|
+
title: "Read docs"
|
|
451
|
+
completed: false
|
|
451
452
|
capture:
|
|
452
|
-
- name:
|
|
453
|
-
path: data.
|
|
454
|
-
- name:
|
|
455
|
-
path: data.
|
|
453
|
+
- name: todoId
|
|
454
|
+
path: data.id
|
|
455
|
+
- name: todoTitle
|
|
456
|
+
path: data.title
|
|
456
457
|
|
|
457
|
-
- name:
|
|
458
|
+
- name: Verify todo title
|
|
458
459
|
request:
|
|
459
460
|
method: GET
|
|
460
|
-
url: "{api}/
|
|
461
|
-
|
|
462
|
-
|
|
461
|
+
url: "{api}/todos/${todoId}"
|
|
462
|
+
assertions:
|
|
463
|
+
- path: data.title
|
|
464
|
+
operator: equals
|
|
465
|
+
value: "${todoTitle}"
|
|
463
466
|
```
|
|
464
467
|
|
|
465
468
|
**Supported patterns:**
|
|
@@ -474,20 +477,20 @@ For operations that take time — polls until condition is met or timeout:
|
|
|
474
477
|
|
|
475
478
|
```yaml
|
|
476
479
|
steps:
|
|
477
|
-
- name: Wait for
|
|
480
|
+
- name: Wait for todo sync
|
|
478
481
|
request:
|
|
479
482
|
method: GET
|
|
480
|
-
url: "{api}/
|
|
483
|
+
url: "{api}/todos/${todoId}/sync-status"
|
|
481
484
|
waitUntil:
|
|
482
485
|
path: data.status
|
|
483
486
|
operator: equals
|
|
484
|
-
value: "
|
|
487
|
+
value: "SYNCED"
|
|
485
488
|
timeout: 30000 # max wait (ms)
|
|
486
489
|
interval: 2000 # poll every (ms)
|
|
487
490
|
assertions:
|
|
488
491
|
- path: data.status
|
|
489
492
|
operator: equals
|
|
490
|
-
value: "
|
|
493
|
+
value: "SYNCED"
|
|
491
494
|
```
|
|
492
495
|
|
|
493
496
|
</details>
|
|
@@ -633,19 +636,19 @@ const report = await runTests({
|
|
|
633
636
|
|
|
634
637
|
```yaml
|
|
635
638
|
steps:
|
|
636
|
-
- name: Check
|
|
639
|
+
- name: Check todo description
|
|
637
640
|
request:
|
|
638
641
|
method: GET
|
|
639
|
-
url: "{api}/
|
|
642
|
+
url: "{api}/todos/${todoId}"
|
|
640
643
|
assertions:
|
|
641
644
|
# Traditional assertion
|
|
642
645
|
- path: status
|
|
643
646
|
operator: equals
|
|
644
647
|
value: 200
|
|
645
648
|
# AI-powered assertion (works with any provider)
|
|
646
|
-
- path: data.
|
|
649
|
+
- path: data.description
|
|
647
650
|
operator: ai-evaluate
|
|
648
|
-
value: "
|
|
651
|
+
value: "Is this a well-formed task description with a clear action item?"
|
|
649
652
|
```
|
|
650
653
|
|
|
651
654
|
### Context file AI config
|
|
@@ -744,23 +747,25 @@ This gives you:
|
|
|
744
747
|
Define your project context in Markdown. The runner uses it to resolve `{baseUrlKey}` references in your YAML flows.
|
|
745
748
|
|
|
746
749
|
```markdown
|
|
747
|
-
#
|
|
750
|
+
# Todo List API
|
|
748
751
|
|
|
749
752
|
## Description
|
|
750
|
-
|
|
753
|
+
A REST + GraphQL API for managing todo items.
|
|
751
754
|
|
|
752
755
|
## Base URLs
|
|
753
756
|
- api: http://localhost:3000
|
|
754
757
|
- graphql: http://localhost:3000/graphql
|
|
755
758
|
|
|
756
759
|
## Endpoints
|
|
757
|
-
- POST /
|
|
758
|
-
- GET /
|
|
760
|
+
- POST /todos - Create todo
|
|
761
|
+
- GET /todos/:id - Get todo by ID
|
|
762
|
+
- PUT /todos/:id - Update todo
|
|
763
|
+
- DELETE /todos/:id - Delete todo
|
|
759
764
|
- POST /graphql - GraphQL endpoint
|
|
760
765
|
|
|
761
766
|
## Rules
|
|
762
767
|
- All endpoints return JSON
|
|
763
|
-
-
|
|
768
|
+
- Todos have: id, title, completed, createdAt
|
|
764
769
|
|
|
765
770
|
## AI Configuration
|
|
766
771
|
- provider: ollama
|
|
@@ -815,26 +820,27 @@ That's it. If tests fail, the job fails automatically (exit code 1).
|
|
|
815
820
|
══════════════════════════════════════════════════════════════
|
|
816
821
|
|
|
817
822
|
Summary:
|
|
818
|
-
Total:
|
|
819
|
-
Passed:
|
|
820
|
-
Failed:
|
|
821
|
-
Duration:
|
|
823
|
+
Total: 3 flows
|
|
824
|
+
Passed: 2
|
|
825
|
+
Failed: 1
|
|
826
|
+
Duration: 1850ms
|
|
822
827
|
|
|
823
828
|
Narrative:
|
|
824
829
|
|
|
825
|
-
✅ **
|
|
826
|
-
→ Create
|
|
827
|
-
📦
|
|
828
|
-
→ Read
|
|
829
|
-
→ Update
|
|
830
|
+
✅ **Todo CRUD**
|
|
831
|
+
→ Create todo
|
|
832
|
+
📦 todoId: abc-123
|
|
833
|
+
→ Read todo
|
|
834
|
+
→ Update todo
|
|
835
|
+
→ Delete todo
|
|
830
836
|
|
|
831
|
-
✅ **
|
|
832
|
-
→
|
|
833
|
-
📦
|
|
834
|
-
→
|
|
837
|
+
✅ **Todo GraphQL**
|
|
838
|
+
→ Create todo (mutation)
|
|
839
|
+
📦 todoId: def-456
|
|
840
|
+
→ Query todo
|
|
835
841
|
|
|
836
|
-
❌ **
|
|
837
|
-
✗
|
|
842
|
+
❌ **Todo Bulk Import**
|
|
843
|
+
✗ Import todos from CSV
|
|
838
844
|
⚠️ Expected status to equal 200, got 500
|
|
839
845
|
|
|
840
846
|
══════════════════════════════════════════════════════════════
|
|
@@ -863,20 +869,23 @@ Narrative:
|
|
|
863
869
|
|
|
864
870
|
See the [`examples/`](./examples) directory for:
|
|
865
871
|
|
|
866
|
-
- **
|
|
867
|
-
- **
|
|
868
|
-
- **
|
|
869
|
-
- **
|
|
870
|
-
- **
|
|
871
|
-
- **Context Files** (`context.md`, `todo-list-context.md`)
|
|
872
|
+
- **REST CRUD** (`rest-crud.yaml`) — Full todo lifecycle: create → read → update → verify
|
|
873
|
+
- **Auth Flow** (`auth-flow.yaml`) — Login, create todo with token, verify access control
|
|
874
|
+
- **GraphQL Flow** (`graphql-flow.yaml`) — Create + query todos via GraphQL mutations
|
|
875
|
+
- **Todo CRUD** (`todo-crud.yaml`) — Extended CRUD with delete + verify deletion
|
|
876
|
+
- **Todo GraphQL** (`todo-graphql.yaml`) — GraphQL mutations and queries with variable capture
|
|
877
|
+
- **Context Files** (`context.md`, `todo-list-context.md`) — API context templates
|
|
872
878
|
|
|
873
879
|
**Quick start with examples:**
|
|
874
880
|
|
|
875
881
|
```bash
|
|
876
|
-
# Run specific
|
|
877
|
-
npx testflow --context ./examples/
|
|
882
|
+
# Run a specific flow
|
|
883
|
+
npx testflow --context ./examples/context.md ./examples/rest-crud.yaml
|
|
884
|
+
|
|
885
|
+
# Run the auth flow
|
|
886
|
+
npx testflow --context ./examples/context.md ./examples/auth-flow.yaml
|
|
878
887
|
|
|
879
|
-
# Run all examples
|
|
888
|
+
# Run all examples
|
|
880
889
|
npx testflow --dir ./examples --context ./examples/context.md
|
|
881
890
|
```
|
|
882
891
|
|
package/examples/auth-flow.yaml
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
# Auth flow — Login, use token, access protected
|
|
1
|
+
# Auth flow — Login, use token, create and access a protected todo.
|
|
2
2
|
|
|
3
|
-
name:
|
|
4
|
-
description: Login
|
|
3
|
+
name: Authenticated Todo Flow
|
|
4
|
+
description: Login, create a todo with auth token, and verify access control
|
|
5
5
|
tags:
|
|
6
6
|
- auth
|
|
7
|
+
- todos
|
|
7
8
|
- smoke
|
|
8
9
|
|
|
9
10
|
steps:
|
|
@@ -19,8 +20,6 @@ steps:
|
|
|
19
20
|
capture:
|
|
20
21
|
- name: token
|
|
21
22
|
path: data.accessToken
|
|
22
|
-
- name: userId
|
|
23
|
-
path: data.user.id
|
|
24
23
|
assertions:
|
|
25
24
|
- path: status
|
|
26
25
|
operator: equals
|
|
@@ -28,10 +27,31 @@ steps:
|
|
|
28
27
|
- path: data.accessToken
|
|
29
28
|
operator: exists
|
|
30
29
|
|
|
31
|
-
- name:
|
|
30
|
+
- name: Create todo (authenticated)
|
|
31
|
+
request:
|
|
32
|
+
method: POST
|
|
33
|
+
url: "{api}/todos"
|
|
34
|
+
headers:
|
|
35
|
+
Content-Type: application/json
|
|
36
|
+
Authorization: "Bearer ${token}"
|
|
37
|
+
body:
|
|
38
|
+
title: "Deploy to production"
|
|
39
|
+
completed: false
|
|
40
|
+
capture:
|
|
41
|
+
- name: todoId
|
|
42
|
+
path: data.id
|
|
43
|
+
assertions:
|
|
44
|
+
- path: status
|
|
45
|
+
operator: equals
|
|
46
|
+
value: 201
|
|
47
|
+
- path: data.title
|
|
48
|
+
operator: equals
|
|
49
|
+
value: "Deploy to production"
|
|
50
|
+
|
|
51
|
+
- name: Read todo (authenticated)
|
|
32
52
|
request:
|
|
33
53
|
method: GET
|
|
34
|
-
url: "{api}/
|
|
54
|
+
url: "{api}/todos/${todoId}"
|
|
35
55
|
headers:
|
|
36
56
|
Authorization: "Bearer ${token}"
|
|
37
57
|
assertions:
|
|
@@ -40,12 +60,16 @@ steps:
|
|
|
40
60
|
value: 200
|
|
41
61
|
- path: data.id
|
|
42
62
|
operator: equals
|
|
43
|
-
value: "${
|
|
63
|
+
value: "${todoId}"
|
|
44
64
|
|
|
45
65
|
- name: Reject without token
|
|
46
66
|
request:
|
|
47
|
-
method:
|
|
48
|
-
url: "{api}/
|
|
67
|
+
method: POST
|
|
68
|
+
url: "{api}/todos"
|
|
69
|
+
headers:
|
|
70
|
+
Content-Type: application/json
|
|
71
|
+
body:
|
|
72
|
+
title: "Should fail"
|
|
49
73
|
assertions:
|
|
50
74
|
- path: status
|
|
51
75
|
operator: equals
|
package/examples/context.md
CHANGED
|
@@ -1,25 +1,27 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Todo API
|
|
2
2
|
|
|
3
3
|
## Description
|
|
4
|
-
Example API context for testflow-ai.
|
|
4
|
+
Example API context for testflow-ai — a simple Todo REST + GraphQL API.
|
|
5
5
|
|
|
6
6
|
## Base URLs
|
|
7
7
|
- api: http://localhost:3000
|
|
8
8
|
- graphql: http://localhost:3000/graphql
|
|
9
9
|
|
|
10
10
|
## Endpoints
|
|
11
|
-
- POST /
|
|
12
|
-
- GET /
|
|
13
|
-
-
|
|
14
|
-
-
|
|
11
|
+
- POST /todos - Create a new todo
|
|
12
|
+
- GET /todos/:id - Get todo by ID
|
|
13
|
+
- GET /todos - List all todos
|
|
14
|
+
- PUT /todos/:id - Update todo
|
|
15
|
+
- DELETE /todos/:id - Delete todo
|
|
15
16
|
- POST /auth/login - Authenticate and get token
|
|
16
17
|
- POST /graphql - GraphQL endpoint
|
|
17
18
|
|
|
18
19
|
## Rules
|
|
19
20
|
- All endpoints return JSON
|
|
20
|
-
- Authentication required for
|
|
21
|
+
- Authentication required for write operations
|
|
21
22
|
- Rate limit: 100 requests per minute
|
|
22
23
|
|
|
23
24
|
## AI Configuration
|
|
25
|
+
- provider: ollama
|
|
24
26
|
- url: http://localhost:11434
|
|
25
27
|
- model: llama3.2:3b
|
|
@@ -1,58 +1,58 @@
|
|
|
1
|
-
# GraphQL — Mutation + query with variable capture.
|
|
1
|
+
# GraphQL — Mutation + query with variable capture for todos.
|
|
2
2
|
|
|
3
|
-
name: GraphQL
|
|
4
|
-
description: Create a
|
|
3
|
+
name: GraphQL Todo Flow
|
|
4
|
+
description: Create a todo via mutation, then query it back
|
|
5
5
|
tags:
|
|
6
6
|
- graphql
|
|
7
|
-
-
|
|
7
|
+
- todos
|
|
8
8
|
|
|
9
9
|
steps:
|
|
10
|
-
- name: Create
|
|
10
|
+
- name: Create todo (mutation)
|
|
11
11
|
request:
|
|
12
12
|
method: POST
|
|
13
13
|
url: "{graphql}"
|
|
14
14
|
graphql:
|
|
15
15
|
query: |
|
|
16
|
-
mutation
|
|
17
|
-
|
|
16
|
+
mutation CreateTodo($input: CreateTodoInput!) {
|
|
17
|
+
createTodo(input: $input) {
|
|
18
18
|
id
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
title
|
|
20
|
+
completed
|
|
21
21
|
}
|
|
22
22
|
}
|
|
23
23
|
variables:
|
|
24
24
|
input:
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
title: "Learn GraphQL"
|
|
26
|
+
completed: false
|
|
27
27
|
capture:
|
|
28
|
-
- name:
|
|
29
|
-
path: data.
|
|
28
|
+
- name: todoId
|
|
29
|
+
path: data.createTodo.id
|
|
30
30
|
assertions:
|
|
31
|
-
- path: data.
|
|
31
|
+
- path: data.createTodo.title
|
|
32
32
|
operator: equals
|
|
33
|
-
value:
|
|
34
|
-
- path: data.
|
|
33
|
+
value: "Learn GraphQL"
|
|
34
|
+
- path: data.createTodo.id
|
|
35
35
|
operator: exists
|
|
36
36
|
|
|
37
|
-
- name: Query
|
|
37
|
+
- name: Query todo
|
|
38
38
|
request:
|
|
39
39
|
method: POST
|
|
40
40
|
url: "{graphql}"
|
|
41
41
|
graphql:
|
|
42
42
|
query: |
|
|
43
|
-
query
|
|
44
|
-
|
|
43
|
+
query GetTodo($id: ID!) {
|
|
44
|
+
todo(id: $id) {
|
|
45
45
|
id
|
|
46
|
-
|
|
47
|
-
|
|
46
|
+
title
|
|
47
|
+
completed
|
|
48
48
|
}
|
|
49
49
|
}
|
|
50
50
|
variables:
|
|
51
|
-
id: "${
|
|
51
|
+
id: "${todoId}"
|
|
52
52
|
assertions:
|
|
53
|
-
- path: data.
|
|
53
|
+
- path: data.todo.id
|
|
54
54
|
operator: equals
|
|
55
|
-
value: "${
|
|
56
|
-
- path: data.
|
|
55
|
+
value: "${todoId}"
|
|
56
|
+
- path: data.todo.title
|
|
57
57
|
operator: equals
|
|
58
|
-
value:
|
|
58
|
+
value: "Learn GraphQL"
|
package/examples/rest-crud.yaml
CHANGED
|
@@ -1,76 +1,77 @@
|
|
|
1
|
-
# REST CRUD — Create, read, update, verify a
|
|
1
|
+
# REST CRUD — Create, read, update, verify a todo item.
|
|
2
2
|
|
|
3
|
-
name:
|
|
4
|
-
description: Full lifecycle test for a REST
|
|
3
|
+
name: Todo REST CRUD
|
|
4
|
+
description: Full lifecycle test for a REST todo resource
|
|
5
5
|
tags:
|
|
6
|
-
-
|
|
6
|
+
- todos
|
|
7
7
|
- crud
|
|
8
8
|
- smoke
|
|
9
9
|
|
|
10
10
|
steps:
|
|
11
|
-
- name: Create
|
|
11
|
+
- name: Create todo
|
|
12
12
|
request:
|
|
13
13
|
method: POST
|
|
14
|
-
url: "{api}/
|
|
14
|
+
url: "{api}/todos"
|
|
15
15
|
headers:
|
|
16
16
|
Content-Type: application/json
|
|
17
17
|
body:
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
title: "Write unit tests"
|
|
19
|
+
completed: false
|
|
20
20
|
capture:
|
|
21
|
-
- name:
|
|
21
|
+
- name: todoId
|
|
22
22
|
path: data.id
|
|
23
|
-
- name:
|
|
24
|
-
path: data.
|
|
23
|
+
- name: todoTitle
|
|
24
|
+
path: data.title
|
|
25
25
|
assertions:
|
|
26
26
|
- path: status
|
|
27
27
|
operator: equals
|
|
28
28
|
value: 201
|
|
29
|
-
- path: data.
|
|
29
|
+
- path: data.title
|
|
30
30
|
operator: equals
|
|
31
|
-
value:
|
|
31
|
+
value: "Write unit tests"
|
|
32
32
|
- path: data.id
|
|
33
33
|
operator: exists
|
|
34
34
|
|
|
35
|
-
- name: Read
|
|
35
|
+
- name: Read todo
|
|
36
36
|
request:
|
|
37
37
|
method: GET
|
|
38
|
-
url: "{api}/
|
|
38
|
+
url: "{api}/todos/${todoId}"
|
|
39
39
|
assertions:
|
|
40
40
|
- path: status
|
|
41
41
|
operator: equals
|
|
42
42
|
value: 200
|
|
43
43
|
- path: data.id
|
|
44
44
|
operator: equals
|
|
45
|
-
value: "${
|
|
46
|
-
- path: data.
|
|
45
|
+
value: "${todoId}"
|
|
46
|
+
- path: data.title
|
|
47
47
|
operator: equals
|
|
48
|
-
value: "${
|
|
48
|
+
value: "${todoTitle}"
|
|
49
49
|
|
|
50
|
-
- name: Update
|
|
50
|
+
- name: Update todo
|
|
51
51
|
request:
|
|
52
52
|
method: PUT
|
|
53
|
-
url: "{api}/
|
|
53
|
+
url: "{api}/todos/${todoId}"
|
|
54
54
|
headers:
|
|
55
55
|
Content-Type: application/json
|
|
56
56
|
body:
|
|
57
|
-
|
|
57
|
+
title: "Write unit tests (done)"
|
|
58
|
+
completed: true
|
|
58
59
|
assertions:
|
|
59
60
|
- path: status
|
|
60
61
|
operator: equals
|
|
61
62
|
value: 200
|
|
62
|
-
- path: data.
|
|
63
|
+
- path: data.title
|
|
63
64
|
operator: equals
|
|
64
|
-
value:
|
|
65
|
+
value: "Write unit tests (done)"
|
|
65
66
|
|
|
66
67
|
- name: Verify update
|
|
67
68
|
request:
|
|
68
69
|
method: GET
|
|
69
|
-
url: "{api}/
|
|
70
|
+
url: "{api}/todos/${todoId}"
|
|
70
71
|
assertions:
|
|
71
|
-
- path: data.
|
|
72
|
+
- path: data.title
|
|
72
73
|
operator: equals
|
|
73
|
-
value:
|
|
74
|
-
- path: data.
|
|
74
|
+
value: "Write unit tests (done)"
|
|
75
|
+
- path: data.completed
|
|
75
76
|
operator: equals
|
|
76
|
-
value:
|
|
77
|
+
value: true
|
package/package.json
CHANGED