camunda / camunda/api-test-generator
feat: JavaScript SDK emitter (`js-sdk`) — lower path-analyser scenarios onto @camunda8/orchestration-cluster-api
@johnOC03 is already working on this.
Since May 5, 2026.
- Dominant language
- TypeScript
- Stars
- 0
- Forks
- 3
- Avg merge
- 13h 41m
- Merged PRs (30d)
- 23
Description
Sub-issue of #8. Implement the js-sdk emitter strategy that lowers path-analyser EndpointScenarioCollection objects onto the @camunda8/orchestration-cluster-api TypeScript SDK, instead of emitting raw Playwright HTTP calls.
Prerequisites
-
Emitterinterface — landed (path-analyser/src/codegen/emitter.ts,registry.ts,orchestrator.ts,cli-args.ts) — see #5 / #8 - Reference implementation —
PlaywrightEmitteratpath-analyser/src/codegen/playwright/emitter.ts(488 lines). Treat this as the canonical lowering reference. - Per-step success-status correctness —
successStatusByOpflows throughRequestStep.expect.status(PR #52 / Bug A). SDK emitter gets this for free.
What to build
A new emitter registered under --target=js-sdk at:
path-analyser/src/codegen/js-sdk/
emitter.ts # JsSdkEmitter implements Emitter
sdk-mapping.ts # SdkMappingSource interface + OperationMapJsonSource impl
materialize-support.ts # vendors a self-contained JS project skeleton into <outDir>/
README.md # emitter id, env vars, supported scenario shapes
SDK surface
- Package:
@camunda8/orchestration-cluster-api - Client construction:
createCamundaClient()(ornew CamundaClient(config)— confirm against SDK README) - Method naming:
camelCase—operationIdalready matches directly - Ergonomic helpers:
deployResourcesFromFilesand others insrc/facade/operations.gen.ts - Hooks that produce them:
hooks/post/300-generate-class-methods.ts,hooks/post/400-generate-facade.ts - Existing helper map:
examples/operation-map.json
Mapping strategy (Option C from #8)
Use the SDK's existing examples/operation-map.json combined with spec/bundled/spec-metadata.json:
- Load
operation-map.jsonfrom the SDK repo (see Open Question 1 on checkout layout). - For each
operationId, look upoperation-map.json[operationId][0].region— this is the preferred method symbol (helper or raw). - If no entry exists, derive raw method from
operationIddirectly (already camelCase — no transform needed for JS). - Emit
client.<method>(args)instead ofrequest.post(url, body).
Implement SdkMappingSource as a shared interface in path-analyser/src/codegen/strategy/sdk-mapping.ts so Python and C# emitters can reuse it.
Test runner decision (to be pinned in first PR)
Decide between:
- Playwright Test — reuses
@playwright/testinfra already in use;requestfixture available for any raw-HTTP fallback steps - Vitest — better TypeScript DX, no browser overhead, fits a pure-SDK suite better
Recommendation: Vitest for the SDK suite (SDK calls are plain async functions, no HTTP fixture needed). Keep Playwright for the raw REST suite.
Emitter behaviour
For each scenario step, the emitter should:
- Map
RequestStep.operationId→ SDK method symbol viaSdkMappingSource. - Build typed call arguments from
RequestStep.body/RequestStep.pathParams/RequestStep.queryParams. - Emit
const result = await client.<method>(args). - Extract response fields into
ctxusing the sameextractIntopattern asPlaywrightEmitter, but from the typed SDK response rather thanresponse.json(). - Assert
resultshape withassert-json-body(reuse existing).
Auth / env vars
The generated suite must support both:
- Local unauthenticated (no env vars) —
createCamundaClient()with no credentials - OAuth2 / SaaS —
CAMUNDA_CLIENT_ID,CAMUNDA_CLIENT_SECRET,CAMUNDA_OAUTH_URL,CAMUNDA_CLUSTER_IDper SDK conventions
Investigate whether the SDK's built-in credential resolution already handles the env-var pattern used in support/env.ts today (API_BASE_URL, etc.) and document the mapping.
Open questions to resolve (from #8)
- SDK-repo checkout layout — how does the generator read
examples/operation-map.jsonat generation time? Options: sparse clone (likecamunda-schema-bundler), published npm sidecar, local path env var, or bundled intospec-metadata.jsonupstream. Pick and document. - Helper-signature mismatch policy — if a scenario's request shape doesn't match the helper's signature (e.g. multipart body that the helper doesn't accept), does the emitter silently fall back to the raw SDK method, or hard-fail to surface the gap?
request-validationparity — shouldrequest-validation/src/emit/qaEmitter.tsalso get a JS SDK variant, or is this emitter path-analyser-only for now?endpoint-map.jsonenrichment — shouldcamunda-schema-bundler2.x addoperationIdtoendpoint-map.jsonto drop one of the two current metadata reads? Coordinate with camunda-schema-bundler#21.
Layered test requirements (mirrors Bug A pattern from #8)
Per the AGENTS.md red/green/class-scoped rule and the regression-guard pattern in #8:
- Layer-1 fixture — one hand-built
EndpointScenarioCollection→ emitted JS SDK call assertion (intests/fixtures/planner/). - Layer-2 contract —
JsSdkEmitter.emit()purity test: same input produces byte-identical output (intests/codegen/js-sdk-emitter.test.ts). - Layer-3 invariant — class-scoped assertion in
tests/regression/bundled-spec-invariants.test.ts:- Every URL placeholder in the JS SDK suite is either seeded or extracted by an upstream step (mirrors Bug A invariant).
- The
operationIdkeyset of the emitter's call-shape table matchesexamples/operation-map.jsonunder a CI cross-check.
Definition of Done
-
JsSdkEmitterregistered under--target=js-sdkviaregisterEmitter(). -
npm run testsuite:generate -- --target=js-sdkproduces a runnable suite for every endpoint in the pinned bundled spec. -
materialize-supportanalogue produces a self-contained project (package.json,tsconfig.json,vitest.config.tsorplaywright.config.ts) that runsnpm install && npm testwithout referencing this generator. - Layer-3 invariant in
tests/regression/bundled-spec-invariants.test.tscovers placeholder binding and per-step success-status correctness for the JS SDK suite. -
operationIdkeyset of emitter's mapping matches SDK'sexamples/operation-map.jsonunder CI. -
path-analyser/src/codegen/js-sdk/README.mddocuments: emitter id, expected env vars, supported scenario shapes, how to point the strategy at a checked-out SDK repo. -
npm run lint,tsc --noEmit, andnpm testall pass.
Out of scope
- Live-cluster CI matrix (separate follow-up once emitter ships end-to-end).
- Resolving Bug B (#53) and Bug C (#54) — apply the same scope filters as the Bug A invariant.
- Python and C# emitters (tracked in their own sub-issues).
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.