executable-stories-formatters 0.9.0 → 0.10.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "executable-stories-formatters",
3
- "version": "0.9.0",
3
+ "version": "0.10.0",
4
4
  "description": "Cucumber-compatible report formats (HTML, Markdown, JUnit XML, Cucumber JSON) for executable-stories test results.",
5
5
  "author": "Jag Reehal <jag@jagreehal.com>",
6
6
  "license": "MIT",
@@ -0,0 +1,65 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://executable-stories.dev/schemas/behavior-manifest-v1.json",
4
+ "title": "Executable Stories Behavior Manifest v1",
5
+ "type": "object",
6
+ "required": ["schemaVersion", "runId", "generatedAtMs", "summary", "sourceFiles", "tags", "docCoverage", "debugger"],
7
+ "additionalProperties": false,
8
+ "properties": {
9
+ "schemaVersion": { "const": "1.0" },
10
+ "runId": { "type": "string" },
11
+ "generatedAtMs": { "type": "number" },
12
+ "summary": { "$ref": "scenario-index-v1.json#/$defs/summary" },
13
+ "sourceFiles": {
14
+ "type": "array",
15
+ "items": {
16
+ "type": "object",
17
+ "required": ["path", "scenarioCount", "failed", "tags"],
18
+ "additionalProperties": false,
19
+ "properties": {
20
+ "path": { "type": "string" },
21
+ "scenarioCount": { "type": "number" },
22
+ "failed": { "type": "number" },
23
+ "tags": { "type": "array", "items": { "type": "string" } }
24
+ }
25
+ }
26
+ },
27
+ "tags": {
28
+ "type": "array",
29
+ "items": {
30
+ "type": "object",
31
+ "required": ["name", "scenarioCount"],
32
+ "additionalProperties": false,
33
+ "properties": {
34
+ "name": { "type": "string" },
35
+ "scenarioCount": { "type": "number" }
36
+ }
37
+ }
38
+ },
39
+ "docCoverage": {
40
+ "type": "object",
41
+ "required": ["scenariosWithDocs", "scenariosWithoutDocs", "docKinds"],
42
+ "additionalProperties": false,
43
+ "properties": {
44
+ "scenariosWithDocs": { "type": "number" },
45
+ "scenariosWithoutDocs": { "type": "number" },
46
+ "docKinds": { "type": "array", "items": { "type": "string" } }
47
+ }
48
+ },
49
+ "debugger": {
50
+ "type": "array",
51
+ "items": {
52
+ "type": "object",
53
+ "required": ["severity", "code", "scenarioId", "title", "message"],
54
+ "additionalProperties": false,
55
+ "properties": {
56
+ "severity": { "const": "warning" },
57
+ "code": { "enum": ["missing-docs", "missing-tags", "missing-covers", "missing-source-line"] },
58
+ "scenarioId": { "type": "string" },
59
+ "title": { "type": "string" },
60
+ "message": { "type": "string" }
61
+ }
62
+ }
63
+ }
64
+ }
65
+ }
@@ -11,7 +11,11 @@
11
11
  {
12
12
  "externalId": "MyApp.Tests.Auth.LoginTests.SuccessfulLogin_ReturnsToken",
13
13
  "title": "Successful login returns token",
14
- "titlePath": ["MyApp.Tests.Auth", "LoginTests", "Successful login returns token"],
14
+ "titlePath": [
15
+ "MyApp.Tests.Auth",
16
+ "LoginTests",
17
+ "Successful login returns token"
18
+ ],
15
19
  "sourceFile": "tests/MyApp.Tests/Auth/LoginTests.cs",
16
20
  "sourceLine": 22,
17
21
  "status": "pass",
@@ -19,15 +23,38 @@
19
23
  "story": {
20
24
  "scenario": "Successful login returns token",
21
25
  "steps": [
22
- { "keyword": "Given", "text": "a registered user with email 'alice@example.com'" },
23
- { "keyword": "When", "text": "the user submits login with valid credentials" },
24
- { "keyword": "Then", "text": "the response status is 200" },
25
- { "keyword": "And", "text": "a JWT token is returned" }
26
+ {
27
+ "keyword": "Given",
28
+ "text": "a registered user with email 'alice@example.com'"
29
+ },
30
+ {
31
+ "keyword": "When",
32
+ "text": "the user submits login with valid credentials"
33
+ },
34
+ {
35
+ "keyword": "Then",
36
+ "text": "the response status is 200"
37
+ },
38
+ {
39
+ "keyword": "And",
40
+ "text": "a JWT token is returned"
41
+ }
26
42
  ],
27
- "tags": ["smoke", "auth"],
28
- "tickets": ["AUTH-101"],
29
- "suitePath": ["MyApp.Tests.Auth", "LoginTests"],
30
- "sourceOrder": 0
43
+ "tags": [
44
+ "smoke",
45
+ "auth"
46
+ ],
47
+ "tickets": [
48
+ "AUTH-101"
49
+ ],
50
+ "suitePath": [
51
+ "MyApp.Tests.Auth",
52
+ "LoginTests"
53
+ ],
54
+ "sourceOrder": 0,
55
+ "covers": [
56
+ "src/auth/login.*"
57
+ ]
31
58
  },
32
59
  "meta": {
33
60
  "framework": "xunit",
@@ -37,7 +64,11 @@
37
64
  {
38
65
  "externalId": "MyApp.Tests.Auth.LoginTests.InvalidPassword_Returns401",
39
66
  "title": "Invalid password returns 401",
40
- "titlePath": ["MyApp.Tests.Auth", "LoginTests", "Invalid password returns 401"],
67
+ "titlePath": [
68
+ "MyApp.Tests.Auth",
69
+ "LoginTests",
70
+ "Invalid password returns 401"
71
+ ],
41
72
  "sourceFile": "tests/MyApp.Tests/Auth/LoginTests.cs",
42
73
  "sourceLine": 48,
43
74
  "status": "fail",
@@ -54,7 +85,11 @@
54
85
  {
55
86
  "externalId": "MyApp.Tests.Auth.LoginTests.RateLimiting_BlocksAfterFiveAttempts",
56
87
  "title": "Rate limiting blocks after five attempts",
57
- "titlePath": ["MyApp.Tests.Auth", "LoginTests", "Rate limiting blocks after five attempts"],
88
+ "titlePath": [
89
+ "MyApp.Tests.Auth",
90
+ "LoginTests",
91
+ "Rate limiting blocks after five attempts"
92
+ ],
58
93
  "sourceFile": "tests/MyApp.Tests/Auth/LoginTests.cs",
59
94
  "sourceLine": 75,
60
95
  "status": "skip",
@@ -68,7 +103,11 @@
68
103
  {
69
104
  "externalId": "MyApp.Tests.Cart.CheckoutTests.CompleteCheckout_WithCreditCard",
70
105
  "title": "Complete checkout with credit card",
71
- "titlePath": ["MyApp.Tests.Cart", "CheckoutTests", "Complete checkout with credit card"],
106
+ "titlePath": [
107
+ "MyApp.Tests.Cart",
108
+ "CheckoutTests",
109
+ "Complete checkout with credit card"
110
+ ],
72
111
  "sourceFile": "tests/MyApp.Tests/Cart/CheckoutTests.cs",
73
112
  "sourceLine": 16,
74
113
  "status": "pass",
@@ -76,14 +115,35 @@
76
115
  "story": {
77
116
  "scenario": "Complete checkout with credit card",
78
117
  "steps": [
79
- { "keyword": "Given", "text": "a cart with 2 items totaling $59.98" },
80
- { "keyword": "When", "text": "the user submits payment with a test credit card" },
81
- { "keyword": "Then", "text": "the order is confirmed" },
82
- { "keyword": "And", "text": "a confirmation email is queued" }
118
+ {
119
+ "keyword": "Given",
120
+ "text": "a cart with 2 items totaling $59.98"
121
+ },
122
+ {
123
+ "keyword": "When",
124
+ "text": "the user submits payment with a test credit card"
125
+ },
126
+ {
127
+ "keyword": "Then",
128
+ "text": "the order is confirmed"
129
+ },
130
+ {
131
+ "keyword": "And",
132
+ "text": "a confirmation email is queued"
133
+ }
134
+ ],
135
+ "tags": [
136
+ "checkout",
137
+ "payments",
138
+ "e2e"
139
+ ],
140
+ "tickets": [
141
+ "SHOP-200"
142
+ ],
143
+ "suitePath": [
144
+ "MyApp.Tests.Cart",
145
+ "CheckoutTests"
83
146
  ],
84
- "tags": ["checkout", "payments", "e2e"],
85
- "tickets": ["SHOP-200"],
86
- "suitePath": ["MyApp.Tests.Cart", "CheckoutTests"],
87
147
  "sourceOrder": 0
88
148
  },
89
149
  "meta": {
@@ -94,7 +154,11 @@
94
154
  {
95
155
  "externalId": "MyApp.Tests.Cart.CheckoutTests.EmptyCart_ShouldBlock",
96
156
  "title": "Empty cart should block checkout",
97
- "titlePath": ["MyApp.Tests.Cart", "CheckoutTests", "Empty cart should block checkout"],
157
+ "titlePath": [
158
+ "MyApp.Tests.Cart",
159
+ "CheckoutTests",
160
+ "Empty cart should block checkout"
161
+ ],
98
162
  "sourceFile": "tests/MyApp.Tests/Cart/CheckoutTests.cs",
99
163
  "sourceLine": 50,
100
164
  "status": "pass",
@@ -11,7 +11,10 @@
11
11
  {
12
12
  "externalId": "myapp/auth.TestSuccessfulLogin",
13
13
  "title": "Successful login with valid credentials",
14
- "titlePath": ["myapp/auth", "TestSuccessfulLogin"],
14
+ "titlePath": [
15
+ "myapp/auth",
16
+ "TestSuccessfulLogin"
17
+ ],
15
18
  "sourceFile": "auth/auth_test.go",
16
19
  "sourceLine": 18,
17
20
  "status": "pass",
@@ -19,15 +22,37 @@
19
22
  "story": {
20
23
  "scenario": "Successful login with valid credentials",
21
24
  "steps": [
22
- { "keyword": "Given", "text": "a registered user with email 'alice@example.com'" },
23
- { "keyword": "When", "text": "the user submits login with valid credentials" },
24
- { "keyword": "Then", "text": "the response status is 200" },
25
- { "keyword": "And", "text": "a JWT token is returned" }
25
+ {
26
+ "keyword": "Given",
27
+ "text": "a registered user with email 'alice@example.com'"
28
+ },
29
+ {
30
+ "keyword": "When",
31
+ "text": "the user submits login with valid credentials"
32
+ },
33
+ {
34
+ "keyword": "Then",
35
+ "text": "the response status is 200"
36
+ },
37
+ {
38
+ "keyword": "And",
39
+ "text": "a JWT token is returned"
40
+ }
26
41
  ],
27
- "tags": ["smoke", "auth"],
28
- "tickets": ["AUTH-101"],
29
- "suitePath": ["myapp/auth"],
30
- "sourceOrder": 0
42
+ "tags": [
43
+ "smoke",
44
+ "auth"
45
+ ],
46
+ "tickets": [
47
+ "AUTH-101"
48
+ ],
49
+ "suitePath": [
50
+ "myapp/auth"
51
+ ],
52
+ "sourceOrder": 0,
53
+ "covers": [
54
+ "src/auth/login.*"
55
+ ]
31
56
  },
32
57
  "meta": {
33
58
  "framework": "go",
@@ -37,7 +62,10 @@
37
62
  {
38
63
  "externalId": "myapp/auth.TestLoginInvalidPassword",
39
64
  "title": "Login with invalid password returns 401",
40
- "titlePath": ["myapp/auth", "TestLoginInvalidPassword"],
65
+ "titlePath": [
66
+ "myapp/auth",
67
+ "TestLoginInvalidPassword"
68
+ ],
41
69
  "sourceFile": "auth/auth_test.go",
42
70
  "sourceLine": 45,
43
71
  "status": "fail",
@@ -54,7 +82,10 @@
54
82
  {
55
83
  "externalId": "myapp/auth.TestLoginRateLimiting",
56
84
  "title": "Login is rate-limited after 5 failed attempts",
57
- "titlePath": ["myapp/auth", "TestLoginRateLimiting"],
85
+ "titlePath": [
86
+ "myapp/auth",
87
+ "TestLoginRateLimiting"
88
+ ],
58
89
  "sourceFile": "auth/auth_test.go",
59
90
  "sourceLine": 72,
60
91
  "status": "skip",
@@ -68,7 +99,10 @@
68
99
  {
69
100
  "externalId": "myapp/cart.TestCompleteCheckout",
70
101
  "title": "Complete checkout with credit card",
71
- "titlePath": ["myapp/cart", "TestCompleteCheckout"],
102
+ "titlePath": [
103
+ "myapp/cart",
104
+ "TestCompleteCheckout"
105
+ ],
72
106
  "sourceFile": "cart/checkout_test.go",
73
107
  "sourceLine": 15,
74
108
  "status": "pass",
@@ -76,14 +110,34 @@
76
110
  "story": {
77
111
  "scenario": "Complete checkout with credit card",
78
112
  "steps": [
79
- { "keyword": "Given", "text": "a cart with 2 items totaling $59.98" },
80
- { "keyword": "When", "text": "the user submits payment with a test credit card" },
81
- { "keyword": "Then", "text": "the order is confirmed" },
82
- { "keyword": "And", "text": "a confirmation email is queued" }
113
+ {
114
+ "keyword": "Given",
115
+ "text": "a cart with 2 items totaling $59.98"
116
+ },
117
+ {
118
+ "keyword": "When",
119
+ "text": "the user submits payment with a test credit card"
120
+ },
121
+ {
122
+ "keyword": "Then",
123
+ "text": "the order is confirmed"
124
+ },
125
+ {
126
+ "keyword": "And",
127
+ "text": "a confirmation email is queued"
128
+ }
129
+ ],
130
+ "tags": [
131
+ "checkout",
132
+ "payments",
133
+ "e2e"
134
+ ],
135
+ "tickets": [
136
+ "SHOP-200"
137
+ ],
138
+ "suitePath": [
139
+ "myapp/cart"
83
140
  ],
84
- "tags": ["checkout", "payments", "e2e"],
85
- "tickets": ["SHOP-200"],
86
- "suitePath": ["myapp/cart"],
87
141
  "sourceOrder": 0
88
142
  },
89
143
  "meta": {
@@ -94,7 +148,10 @@
94
148
  {
95
149
  "externalId": "myapp/cart.TestEmptyCartCheckout",
96
150
  "title": "Cannot checkout with an empty cart",
97
- "titlePath": ["myapp/cart", "TestEmptyCartCheckout"],
151
+ "titlePath": [
152
+ "myapp/cart",
153
+ "TestEmptyCartCheckout"
154
+ ],
98
155
  "sourceFile": "cart/checkout_test.go",
99
156
  "sourceLine": 48,
100
157
  "status": "pass",
@@ -11,7 +11,11 @@
11
11
  {
12
12
  "externalId": "[engine:junit-jupiter]/[class:com.acme.auth.LoginTest]/[method:testSuccessfulLogin()]",
13
13
  "title": "Successful login with valid credentials",
14
- "titlePath": ["com.acme.auth", "LoginTest", "Successful login with valid credentials"],
14
+ "titlePath": [
15
+ "com.acme.auth",
16
+ "LoginTest",
17
+ "Successful login with valid credentials"
18
+ ],
15
19
  "sourceFile": "src/test/java/com/acme/auth/LoginTest.java",
16
20
  "sourceLine": 24,
17
21
  "status": "pass",
@@ -19,15 +23,38 @@
19
23
  "story": {
20
24
  "scenario": "Successful login with valid credentials",
21
25
  "steps": [
22
- { "keyword": "Given", "text": "a registered user with email 'alice@example.com'" },
23
- { "keyword": "When", "text": "the user submits login with valid credentials" },
24
- { "keyword": "Then", "text": "the response status is 200" },
25
- { "keyword": "And", "text": "a JWT token is returned" }
26
+ {
27
+ "keyword": "Given",
28
+ "text": "a registered user with email 'alice@example.com'"
29
+ },
30
+ {
31
+ "keyword": "When",
32
+ "text": "the user submits login with valid credentials"
33
+ },
34
+ {
35
+ "keyword": "Then",
36
+ "text": "the response status is 200"
37
+ },
38
+ {
39
+ "keyword": "And",
40
+ "text": "a JWT token is returned"
41
+ }
26
42
  ],
27
- "tags": ["smoke", "auth"],
28
- "tickets": ["AUTH-101"],
29
- "suitePath": ["com.acme.auth", "LoginTest"],
30
- "sourceOrder": 0
43
+ "tags": [
44
+ "smoke",
45
+ "auth"
46
+ ],
47
+ "tickets": [
48
+ "AUTH-101"
49
+ ],
50
+ "suitePath": [
51
+ "com.acme.auth",
52
+ "LoginTest"
53
+ ],
54
+ "sourceOrder": 0,
55
+ "covers": [
56
+ "src/auth/login.*"
57
+ ]
31
58
  },
32
59
  "meta": {
33
60
  "framework": "junit5",
@@ -37,7 +64,11 @@
37
64
  {
38
65
  "externalId": "[engine:junit-jupiter]/[class:com.acme.auth.LoginTest]/[method:testLoginInvalidPassword()]",
39
66
  "title": "Login with invalid password returns 401",
40
- "titlePath": ["com.acme.auth", "LoginTest", "Login with invalid password returns 401"],
67
+ "titlePath": [
68
+ "com.acme.auth",
69
+ "LoginTest",
70
+ "Login with invalid password returns 401"
71
+ ],
41
72
  "sourceFile": "src/test/java/com/acme/auth/LoginTest.java",
42
73
  "sourceLine": 48,
43
74
  "status": "fail",
@@ -54,7 +85,11 @@
54
85
  {
55
86
  "externalId": "[engine:junit-jupiter]/[class:com.acme.auth.LoginTest]/[method:testLoginRateLimiting()]",
56
87
  "title": "Login is rate-limited after 5 failed attempts",
57
- "titlePath": ["com.acme.auth", "LoginTest", "Login is rate-limited after 5 failed attempts"],
88
+ "titlePath": [
89
+ "com.acme.auth",
90
+ "LoginTest",
91
+ "Login is rate-limited after 5 failed attempts"
92
+ ],
58
93
  "sourceFile": "src/test/java/com/acme/auth/LoginTest.java",
59
94
  "sourceLine": 75,
60
95
  "status": "skip",
@@ -68,7 +103,11 @@
68
103
  {
69
104
  "externalId": "[engine:junit-jupiter]/[class:com.acme.cart.CheckoutTest]/[method:testCompleteCheckout()]",
70
105
  "title": "Complete checkout with credit card",
71
- "titlePath": ["com.acme.cart", "CheckoutTest", "Complete checkout with credit card"],
106
+ "titlePath": [
107
+ "com.acme.cart",
108
+ "CheckoutTest",
109
+ "Complete checkout with credit card"
110
+ ],
72
111
  "sourceFile": "src/test/java/com/acme/cart/CheckoutTest.java",
73
112
  "sourceLine": 18,
74
113
  "status": "pass",
@@ -76,14 +115,35 @@
76
115
  "story": {
77
116
  "scenario": "Complete checkout with credit card",
78
117
  "steps": [
79
- { "keyword": "Given", "text": "a cart with 2 items totaling $59.98" },
80
- { "keyword": "When", "text": "the user submits payment with a test credit card" },
81
- { "keyword": "Then", "text": "the order is confirmed" },
82
- { "keyword": "And", "text": "a confirmation email is queued" }
118
+ {
119
+ "keyword": "Given",
120
+ "text": "a cart with 2 items totaling $59.98"
121
+ },
122
+ {
123
+ "keyword": "When",
124
+ "text": "the user submits payment with a test credit card"
125
+ },
126
+ {
127
+ "keyword": "Then",
128
+ "text": "the order is confirmed"
129
+ },
130
+ {
131
+ "keyword": "And",
132
+ "text": "a confirmation email is queued"
133
+ }
134
+ ],
135
+ "tags": [
136
+ "checkout",
137
+ "payments",
138
+ "e2e"
139
+ ],
140
+ "tickets": [
141
+ "SHOP-200"
142
+ ],
143
+ "suitePath": [
144
+ "com.acme.cart",
145
+ "CheckoutTest"
83
146
  ],
84
- "tags": ["checkout", "payments", "e2e"],
85
- "tickets": ["SHOP-200"],
86
- "suitePath": ["com.acme.cart", "CheckoutTest"],
87
147
  "sourceOrder": 0
88
148
  },
89
149
  "meta": {
@@ -94,7 +154,11 @@
94
154
  {
95
155
  "externalId": "[engine:junit-jupiter]/[class:com.acme.cart.CheckoutTest]/[method:testEmptyCartCheckout()]",
96
156
  "title": "Cannot checkout with an empty cart",
97
- "titlePath": ["com.acme.cart", "CheckoutTest", "Cannot checkout with an empty cart"],
157
+ "titlePath": [
158
+ "com.acme.cart",
159
+ "CheckoutTest",
160
+ "Cannot checkout with an empty cart"
161
+ ],
98
162
  "sourceFile": "src/test/java/com/acme/cart/CheckoutTest.java",
99
163
  "sourceLine": 52,
100
164
  "status": "pass",