bmad-method-test-architecture-enterprise 1.1.0 → 1.2.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,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/package.json",
3
3
  "name": "bmad-method-test-architecture-enterprise",
4
- "version": "1.1.0",
4
+ "version": "1.2.0",
5
5
  "description": "Master Test Architect for quality strategy, test automation, and release gates",
6
6
  "keywords": [
7
7
  "bmad",
package/release_notes.md CHANGED
@@ -1,15 +1,10 @@
1
- ## 🚀 What's New in v1.1.0
1
+ ## 🚀 What's New in v1.2.0
2
2
 
3
3
  ### ✨ New Features
4
- - feat: prereq prompts part2
5
-
6
- ### 🐛 Bug Fixes
7
- - fix: issues 22 23
4
+ - feat:enhance api-request with operation-based overload and update documentation
8
5
 
9
6
  ### 📦 Other Changes
10
- - Merge pull request #25 from bmad-code-org/feat/prereq-prompts-part2
11
- - addressed PR comments
12
- - Merge pull request #26 from bmad-code-org/fix/issue-22-23
7
+ - Merge pull request #28 from bmad-code-org/feat/knowledge-update-pw-utils-3-14-0
13
8
 
14
9
 
15
10
  ## 📦 Installation
@@ -19,4 +14,4 @@ npx bmad-method install
19
14
  # Select "Test Architect" from module menu
20
15
  ```
21
16
 
22
- **Full Changelog**: https://github.com/bmad-code-org/bmad-method-test-architecture-enterprise/compare/v1.0.1...v1.1.0
17
+ **Full Changelog**: https://github.com/bmad-code-org/bmad-method-test-architecture-enterprise/compare/v1.1.0...v1.2.0
@@ -371,6 +371,95 @@ test.describe('GraphQL API', () => {
371
371
  - Check `body.errors` for GraphQL errors (not status code)
372
372
  - Works for queries and mutations
373
373
 
374
+ ### Example 8: Operation-Based Overload (OpenAPI / Code Generators)
375
+
376
+ **Context**: When using a code generator (orval, openapi-generator, custom scripts) that produces typed operation definitions from an OpenAPI spec, pass the operation object directly to `apiRequest`. This eliminates manual `method`/`path` extraction and `typeof` assertions while preserving full type inference for request body, response, and query parameters. Available since v3.14.0.
377
+
378
+ **Implementation**:
379
+
380
+ ```typescript
381
+ // Generated operation definition — structural typing, no import from playwright-utils needed
382
+ // type OperationShape = { path: string; method: 'POST'|'GET'|'PUT'|'DELETE'|'PATCH'|'HEAD'; response: unknown; request: unknown; query?: unknown }
383
+
384
+ import { test, expect } from '@seontechnologies/playwright-utils/api-request/fixtures';
385
+
386
+ // --- Basic usage: operation replaces method + path ---
387
+ test('should upsert person via operation overload', async ({ apiRequest }) => {
388
+ const { status, body } = await apiRequest({
389
+ operation: upsertPersonv2({ customerId }),
390
+ headers: getHeaders(customerId),
391
+ body: personInput, // compile-time typed as Schemas.PersonInput
392
+ });
393
+
394
+ expect(status).toBe(200);
395
+ expect(body.id).toBeDefined(); // body typed as Schemas.Person
396
+ });
397
+
398
+ // --- Typed query parameters (replaces string concatenation) ---
399
+ test('should list people with typed query', async ({ apiRequest }) => {
400
+ const { body } = await apiRequest({
401
+ operation: getPeoplev2({ customerId }),
402
+ headers: getHeaders(customerId),
403
+ query: { page: 0, page_size: 5 }, // typed from operation's query definition
404
+ });
405
+
406
+ expect(body.items).toHaveLength(5);
407
+ });
408
+
409
+ // --- Params escape hatch (pre-formatted query strings) ---
410
+ test('should fetch billing history with raw params', async ({ apiRequest }) => {
411
+ const { body } = await apiRequest({
412
+ operation: getBillingHistoryv2({ customerId }),
413
+ headers: getHeaders(customerId),
414
+ params: {
415
+ 'filters[start_date]': getThisMonthTimestamp(),
416
+ 'filters[date_type]': 'MONTH',
417
+ },
418
+ });
419
+
420
+ expect(body.entries.length).toBeGreaterThan(0);
421
+ });
422
+
423
+ // --- Works with recurse (polling) ---
424
+ test('should poll until person is reviewed', async ({ apiRequest, recurse }) => {
425
+ await recurse(
426
+ async () =>
427
+ apiRequest({
428
+ operation: getPersonv2({ customerId, hash }),
429
+ headers: getHeaders(customerId),
430
+ }),
431
+ (res) => {
432
+ expect(res.status).toBe(200);
433
+ expect(res.body.status).toBe('REVIEWED');
434
+ },
435
+ { timeout: 30000, interval: 1000 },
436
+ );
437
+ });
438
+
439
+ // --- Schema validation chains work identically ---
440
+ test('should create movie with schema validation', async ({ apiRequest }) => {
441
+ const { body } = await apiRequest({
442
+ operation: createMovieOp,
443
+ headers: commonHeaders(authToken),
444
+ body: movie,
445
+ }).validateSchema(CreateMovieResponseSchema, {
446
+ shape: { status: 200, data: { name: movie.name } },
447
+ });
448
+
449
+ expect(body.data.id).toBeDefined();
450
+ });
451
+ ```
452
+
453
+ **Key Points**:
454
+
455
+ - Pass `operation` instead of `method` + `path` — mutually exclusive at compile time
456
+ - Response body, request body, and query types inferred from operation definition
457
+ - Uses structural typing (duck typing) — works with any code generator producing `{ path, method, response, request, query? }`
458
+ - `query` field auto-serializes to bracket notation (`filters[type]=pep`, `ids[0]=10`)
459
+ - `params` escape hatch for pre-formatted strings — wins over `query` on conflict
460
+ - Fully composable with `recurse`, `validateSchema`, and all existing features
461
+ - `response`/`request`/`query` on the operation are type-level only — runtime never reads their values
462
+
374
463
  ## Comparison with Vanilla Playwright
375
464
 
376
465
  | Vanilla Playwright | playwright-utils apiRequest |
@@ -393,6 +482,7 @@ test.describe('GraphQL API', () => {
393
482
  - ✅ Tests requiring retry logic
394
483
  - ✅ Background API calls in UI tests
395
484
  - ✅ Contract testing support
485
+ - ✅ Type-safe API testing with OpenAPI-generated operations (v3.14.0+)
396
486
 
397
487
  **Stick with vanilla Playwright for:**
398
488
 
@@ -440,3 +530,34 @@ const response: any = await apiRequest({ method: 'GET', path: '/users' });
440
530
  const { body } = await apiRequest<User[]>({ method: 'GET', path: '/users' });
441
531
  // body is typed as User[]
442
532
  ```
533
+
534
+ **❌ Mixing operation overload with explicit generics:**
535
+
536
+ ```typescript
537
+ // Don't pass a generic when using operation — types are inferred from the operation
538
+ const { body } = await apiRequest<MyType>({
539
+ operation: getPersonv2({ customerId }),
540
+ headers: getHeaders(customerId),
541
+ });
542
+ ```
543
+
544
+ **✅ Let the operation infer the types:**
545
+
546
+ ```typescript
547
+ const { body } = await apiRequest({
548
+ operation: getPersonv2({ customerId }),
549
+ headers: getHeaders(customerId),
550
+ });
551
+ // body type inferred from operation.response
552
+ ```
553
+
554
+ **❌ Mixing operation with method/path:**
555
+
556
+ ```typescript
557
+ // Compile error — operation and method/path are mutually exclusive
558
+ await apiRequest({
559
+ operation: getPersonv2({ customerId }),
560
+ method: 'GET', // Error: method?: never
561
+ path: '/api/person', // Error: path?: never
562
+ });
563
+ ```
@@ -197,6 +197,7 @@ test.describe('Orders API', () => {
197
197
  - `validateSchema` throws if response doesn't match
198
198
  - Built-in retry for transient failures
199
199
  - Type-safe `body` access
200
+ - **Note**: If your project uses code-generated operations from an OpenAPI spec, see [Example 8](#example-8-operation-based-api-testing-openapi--code-generators) for the preferred `operation`-based overload (v3.14.0+)
200
201
 
201
202
  ### Example 3: Microservice-to-Microservice Testing
202
203
 
@@ -713,6 +714,69 @@ test.describe('Authenticated API Tests', () => {
713
714
  - Test auth, expired tokens, and RBAC
714
715
  - Pure API testing without UI
715
716
 
717
+ ### Example 8: Operation-Based API Testing (OpenAPI / Code Generators)
718
+
719
+ **Context**: When your project uses code-generated operation definitions from an OpenAPI spec, leverage the operation-based overload of `apiRequest` (v3.14.0+) instead of manual `method`/`path` extraction. This eliminates `typeof` assertions and provides full type inference for request body, response, and query parameters.
720
+
721
+ **Implementation**:
722
+
723
+ ```typescript
724
+ // tests/api/operations.spec.ts
725
+ import { test, expect } from '@seontechnologies/playwright-utils/api-request/fixtures';
726
+
727
+ test.describe('API Tests with Generated Operations', () => {
728
+ test('should create entity with full type safety', async ({ apiRequest }) => {
729
+ // Operation object from code generator — contains path, method, and type info
730
+ const { status, body } = await apiRequest({
731
+ operation: createEntityOp({ workspaceId }),
732
+ headers: getHeaders(workspaceId),
733
+ body: entityInput, // Compile-time typed from operation.request
734
+ });
735
+
736
+ expect(status).toBe(201);
737
+ expect(body.id).toBeDefined(); // body typed from operation.response
738
+ });
739
+
740
+ test('should list with typed query parameters', async ({ apiRequest }) => {
741
+ // query field replaces manual string concatenation
742
+ const { body } = await apiRequest({
743
+ operation: listEntitiesOp({ workspaceId }),
744
+ headers: getHeaders(workspaceId),
745
+ query: { page: 0, page_size: 10, status: 'active' },
746
+ });
747
+
748
+ expect(body.items).toHaveLength(10);
749
+ expect(body.total).toBeGreaterThan(10);
750
+ });
751
+
752
+ test('should poll async operation until complete', async ({ apiRequest, recurse }) => {
753
+ const { body: job } = await apiRequest({
754
+ operation: startJobOp({ workspaceId }),
755
+ headers: getHeaders(workspaceId),
756
+ body: { type: 'export' },
757
+ });
758
+
759
+ await recurse(
760
+ async () =>
761
+ apiRequest({
762
+ operation: getJobOp({ workspaceId, jobId: job.id }),
763
+ headers: getHeaders(workspaceId),
764
+ }),
765
+ (res) => res.body.status === 'completed',
766
+ { timeout: 60000, interval: 2000 },
767
+ );
768
+ });
769
+ });
770
+ ```
771
+
772
+ **Key Points**:
773
+
774
+ - `operation` replaces `method` + `path` — mutually exclusive at compile time
775
+ - Types for body, response, and query all inferred from the operation definition
776
+ - Works with any code generator using structural typing (no imports from playwright-utils needed in generator)
777
+ - Composable with `recurse`, `validateSchema`, and all existing `apiRequest` features
778
+ - Preferred approach over `typeof operation.response` for generated operations
779
+
716
780
  ## API Test Configuration
717
781
 
718
782
  ### Playwright Config for API-Only Tests
@@ -38,17 +38,17 @@ npm install -D @seontechnologies/playwright-utils
38
38
 
39
39
  ### Core Testing Utilities
40
40
 
41
- | Utility | Purpose | Test Context |
42
- | -------------------------- | -------------------------------------------------- | ------------------ |
43
- | **api-request** | Typed HTTP client with schema validation and retry | **API/Backend** |
44
- | **recurse** | Polling for async operations, background jobs | **API/Backend** |
45
- | **auth-session** | Token persistence, multi-user, service-to-service | **API/Backend/UI** |
46
- | **log** | Playwright report-integrated logging | **API/Backend/UI** |
47
- | **file-utils** | CSV/XLSX/PDF/ZIP reading & validation | **API/Backend/UI** |
48
- | **burn-in** | Smart test selection with git diff | **CI/CD** |
49
- | **network-recorder** | HAR record/playback for offline testing | UI only |
50
- | **intercept-network-call** | Network spy/stub with auto JSON parsing | UI only |
51
- | **network-error-monitor** | Automatic HTTP 4xx/5xx detection | UI only |
41
+ | Utility | Purpose | Test Context |
42
+ | -------------------------- | ----------------------------------------------------------------------------- | ------------------ |
43
+ | **api-request** | Typed HTTP client with schema validation, retry, and operation-based overload | **API/Backend** |
44
+ | **recurse** | Polling for async operations, background jobs | **API/Backend** |
45
+ | **auth-session** | Token persistence, multi-user, service-to-service | **API/Backend/UI** |
46
+ | **log** | Playwright report-integrated logging | **API/Backend/UI** |
47
+ | **file-utils** | CSV/XLSX/PDF/ZIP reading & validation | **API/Backend/UI** |
48
+ | **burn-in** | Smart test selection with git diff | **CI/CD** |
49
+ | **network-recorder** | HAR record/playback for offline testing | UI only |
50
+ | **intercept-network-call** | Network spy/stub with auto JSON parsing | UI only |
51
+ | **network-error-monitor** | Automatic HTTP 4xx/5xx detection | UI only |
52
52
 
53
53
  **Note**: 6 of 9 utilities work without a browser. Only 3 are UI-specific (network-recorder, intercept-network-call, network-error-monitor).
54
54
 
@@ -21,7 +21,7 @@ test-healing-patterns,Test Healing Patterns,"Common failure patterns and automat
21
21
  selector-resilience,Selector Resilience,"Robust selector strategies and debugging techniques","selectors,locators,debugging,ui",knowledge/selector-resilience.md
22
22
  timing-debugging,Timing Debugging,"Race condition identification and deterministic wait fixes","timing,async,debugging",knowledge/timing-debugging.md
23
23
  overview,Playwright Utils Overview,"Installation, design principles, fixture patterns for API and UI testing","playwright-utils,fixtures,api,backend,ui",knowledge/overview.md
24
- api-request,API Request,"Typed HTTP client, schema validation, retry logic for API and service testing","api,backend,service-testing,api-testing,playwright-utils",knowledge/api-request.md
24
+ api-request,API Request,"Typed HTTP client, schema validation, retry logic, operation-based overload for API and service testing","api,backend,service-testing,api-testing,playwright-utils,openapi,codegen,operation",knowledge/api-request.md
25
25
  network-recorder,Network Recorder,"HAR record/playback, CRUD detection for offline UI testing","network,playwright-utils,ui,har",knowledge/network-recorder.md
26
26
  auth-session,Auth Session,"Token persistence, multi-user, API and browser authentication","auth,playwright-utils,api,backend,jwt,token",knowledge/auth-session.md
27
27
  intercept-network-call,Intercept Network Call,"Network spy/stub, JSON parsing for UI tests","network,playwright-utils,ui",knowledge/intercept-network-call.md