@esimplicitylabs/katalyst-xspec 0.6.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.
Files changed (29) hide show
  1. package/LICENSE +7 -0
  2. package/README.md +69 -0
  3. package/bin/katalyst-xspec.cjs +54 -0
  4. package/cli/init.cjs +679 -0
  5. package/cli/stubs.cjs +365 -0
  6. package/cli/upgrade.cjs +1014 -0
  7. package/dist/chunk-ACAXOGKZ.js +1611 -0
  8. package/dist/index.d.ts +881 -0
  9. package/dist/index.js +1091 -0
  10. package/dist/steps/index.d.ts +151 -0
  11. package/dist/steps/index.js +50 -0
  12. package/package.json +80 -0
  13. package/scripts/postinstall.cjs +85 -0
  14. package/skills/katalyst-bdd-architecture/SKILL.md +517 -0
  15. package/skills/katalyst-bdd-architecture/references/adapters.md +310 -0
  16. package/skills/katalyst-bdd-architecture/references/custom-steps.md +360 -0
  17. package/skills/katalyst-bdd-architecture/references/ports.md +256 -0
  18. package/skills/katalyst-bdd-create-test/SKILL.md +366 -0
  19. package/skills/katalyst-bdd-create-test/references/api-patterns.md +371 -0
  20. package/skills/katalyst-bdd-create-test/references/hybrid-patterns.md +420 -0
  21. package/skills/katalyst-bdd-create-test/references/tui-patterns.md +458 -0
  22. package/skills/katalyst-bdd-create-test/references/ui-patterns.md +415 -0
  23. package/skills/katalyst-bdd-quickstart/SKILL.md +292 -0
  24. package/skills/katalyst-bdd-step-reference/SKILL.md +147 -0
  25. package/skills/katalyst-bdd-step-reference/references/api-steps.md +247 -0
  26. package/skills/katalyst-bdd-step-reference/references/shared-steps.md +340 -0
  27. package/skills/katalyst-bdd-step-reference/references/tui-steps.md +483 -0
  28. package/skills/katalyst-bdd-step-reference/references/ui-steps.md +521 -0
  29. package/skills/katalyst-bdd-troubleshooting/SKILL.md +449 -0
@@ -0,0 +1,420 @@
1
+ # Hybrid Test Patterns
2
+
3
+ Common patterns for hybrid testing (combining API and UI) with the Katalyst BDD framework.
4
+
5
+ ## Core Principle
6
+
7
+ Hybrid tests use `@hybrid` tag to access both API and UI steps. The typical flow:
8
+ 1. **Setup** - Create test data via API (fast, reliable)
9
+ 2. **Test** - Verify behavior in UI (user-facing validation)
10
+ 3. **Cleanup** - Remove test data via API (automatic)
11
+
12
+ ## Basic Patterns
13
+
14
+ ### Create via API, Verify in UI
15
+
16
+ ```gherkin
17
+ @hybrid
18
+ Scenario: Create user via API, verify in admin panel
19
+ # API: Create test data
20
+ Given I am authenticated as an admin via API
21
+ Given I generate a UUID and store as "testId"
22
+ When I POST "/admin/users" with JSON body:
23
+ """
24
+ {
25
+ "email": "test-{testId}@example.com",
26
+ "name": "Test User {testId}"
27
+ }
28
+ """
29
+ Then the response status should be 201
30
+ And I store the value at "id" as "userId"
31
+ Given I register cleanup DELETE "/admin/users/{userId}"
32
+
33
+ # UI: Verify user appears
34
+ Given I navigate to "/admin/users"
35
+ Then I should see text "test-{testId}@example.com"
36
+ Then I should see text "Test User {testId}"
37
+ ```
38
+
39
+ ### Setup Data, Test Workflow
40
+
41
+ ```gherkin
42
+ @hybrid
43
+ Scenario: Test order workflow with pre-created product
44
+ # API: Create product
45
+ Given I am authenticated as an admin via API
46
+ Given I generate a UUID and store as "productId"
47
+ When I POST "/admin/products" with JSON body:
48
+ """
49
+ {
50
+ "name": "Test Product {productId}",
51
+ "price": 99.99,
52
+ "stock": 100
53
+ }
54
+ """
55
+ Then the response status should be 201
56
+ And I store the value at "id" as "prodId"
57
+ Given I register cleanup DELETE "/admin/products/{prodId}"
58
+
59
+ # UI: Test ordering flow
60
+ Given I am authenticated in UI as "customer"
61
+ Given I navigate to "/products/{prodId}"
62
+ Then I should see text "Test Product {productId}"
63
+ When I click the button "Add to Cart"
64
+ Then I should see text "Added to cart"
65
+ ```
66
+
67
+ ### Verify API Changes Reflect in UI
68
+
69
+ ```gherkin
70
+ @hybrid
71
+ Scenario: API update reflects in UI
72
+ # API: Create and update
73
+ Given I am authenticated as an admin via API
74
+ When I POST "/users" with JSON body:
75
+ """
76
+ { "name": "Original Name" }
77
+ """
78
+ Then the response status should be 201
79
+ And I store the value at "id" as "userId"
80
+ Given I register cleanup DELETE "/users/{userId}"
81
+
82
+ When I PATCH "/users/{userId}" with JSON body:
83
+ """
84
+ { "name": "Updated Name" }
85
+ """
86
+ Then the response status should be 200
87
+
88
+ # UI: Verify update is visible
89
+ Given I navigate to "/users/{userId}"
90
+ Then I should see text "Updated Name"
91
+ And I should not see text "Original Name"
92
+ ```
93
+
94
+ ## Variable Sharing Patterns
95
+
96
+ ### Share IDs Between Layers
97
+
98
+ ```gherkin
99
+ @hybrid
100
+ Scenario: Use API-created ID in UI navigation
101
+ # API: Create resource
102
+ Given I am authenticated as an admin via API
103
+ When I POST "/projects" with JSON body:
104
+ """
105
+ { "name": "Test Project" }
106
+ """
107
+ Then the response status should be 201
108
+ And I store the value at "id" as "projectId"
109
+ Given I register cleanup DELETE "/projects/{projectId}"
110
+
111
+ # UI: Navigate using ID
112
+ Given I navigate to "/projects/{projectId}"
113
+ Then I should see text "Test Project"
114
+ And the URL should contain "/projects/{projectId}"
115
+ ```
116
+
117
+ ### Share Data Between Layers
118
+
119
+ ```gherkin
120
+ @hybrid
121
+ Scenario: Verify API data in UI
122
+ # Setup variables
123
+ Given I generate a UUID and store as "runId"
124
+ Given I set variable "testEmail" to "hybrid-{runId}@test.com"
125
+ Given I set variable "testName" to "Hybrid User {runId}"
126
+
127
+ # API: Create with variables
128
+ Given I am authenticated as an admin via API
129
+ When I POST "/users" with JSON body:
130
+ """
131
+ {
132
+ "email": "{testEmail}",
133
+ "name": "{testName}"
134
+ }
135
+ """
136
+ Then the response status should be 201
137
+ And I store the value at "id" as "userId"
138
+ Given I register cleanup DELETE "/users/{userId}"
139
+
140
+ # UI: Verify same variables
141
+ Given I navigate to "/users/{userId}"
142
+ Then I should see text "{testEmail}"
143
+ Then I should see text "{testName}"
144
+ ```
145
+
146
+ ## Authentication Patterns
147
+
148
+ ### Separate API and UI Auth
149
+
150
+ ```gherkin
151
+ @hybrid
152
+ Scenario: Different auth for API vs UI
153
+ # API: Admin creates data
154
+ Given I am authenticated as an admin via API
155
+ When I POST "/admin/announcements" with JSON body:
156
+ """
157
+ { "message": "Test announcement", "audience": "all" }
158
+ """
159
+ Then the response status should be 201
160
+ And I store the value at "id" as "announcementId"
161
+ Given I register cleanup DELETE "/admin/announcements/{announcementId}"
162
+
163
+ # UI: Regular user sees announcement
164
+ Given I am authenticated in UI as "user"
165
+ Given I navigate to "/dashboard"
166
+ Then I should see text "Test announcement"
167
+ ```
168
+
169
+ ### Use API Token in UI
170
+
171
+ ```gherkin
172
+ @hybrid
173
+ Scenario: Get token from API, use in UI
174
+ # API: Login and get token
175
+ When I POST "/auth/login" with JSON body:
176
+ """
177
+ { "email": "user@example.com", "password": "password" }
178
+ """
179
+ Then the response status should be 200
180
+ And I store the value at "token" as "authToken"
181
+
182
+ # UI: Use token for authentication
183
+ Given I am authenticated in UI with bearer token "{authToken}"
184
+ Given I navigate to "/profile"
185
+ Then I should see text "My Profile"
186
+ ```
187
+
188
+ ## Complex Workflow Patterns
189
+
190
+ ### Multi-Step Business Process
191
+
192
+ ```gherkin
193
+ @hybrid
194
+ Scenario: Complete order processing workflow
195
+ # API: Setup - Create customer and product
196
+ Given I am authenticated as an admin via API
197
+ Given I generate a UUID and store as "runId"
198
+
199
+ When I POST "/customers" with JSON body:
200
+ """
201
+ { "email": "customer-{runId}@test.com" }
202
+ """
203
+ Then the response status should be 201
204
+ And I store the value at "id" as "customerId"
205
+ Given I register cleanup DELETE "/customers/{customerId}"
206
+
207
+ When I POST "/products" with JSON body:
208
+ """
209
+ { "name": "Product {runId}", "price": 50.00 }
210
+ """
211
+ Then the response status should be 201
212
+ And I store the value at "id" as "productId"
213
+ Given I register cleanup DELETE "/products/{productId}"
214
+
215
+ # UI: Customer places order
216
+ Given I am authenticated in UI as "customer-{runId}@test.com"
217
+ Given I navigate to "/products/{productId}"
218
+ When I click the button "Buy Now"
219
+ Then I should see text "Order Confirmation"
220
+ And I store the current URL as "orderUrl"
221
+
222
+ # API: Verify order created
223
+ When I GET "/customers/{customerId}/orders"
224
+ Then the response status should be 200
225
+ And the response should be a JSON array
226
+ ```
227
+
228
+ ### Data Synchronization Test
229
+
230
+ ```gherkin
231
+ @hybrid
232
+ Scenario: Real-time sync between API and UI
233
+ Given I am authenticated as an admin via API
234
+ Given I generate a UUID and store as "runId"
235
+
236
+ # API: Create initial data
237
+ When I POST "/messages" with JSON body:
238
+ """
239
+ { "content": "Message {runId}" }
240
+ """
241
+ Then the response status should be 201
242
+ And I store the value at "id" as "messageId"
243
+ Given I register cleanup DELETE "/messages/{messageId}"
244
+
245
+ # UI: Open page to watch for updates
246
+ Given I am authenticated in UI as "user"
247
+ Given I navigate to "/messages"
248
+ Then I should see text "Message {runId}"
249
+
250
+ # API: Update data
251
+ When I PATCH "/messages/{messageId}" with JSON body:
252
+ """
253
+ { "content": "Updated Message {runId}" }
254
+ """
255
+ Then the response status should be 200
256
+
257
+ # UI: Verify update (may need to refresh or wait for websocket)
258
+ When I reload the page
259
+ Then I should see text "Updated Message {runId}"
260
+ ```
261
+
262
+ ## State Management Patterns
263
+
264
+ ### Clean State Between Tests
265
+
266
+ ```gherkin
267
+ @hybrid
268
+ Feature: User Settings
269
+
270
+ Background:
271
+ Given I am authenticated as an admin via API
272
+ Given I generate a UUID and store as "testId"
273
+
274
+ # Create fresh user for each test
275
+ When I POST "/users" with JSON body:
276
+ """
277
+ { "email": "settings-{testId}@test.com" }
278
+ """
279
+ Then the response status should be 201
280
+ And I store the value at "id" as "userId"
281
+ Given I register cleanup DELETE "/users/{userId}"
282
+
283
+ Scenario: Update notification settings
284
+ Given I navigate to "/users/{userId}/settings"
285
+ When I click the "Notifications" tab
286
+ And I click the element "#email-notifications"
287
+ And I click the button "Save"
288
+ Then I should see text "Settings saved"
289
+
290
+ # Verify via API
291
+ When I GET "/users/{userId}/settings"
292
+ Then the value at "notifications.email" should equal "true"
293
+
294
+ Scenario: Update privacy settings
295
+ # Uses fresh user from Background
296
+ Given I navigate to "/users/{userId}/settings"
297
+ When I click the "Privacy" tab
298
+ # ... test privacy settings
299
+ ```
300
+
301
+ ### Seed Multiple Resources
302
+
303
+ ```gherkin
304
+ @hybrid
305
+ Scenario: Dashboard with multiple data types
306
+ Given I am authenticated as an admin via API
307
+ Given I generate a UUID and store as "runId"
308
+
309
+ # Create multiple related resources
310
+ When I POST "/projects" with JSON body:
311
+ """
312
+ { "name": "Project {runId}" }
313
+ """
314
+ Then the response status should be 201
315
+ And I store the value at "id" as "projectId"
316
+ Given I register cleanup DELETE "/projects/{projectId}"
317
+
318
+ When I POST "/projects/{projectId}/tasks" with JSON body:
319
+ """
320
+ { "title": "Task 1" }
321
+ """
322
+ Then the response status should be 201
323
+
324
+ When I POST "/projects/{projectId}/tasks" with JSON body:
325
+ """
326
+ { "title": "Task 2" }
327
+ """
328
+ Then the response status should be 201
329
+
330
+ # UI: Verify dashboard shows all data
331
+ Given I navigate to "/projects/{projectId}"
332
+ Then I should see text "Project {runId}"
333
+ And I should see text "Task 1"
334
+ And I should see text "Task 2"
335
+ ```
336
+
337
+ ## Error Testing Patterns
338
+
339
+ ### Test Error States
340
+
341
+ ```gherkin
342
+ @hybrid
343
+ Scenario: UI shows error when API resource deleted
344
+ # API: Create and immediately delete
345
+ Given I am authenticated as an admin via API
346
+ When I POST "/items" with JSON body:
347
+ """
348
+ { "name": "Temporary Item" }
349
+ """
350
+ Then the response status should be 201
351
+ And I store the value at "id" as "itemId"
352
+
353
+ When I DELETE "/items/{itemId}"
354
+ Then the response status should be 204
355
+
356
+ # UI: Try to access deleted resource
357
+ Given I navigate to "/items/{itemId}"
358
+ Then I should see text "Item not found"
359
+ ```
360
+
361
+ ## Complete Example: User Onboarding Flow
362
+
363
+ ```gherkin
364
+ @hybrid
365
+ Feature: User Onboarding
366
+ As a product owner
367
+ I want to test the complete onboarding flow
368
+ So that I can ensure new users have a smooth experience
369
+
370
+ Scenario: Complete onboarding journey
371
+ Given I generate a UUID and store as "testId"
372
+ Given I set variable "userEmail" to "onboard-{testId}@test.com"
373
+ Given I set variable "userName" to "New User {testId}"
374
+
375
+ # Step 1: Admin creates user invitation via API
376
+ Given I am authenticated as an admin via API
377
+ When I POST "/admin/invitations" with JSON body:
378
+ """
379
+ {
380
+ "email": "{userEmail}",
381
+ "role": "member"
382
+ }
383
+ """
384
+ Then the response status should be 201
385
+ And I store the value at "token" as "inviteToken"
386
+ And I store the value at "id" as "inviteId"
387
+ Given I register cleanup DELETE "/admin/invitations/{inviteId}"
388
+
389
+ # Step 2: User accepts invitation via UI
390
+ Given I navigate to "/invite/{inviteToken}"
391
+ Then I should see text "Welcome! Complete your profile"
392
+ When I fill the form:
393
+ | Field | Value |
394
+ | Full Name | {userName} |
395
+ | Password | SecurePass123! |
396
+ | Confirm Password| SecurePass123! |
397
+ And I click the button "Complete Setup"
398
+ Then I should see text "Welcome, {userName}"
399
+ And the URL should contain "/dashboard"
400
+
401
+ # Step 3: Verify user created via API
402
+ Given I am authenticated as an admin via API
403
+ When I GET "/admin/users?email={userEmail}"
404
+ Then the response status should be 200
405
+ And the value at "[0].name" should equal "{userName}"
406
+ And I store the value at "[0].id" as "userId"
407
+ Given I register cleanup DELETE "/admin/users/{userId}"
408
+
409
+ # Step 4: User completes profile via UI
410
+ Given I am authenticated in UI as "member" with id "{userId}"
411
+ Given I navigate to "/profile/edit"
412
+ When I fill in "Bio" with "I'm a new team member!"
413
+ And I click the button "Save"
414
+ Then I should see text "Profile updated"
415
+
416
+ # Step 5: Verify profile update via API
417
+ When I GET "/users/{userId}"
418
+ Then the response status should be 200
419
+ And the value at "bio" should equal "I'm a new team member!"
420
+ ```