@postman/postman-plugin 0.3.0 → 0.4.1-rc.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 (48) hide show
  1. package/README.md +46 -9
  2. package/dist/hosts/antigravity.js +47 -0
  3. package/dist/hosts/codex-hooks.js +68 -0
  4. package/dist/hosts/codex.js +87 -8
  5. package/dist/hosts/copilot.js +60 -0
  6. package/dist/hosts/index.js +3 -1
  7. package/dist/json-rpc.js +113 -0
  8. package/dist/system.js +40 -3
  9. package/mcp.pi.json +2 -2
  10. package/package.json +1 -1
  11. package/skills/ai-readiness/SKILL.md +40 -44
  12. package/skills/api-discovery/SKILL.md +64 -145
  13. package/skills/api-discovery/reference/orbit.md +17 -5
  14. package/skills/api-documentation/SKILL.md +41 -46
  15. package/skills/api-engineer/SKILL.md +78 -23
  16. package/skills/api-mocking/SKILL.md +117 -163
  17. package/skills/api-monitoring/SKILL.md +52 -129
  18. package/skills/api-simulation/SKILL.md +130 -178
  19. package/skills/api-simulation/reference/sim_yaml_schema.md +41 -103
  20. package/skills/api-testing/SKILL.md +48 -95
  21. package/skills/bootstrap/SKILL.md +123 -224
  22. package/skills/ci-integration/SKILL.md +53 -113
  23. package/skills/collection-schema-v3/SKILL.md +43 -204
  24. package/skills/collection-schema-v3/reference/http.md +150 -0
  25. package/skills/datasets/SKILL.md +89 -315
  26. package/skills/datasets/reference/spreadsheets.md +25 -0
  27. package/skills/flows/SKILL.md +57 -206
  28. package/skills/flows/reference/flow_cli_flags.md +3 -2
  29. package/skills/performance-testing/SKILL.md +46 -62
  30. package/skills/performance-testing/references/jmeter-import/README.md +82 -0
  31. package/skills/performance-testing/references/jmeter-import/import-report.md +52 -0
  32. package/skills/performance-testing/references/jmeter-import/mapping-table.md +95 -0
  33. package/skills/performance-testing/references/jmeter-import/postman-perf-capabilities.md +56 -0
  34. package/skills/performance-testing/references/jmeter-import/script-translation.md +97 -0
  35. package/skills/postman-mcp-server/SKILL.md +53 -59
  36. package/skills/postman-mcp-server/references/docs.md +0 -1
  37. package/skills/postman-mcp-server/references/learn.md +10 -9
  38. package/skills/postman-mcp-server/references/mock.md +0 -1
  39. package/skills/postman-mcp-server/references/search.md +0 -1
  40. package/skills/postman-mcp-server/references/security.md +0 -1
  41. package/skills/postman-mcp-server/references/setup.md +0 -1
  42. package/skills/postman-mcp-server/references/sync.md +0 -1
  43. package/skills/postman-mcp-server/references/test.md +0 -1
  44. package/skills/variables/SKILL.md +44 -87
  45. package/skills/webhook-testing/SKILL.md +103 -0
  46. package/skills/webhook-testing/reference/forwarding.md +10 -0
  47. package/skills/webhook-testing/reference/outbound_webhooks.md +25 -0
  48. package/skills/webhook-testing/reference/webhook_scripts.md +163 -0
@@ -1,212 +1,63 @@
1
1
  ---
2
2
  name: flows
3
- description: Runs, deploys, and debugs Postman Flows from the command line — executing a flow file locally, triggering a deployed flow over its webhook, deploying one so it becomes callable, and tracing a failed run to the block that broke. Use when the user names a flow and an action ("run the Checkout flow", "deploy this flow", "why did that flow run fail", "what flows do I have"). Covers `postman flows list`, `run`, `trigger`, `deploy`, `update`, `list-runs`, and `get-run`.
3
+ description: Use when running, deploying, or debugging an existing Postman Flow. Distinguishes local graph execution from a deployed webhook, reuses named input scenarios, and follows a run to the failing block rather than treating an HTTP response as whole-flow success. Use for requests such as "why did this flow fail".
4
4
  ---
5
5
 
6
6
  # Postman Flows
7
7
 
8
- ## Overview
9
-
10
- Listing flows, running them, deploying them so they become callable, and
11
- tracing a failed run to the block that caused it — all through
12
- `postman flows`.
13
-
14
- ## Core knowledge
15
-
16
- A flow is a graph of blocks, not a script. That single fact drives the rest of
17
- this skill: a flow has two independent execution paths, and its HTTP response
18
- describes one block rather than the whole graph, so debugging takes a
19
- different command than running.
20
-
21
- ### Local file vs deployed artifact
22
-
23
- `run` and `trigger` are not two ways to execute one flow. Postman Flows has
24
- two Native Git modes, and they are isolated from each other:
25
-
26
- - **Cloud View** (the default) syncs flows to Postman Cloud, which is what
27
- makes them shareable and **deployable** — so Cloud View is the only side
28
- `deploy`, `trigger`, `update`, `list-runs` and `get-run` ever address.
29
- - **Local View** stores flows as JSON in a local Git repo, updated as they are
30
- edited. Those flows **cannot be shared or deployed**, have no snapshots, and
31
- are isolated from the flows in Cloud View.
32
-
33
- | | `flows run <path>` | `flows trigger <flowId>` |
34
- | --- | --- | --- |
35
- | Executes | a flow JSON file on this machine | the cloud-deployed flow, via its webhook |
36
- | Returns | status, output, test results, exit code | Run ID + HTTP status + response body |
37
- | Observability | own stdout, `--output`, `--reporters` | `get-run`, per block |
38
- | Environment file | `-e/--environment` | not supported |
39
-
40
- `run` exits nonzero on failure, which is what lets a CI job gate on it.
41
- `trigger` goes through the real webhook URL, so it exercises the deployed path
42
- end-to-end — auth and trigger configuration included — and registers a cloud
43
- run that `get-run` can explain block by block.
44
-
45
- `postman init` scaffolds `postman/flows/`, and Postman's `flows run` examples
46
- use that path. Note what puts files there: the Git-connected Flows experience
47
- is **desktop-app only**, so `postman/flows/*.json` is written by the desktop
48
- app's Local View, not by the CLI — `workspace push`/`pull` carry no flows
49
- handling whatever else they sync. Don't tell a user to `workspace pull` to
50
- obtain a flow file.
51
-
52
- ### What deploying buys, and what it requires
53
-
54
- Deploying puts the flow in Postman's cloud and attaches an HTTP trigger, which
55
- is what makes it reachable by schedules, webhooks, third-party apps, and other
56
- APIs — the flow stops being something a human opens and becomes callable
57
- infrastructure.
58
-
59
- Three preconditions sit outside the CLI, so no flag or retry satisfies them:
60
- the flow must be in Cloud View, its Start block must be configured with an API
61
- request trigger, and its canvas must have a Response block. Check these before
62
- re-running a failed deploy with different arguments.
63
-
64
- `--path` is a suffix appended to a generated base URL, not a full URL.
65
-
66
- ### Inputs: `-i` versus a scenario
67
-
68
- A scenario is a named input set stored **in the flow definition**, generated
69
- when someone adds an input to the Start block. Because it travels with the
70
- flow, `-s "Staging"` is reproducible across invocations and across people,
71
- where `-i key=value` is per-invocation. Start-block inputs can be declared
72
- secret, which is what `--show-secrets` unmasks in dry-run output.
73
-
74
- Precedence: `-s` supplies payload, headers, and query; `--headers` and
75
- `--query` override it; `-i`/`-f` override its values.
76
-
77
- ### Identifiers
78
-
79
- `flows list` is the only way to turn a flow name into an id —
80
- `.postman/resources.yaml` maps collections to cloud ids but has no flows
81
- section, so there is nothing local to read. Both `list` and `list-runs`
82
- **require** `-w/--workspace`; take that id from `workspace.id` in
83
- `.postman/resources.yaml`, which `bootstrap` records.
84
-
85
- Run IDs have no single documented shape (`session-abc123` and `main/1a123ab1`
86
- both appear in Postman's own material). Use whatever `trigger` or `list-runs`
87
- printed, verbatim, and apply the same rule to flow ids.
88
-
89
- ### Plan and permission gating
90
-
91
- `flows run` is documented as Enterprise-only, and the cloud subcommands need
92
- `postman login`. `Access denied. Please check your permissions for the
93
- specified resource.` on *every* workspace is a credential-scope or plan
94
- signal, not a wrong-workspace signal — and never means the workspace has no
95
- flows.
96
-
97
- ## Deploying: propose, confirm, then verify
98
-
99
- Deploy is the one multi-phase workflow here, because it is mutating and
100
- because its result is only half-useful without the follow-up check.
101
-
102
- 1. **Resolve the id.** `flows list --workspace <id> --filter "Checkout"`. On
103
- multiple matches, show name + id + last-updated and let the user pick.
104
- 2. **Propose the path.** Derive it from the flow name — "Checkout" →
105
- `/checkout` — so the user is confirming a concrete value rather than
106
- answering an open question. Raise `--auth` here if the trigger will be
107
- reachable by anyone who learns the URL.
108
- 3. **Confirm, then run** `flows deploy <flowId> --path /checkout`.
109
- 4. **Report the Trigger URL and whether the trigger is enabled.** A deploy can
110
- land with the trigger off, which looks identical to a broken deploy at call
111
- time. If it is off, offer `flows update <flowId> --trigger on`.
112
-
113
- When the deploy existed only so the flow could be run, trigger it in the same
114
- turn and report the Run ID — deploy-then-trigger is one job.
115
-
116
- ## Running and triggering
117
-
118
- Show the command before running it, and map the request onto flags: inputs to
119
- `-i`, a payload file to `-f`, query to `-q`, headers to `--headers`, a named
120
- scenario to `-s`.
121
-
122
- ```bash
123
- postman flows run postman/flows/checkout.json -i amount=4200
124
- postman flows trigger <flowId> -i amount=4200
125
- ```
126
-
127
- `run` is documented as Enterprise-only, so check the plan before building a
128
- workflow on the local path. Where the flow is already in Cloud View, `trigger`
129
- covers the gap; a Local View flow has no such fallback, since it cannot be
130
- deployed.
131
-
132
- `-n/--dry-run` on `trigger` prints the resolved URL and payload without
133
- sending — worth reaching for when a flow writes to real systems, since a
134
- trigger is not a read-only probe. For CI, `--output json` and `--reporters
135
- html` persist results, and `--workspace` is required if the flow contains
136
- connector blocks (it fails at the block, not at startup).
137
-
138
- Report the Run ID on every trigger, including successes; it is the only handle
139
- on the run afterwards.
140
-
141
- Two failures are recoverable rather than terminal, and both recover through a
142
- confirmed mutation. A 404 hinting `To deploy it, run: postman flows deploy`
143
- means the flow exists but was never deployed — offer the deploy above, then
144
- re-trigger. A disabled-trigger error means it is deployed but not accepting
145
- calls — offer `flows update <flowId> --trigger on`, then trigger.
146
-
147
- ## Debugging a run
148
-
149
- A trigger's response body is the Response block's output. A flow can answer
150
- 200 with a failed block upstream, and a 500 says nothing about which block
151
- produced it — so read the run, not the response.
152
-
153
- ```bash
154
- postman flows list-runs --workspace <id> --flow <flowId> --range 3d
155
- postman flows get-run --run-id <runId> --logs
156
- ```
157
-
158
- `list-runs` recovers a Run ID nobody wrote down; its `--range` defaults to
159
- `1h`, so widen it before concluding a run is missing. Start `get-run` without
160
- `--logs` and add them when the summary does not explain the failure;
161
- `--filter` narrows to a block-id prefix.
162
-
163
- Report the failing block, the reason, and the run status:
164
-
165
- ```
166
- Run session-abc123 — failed
167
- Failing block: "HTTP Request (Get Orders)"
168
- Reason: downstream returned 504 after 10s timeout
169
- Status: error
170
- ```
171
-
172
- ## Critical Rules
173
-
174
- 1. **Resolve ids, never infer them.** A name is not an id, and no id format is
175
- documented well enough to validate against. Ambiguous name → present
176
- candidates and ask.
177
- 2. **`deploy` and `update` need explicit confirmation.** They change what the
178
- flow does for every caller: a deploy exposes a trigger path, `--trigger
179
- on|off` starts or stops accepting calls, and `--auth off` removes
180
- authentication from a live trigger.
181
- 3. **Report the failing block, not the log.** `--logs` output is input to your
182
- analysis; the user needs the block, the reason, and the status.
183
- 4. **Surface CLI errors verbatim** and read them literally. "Flow file not
184
- found", a required-option error, and "Access denied" have three different
185
- fixes, and only the last is about permissions.
186
- 5. **A missing or unauthenticated CLI is `bootstrap`'s job** — route there
187
- rather than improvising an install or a second login.
188
-
189
- ## Anti-patterns
190
-
191
- 1. **Don't substitute `run` for `trigger` when a flow isn't deployed.** A
192
- green local run says nothing about the deployed path a caller hits, and a
193
- Local View flow cannot be deployed at all.
194
- 2. **Don't hunt for a different workspace id when access is denied across
195
- every workspace you try.** A blanket denial points at the credential's
196
- scope or the plan, not at the id.
197
- 3. **Don't pass `-x/--suppress-exit-code` in CI.** It makes a failed flow
198
- report success to the pipeline, which removes the only thing gating it.
199
- 4. **Don't put reusable inputs on the command line.** A payload that matters
200
- more than once belongs in a Start-block scenario, where it travels with the
201
- flow.
202
-
203
- ## Reference
204
-
205
- - [Flows CLI flags](reference/flow_cli_flags.md) — full flag tables per
206
- subcommand, the BETA dataset-iteration flags, and the short-flag collisions
207
- between subcommands. Read before composing a command with flags not shown
208
- above.
209
- - `bootstrap` skill — CLI install, login, and the workspace id these commands
210
- require.
211
- - `api-discovery` skill — `postman search flows` finds a flow by text across
212
- Postman, a different dataset from `flows list`'s workspace enumeration.
8
+ A Flow saves an API workflow as a graph of blocks. Named inputs make runs
9
+ repeatable, deployment makes the workflow callable by other systems, and
10
+ block-level run evidence shows where it failed. These benefits come from
11
+ different execution paths; choosing the wrong path can produce a passing
12
+ result that says nothing about the caller's actual workflow.
13
+
14
+ 1. Choose the artifact the user means. `postman flows run <path>` executes a
15
+ local JSON file; `postman flows trigger <flow-id>` calls the deployed
16
+ webhook, including trigger auth and configuration. Local View and Cloud
17
+ View artifacts are isolated: local files cannot be assumed deployable,
18
+ and `workspace pull` does not download them. The desktop app's Git-connected
19
+ Local View produces those files. Check current local-run entitlement before
20
+ building CI around it; a deployed flow is not a substitute for a different
21
+ local artifact.
22
+ 2. Resolve hosted IDs through `flows list --workspace <id>`; there is no
23
+ local flow mapping in `.postman/resources.yaml`. Reuse its `workspace.id`
24
+ when applicable or use **api-discovery** for cross-workspace search.
25
+ Resolve ambiguous names before mutating a flow. Use returned flow/run IDs
26
+ verbatim; their spelling is not a reliable validation rule.
27
+ 3. Reuse a Start-block scenario when the same payload should travel with the
28
+ flow. `-s` supplies payload, headers, and query; explicit headers/query and
29
+ `-i`/`-f` override those values. One-off inputs belong on the invocation.
30
+ For deployed flows with side effects, `trigger --dry-run` lets you inspect
31
+ the resolved call first; keep secrets masked.
32
+ 4. Deploy when the workflow needs a callable URL. The hosted flow needs a
33
+ Start block configured for an API request trigger and a Response block;
34
+ changing CLI flags cannot repair missing canvas configuration. Resolve
35
+ the path suffix and intended authentication before deploying. Deploy/auth
36
+ changes affect other callers; a scoped user request authorizes that change,
37
+ while unrequested public exposure or auth removal needs consent.
38
+ 5. Inspect the deployed URL and whether its trigger is enabled. A deployed
39
+ but disabled flow is not ready to receive calls; `flows update <id>
40
+ --trigger on` enables it when intended. If deployment is part of a requested
41
+ run, continue through triggering and capture the Run ID. A request only to
42
+ deploy does not authorize executing unrelated downstream writes.
43
+ 6. Diagnose from run evidence. A trigger response is the Response block's
44
+ output: HTTP 200 can coexist with another failed block. Use
45
+ `flows get-run --run-id <id>` and add `--logs` or a block filter when the
46
+ summary does not explain it. `flows list-runs --workspace <id> --flow <id>`
47
+ recovers missing run IDs; widen its time range before concluding absence.
48
+ 7. In CI, preserve the local run's failure exit code and persist its result
49
+ and reports. Connector blocks need `--workspace` even for a local file;
50
+ otherwise failure occurs inside the graph. An access denial across several
51
+ workspaces points toward credentials or entitlement, not an empty flow list.
52
+ Use **bootstrap** for unresolved CLI/authentication setup.
53
+
54
+ Read [command options](reference/flow_cli_flags.md) for inputs, reporters,
55
+ dataset iteration, and flag collisions; check installed subcommand `-h` before
56
+ carrying an option between commands.
57
+
58
+ ## Verification
59
+
60
+ Report which artifact and path executed, its inputs/scenario without secrets,
61
+ and the actual result. For a trigger, retain the Run ID; for a failure, name
62
+ the failing block and cause. For a deployment, report URL, auth, and enabled
63
+ state separately from any execution result.
@@ -57,8 +57,9 @@ takes `on|off`.
57
57
  with `Invalid command parameters: trigger: At least one option is required:
58
58
  --trigger or --auth`.
59
59
 
60
- Both are mutating and confirmation-gated. `--auth off` strips authentication
61
- from a live trigger — never run it as a convenience.
60
+ Both change the live trigger for other callers. Apply an already authorized
61
+ change within its scope; obtain consent before an unrequested access change.
62
+ `--auth off` removes authentication, so it is not a remedy for a failed login.
62
63
 
63
64
  ## `flows run <path>`
64
65
 
@@ -1,71 +1,55 @@
1
1
  ---
2
2
  name: performance-testing
3
- description: Load-tests a collection with concurrent virtual users, a chosen load profile, and pass/fail thresholds on latency or error rate — run locally or on Postman's cloud runners. Use when the user asks to "load test this API," "run a performance test," "check how this holds up under load," or "benchmark this collection." Covers `postman performance run`. This generates real traffic against a real target — confirm the target and scale before running, the same way any action with effects outside this session gets confirmed.
3
+ description: Use when load-testing or benchmarking an API with concurrent virtual users and latency or error thresholds. Reuses a collection to probe a chosen failure mode and distinguishes target limits from load-generator limits. Use for requests such as "load test this API".
4
4
  ---
5
5
 
6
6
  # Performance Testing
7
7
 
8
- ## Overview
9
-
10
- `performance run <collectionId>` is not `collection run` with more
11
- iterations — it's a dedicated load-test mode: many virtual users hitting the
12
- collection concurrently for a set duration, shaped by a load profile, scored
13
- against thresholds you define, on infrastructure you choose. The collection
14
- under test is authored the normal way — see the `collection-schema-v3` skill
15
- if it needs edits before the load test is meaningful (e.g. an assertion
16
- that would fail every VU's request identically).
17
-
18
- ## Core knowledge
19
-
20
- - **Load profile is what you're actually testing.** `fixed` holds steady
21
- concurrency (does this hold up at N users, sustained); `ramp-up` increases
22
- gradually (where does it start to degrade); `spike` bursts suddenly (does
23
- a sudden surge break it); `peak` sustains near-maximum load (does it
24
- survive staying there). Pick based on the failure mode being probed, not
25
- by default.
26
- - **`--runner` chooses where load originates.** `local` runs from the
27
- current machine/CI runner — bounded by its own resources, fine for
28
- internal or low-scale targets. `postman-cloud` runs from Postman's
29
- infrastructure — needed for realistic external-scale load, or once local
30
- resources would cap the achievable VU count. `postman-cloud-static-ip`
31
- is the same, from a static-IP range — needed when the target allowlists
32
- by IP.
33
- - **`--pass-if "less_than(p95, 500)"` turns a load test into a gate.**
34
- Metrics: `avg`, `p90`, `p95`, `p99`, `error_rate`, `rps`. Checked after the
35
- run completes, not enforced live — a bad configuration still generates its
36
- full load before the gate fails.
37
- - **`--use-mock` points the test at a mock instead of a real backend** — for
38
- load-testing collection/script logic itself, or to baseline mock-only
39
- latency and isolate app/network slowness from what the mock adds.
40
- - **`--setup-collection`/`--teardown-collection`** (cloud runner only) run
41
- once before/after the whole test — for provisioning or cleanup, not
42
- per-iteration setup.
43
- - **`--dataset-id`/`--dataset-view-id`** drive iteration data from a Postman
44
- Dataset instead of a flat `--data-file`; `--dataset-distribution` controls
45
- whether rows are spread round-robin, fixed, or randomly across VUs.
46
-
47
- ## Critical Rules
48
-
49
- 1. **Running this against a real, non-mock backend generates real load with
50
- real consequences — confirm the target, VU count, and duration with the
51
- user before running,** the same way any action with effects outside this
52
- session gets confirmed. Default to a low `--vu-count` and short
53
- `--duration` for a first run against anything live, or point it at a mock
54
- (`--use-mock`) when the goal is testing the collection, not the backend.
55
- 2. **A `--pass-if` gate doesn't stop the load early.** The full VU count and
56
- duration run regardless of whether the threshold will ultimately pass —
57
- plan for that cost, don't assume a failing gate means less traffic was
58
- sent.
59
- 3. **Cloud runners come from Postman's IP ranges.** Before assuming a
60
- `postman-cloud` run will reach a target, check whether it's IP-allowlisted
61
- — use `postman-cloud-static-ip` if so, rather than discovering the
62
- mismatch as a wall of connection failures.
8
+ A collection supplies realistic request sequences; `postman performance run`
9
+ adds concurrency and a load profile. This makes performance claims repeatable,
10
+ but only for the workload, data, and network path actually exercised.
11
+ Collections run directly: converting with `postman-to-k6` is not required.
12
+
13
+ 1. Choose the failure mode before the profile: `fixed` tests sustained
14
+ concurrency, `ramp-up` explores degradation as load grows, `spike` tests
15
+ sudden surges, and `peak` tests staying near maximum load. Reuse the
16
+ collection's auth and assertions, and check that its operations and data
17
+ represent the workload rather than repeating one unusually cheap request.
18
+ 2. Establish the target, VU count, duration, and effects of write requests
19
+ before sending load. Existing user authorization for that scope is enough;
20
+ resolve missing limits before stressing a shared or production service.
21
+ Thresholds are evaluated after the run, so a failing gate will not stop
22
+ traffic early. A small initial run can expose wiring failures before a
23
+ larger authorized test.
24
+ 3. Choose the runner by reachability and capacity. `local` uses this machine
25
+ or CI runner; its CPU or network can become the bottleneck. `postman-cloud`
26
+ moves generation to Postman's infrastructure, while
27
+ `postman-cloud-static-ip` supports targets with IP allowlists. Verify
28
+ reachability before interpreting connection failures as service capacity.
29
+ 4. Set thresholds that represent the user's objective, such as
30
+ `--pass-if "less_than(p95, 500)"`. Supported metrics include `avg`, `p90`,
31
+ `p95`, `p99`, `error_rate`, and `rps`; latency alone can look good when
32
+ requests fail quickly. Use `postman performance run -h` for current syntax,
33
+ units, and runner-specific options.
34
+ 5. Isolate test data where concurrent writes would collide. **datasets**
35
+ supports controlled row distribution across VUs; setup/teardown collections
36
+ on hosted runners execute once around the test, not once per iteration.
37
+ `--use-mock` can baseline collection/script overhead, but its numbers
38
+ cannot establish the real backend's capacity.
39
+
40
+ ## Importing from JMeter
41
+
42
+ Have a JMeter `.jmx` instead of a collection? Import it by following
43
+ `references/jmeter-import/README.md`, then treat the result as the collection
44
+ above. Its mapping table carries the JMeter semantics that are easy to get
45
+ wrong, and the import report marks what mapped exactly, what was approximated,
46
+ and which JMeter features have no equivalent here — think-time timers,
47
+ concurrent thread groups, and non-HTTP (JDBC/FTP/LDAP/Java) samplers are
48
+ reported, never faked.
63
49
 
64
50
  ## Verification
65
51
 
66
- State the actual metrics the run produced (p95, error rate, rps — whatever
67
- the `--pass-if` checked, plus the ones it didn't) and whether the gate
68
- passed, not just that the run completed. State which runner actually
69
- executed it (`local`/`postman-cloud`/`postman-cloud-static-ip`) — that
70
- determines whether the numbers reflect the target's real-world reachability
71
- or only local-network conditions.
52
+ Report the workload, runner, achieved traffic, latency and error metrics,
53
+ and threshold verdict. Identify generator limits or target errors that prevent
54
+ attributing the result to API capacity. See **api-testing** for functional
55
+ assertions and **ci-integration** when the measured threshold becomes a gate.
@@ -0,0 +1,82 @@
1
+ # Importing a JMeter `.jmx` into Postman
2
+
3
+ > Reference for the `performance-testing` skill. Import the plan, review the report, then the result is an ordinary performance run.
4
+
5
+ Turn a JMeter test plan into three artifacts:
6
+
7
+ 1. **Postman Collection v2.1** — requests, flow, headers, auth, variables, extractors, assertions.
8
+ 2. **Performance config** — VU count, duration, load profile, data file, `--pass-if`, and the exact `postman performance run` command.
9
+ 3. **Import report** — what imported exactly, what was approximated, what needs manual work, what is unsupported.
10
+
11
+ There is no importer to run: you read the `.jmx` and build these yourself. The files next to this one are the algorithm:
12
+
13
+ - `mapping-table.md` — what each JMeter element becomes, and how faithfully.
14
+ - `postman-perf-capabilities.md` — the hard limits of the import target.
15
+ - `script-translation.md` — Groovy/BeanShell → JS, and the JS templates for extractors and assertions.
16
+ - `import-report.md` — the report's shape.
17
+
18
+ ## When NOT to guess
19
+
20
+ Postman performance runs do not support everything JMeter does (see `postman-perf-capabilities.md`). Never invent a Postman feature to cover a JMeter one. If something can't import, it goes in the report's "Needs manual work" or "Not supported" section — that is a correct outcome, not a failure.
21
+
22
+ ## Workflow
23
+
24
+ ### 1. Walk the plan
25
+
26
+ JMX has one structural rule: every element is followed by a sibling `<hashTree>` holding its children. Walk those pairs. A config element (Header Manager, Auth Manager, HTTP Defaults, extractor, assertion) applies to every sampler in its subtree; the same element inside a sampler's own hashTree applies only to that sampler. For a large plan, work one thread group or controller at a time.
27
+
28
+ ### 2. Apply the JMeter semantics
29
+
30
+ These are easy to get subtly wrong:
31
+
32
+ - **Implicit HTTP success** — JMeter fails a sample on HTTP ≥ 400 even with no assertion. Every request gets the default 200–399 `pm.test` from `script-translation.md`, **unless** it has a Response Assertion whose `test_field` is `response_code` or `response_message`, or any assertion with `assume_success=true` (Ignore Status). An assertion on the body (`response_data`) does not suppress it.
33
+ - **Port 0 / -1** → "use protocol default" → omit from the URL.
34
+ - **Full-URL path** — if `HTTPSampler.path` starts with `http://` or `https://`, use it verbatim and ignore domain/port.
35
+ - **HEAD / TRACE arguments** — JMeter doesn't send separate parameters as a query for these; drop them and note it.
36
+ - **Headers** — in-scope Header Managers merge; the nearer/last value per name wins, and the collapse is reported. Keep inherited headers even on a GET (JMeter still sends them).
37
+ - **Variables and functions** — `${var}` → `{{var}}`; `${__UUID}` → `{{$guid}}`, `${__time}` → `{{$timestamp}}`, `${__Random(..)}` → `{{$randomInt}}`, `${__RandomString(..)}` → `{{$randomAlphaNumeric}}`.
38
+ - **Extractors and assertions** — extractors become `pm.collectionVariables.set` in the test script, assertions become `pm.test`. Use the templates in `script-translation.md` so every import produces the same code.
39
+ - **Load** — VUs = `num_threads`; duration (minutes) = round(`ThreadGroup.duration` seconds ÷ 60), minimum 1; profile = `ramp-up` if `ramp_time` > 0 or it's a plugin/concurrency group, else `fixed`. Loop counts become duration (there is no iteration count). One `--pass-if` only: a Duration Assertion → `less_than(p95, <ms>)`, otherwise default to `less_than(error_rate, 5)`.
40
+ - **Timers, concurrent thread groups, non-HTTP samplers** → not supported. List them in the report; never fake them.
41
+
42
+ ### 3. Handle what needs judgment
43
+
44
+ - **JSR223/BeanShell pre/post-processors** — translate to a prerequest/test script with `script-translation.md`. Mark anything you're unsure of with a `// REVIEW` comment and list it under "Needs manual work".
45
+ - **JSR223/BeanShell samplers** (no HTTP) — decide with the user: delete it, fold its logic into an adjacent request's script, or replace it with a real request.
46
+ - **XPath / CSS extractors** — the sandbox has no XPath/CSS engine. Rewrite against the JSON body if the response is JSON, use `xml2js`/`cheerio` via `require(...)` (confirm availability), or drop it with a note.
47
+ - **Complex JSONPath** (wildcards, filters, recursion) — rewrite as explicit property access in the test script.
48
+
49
+ ### 4. Validate the collection
50
+
51
+ Confirm the collection is valid v2.1 JSON and that **every `event` script parses as JavaScript** (`node --check` each `exec`, or equivalent). A syntax error in a script is invisible in the file and only surfaces when the perf run executes that request, mid-load.
52
+
53
+ ### 5. Write the report
54
+
55
+ Fill in `import-report.md`'s sections and counts so the report matches the collection you're handing off.
56
+
57
+ ### 6. Hand off the perf config
58
+
59
+ The command needs a collection UID, so the collection must be in a workspace first. The `--pass-if` value is a suggestion unless the JMeter plan had a Duration Assertion, so surface the VU/duration/profile/pass-if choices for the user to adjust.
60
+
61
+ ### 7. (optional) Publish to a Postman workspace
62
+
63
+ Only on explicit user consent — and **never make the user paste a workspace ID**. Pick the destination like this:
64
+
65
+ - **If the current folder is already a connected workspace** (the usual headless case), use it — `postman workspace push` targets the workspace bound to this directory, no ID. Just tell the user which one.
66
+ - **If the user named a workspace** (by name), resolve it with `postman workspace list --json` and match.
67
+ - **Otherwise present a choice, don't demand an ID.** Run `postman workspace list --json`, show the **names**, and ask the user to pick one *or* create a new one:
68
+ - **pick existing** → connect it once with `postman workspace pull <id>` (ID taken from the list), then push.
69
+ - **create new** → the CLI has no `create`; make it via MCP `createWorkspace` (or the Postman app), then `pull` and push.
70
+ - **Get the imported collection into the bound workspace before pushing.** The import is a standalone v2.1 `*.postman_collection.json`; a pulled workspace is a git-native v3 tree. After `pull`, bring the file in with `postman collection migrate <file>.postman_collection.json` into the workspace's collections directory (check `postman collection migrate -h`), then `postman workspace push`. Pushing a folder that has no collection in its tree uploads nothing.
71
+ - **Push through the CLI, not MCP.** MCP `createCollection` drops each request's URL (requests land blank); use MCP only if the `postman` binary genuinely can't be installed, and repair URLs afterward.
72
+ - Interrogate `postman <cmd> -h` for exact flags — the help is authoritative, this file is not.
73
+
74
+ Smoke-test with `postman collection run` — the **same runtime that executes the perf test**, not a generic client — so the request is proven under the variable/auth resolution it will actually run under. Then wire the returned UID into the perf command.
75
+
76
+ ## Scope limits (hard facts, verified against the CLI/engine code)
77
+
78
+ - Performance runs execute **one collection repeated across VUs**. Multiple thread groups cannot run concurrently in a single run.
79
+ - Runs are **time-based**, not iteration-based. JMeter loop counts become a duration.
80
+ - `--pass-if` is a **single, non-repeatable** condition. Extra assertions stay as `pm.test` in scripts.
81
+ - **No think time.** JMeter timers are not reproduced; each one is reported.
82
+ - Only **HTTP(S)** samplers import. JDBC/FTP/LDAP/Java/TCP/Debug/Dummy samplers are reported as skipped.
@@ -0,0 +1,52 @@
1
+ # Import Report — <TEST PLAN NAME>
2
+
3
+ > Fill in every section from the import. Once the manual tasks are resolved, update the
4
+ > "Needs manual work" list and the summary counts to match the collection you hand off.
5
+
6
+ ## Summary
7
+
8
+ - Thread groups: <N>
9
+ - HTTP requests imported: <N>
10
+ - Folders: <N>
11
+ - Script-only samplers (stubs): <N>
12
+ - Collection variables: <N>
13
+ - Data files: <N>
14
+ - Items needing manual work: <N>
15
+
16
+ ## Imported exactly
17
+
18
+ - HTTP requests (method, URL, headers, query/body params)
19
+ - Response assertions → `pm.test` (status / body contains / equals / matches)
20
+ - Regex & Boundary extractors → `pm.collectionVariables.set`
21
+ - Simple JSONPath extractors (dot/index paths) → property access
22
+ - Basic/Digest auth, User Defined Variables → collection variables
23
+ - `${var}` → `{{var}}` interpolation
24
+
25
+ ## Approximated
26
+
27
+ - **Thread group load** → VU count + duration + one of 4 load profiles.
28
+ - **Loop counts / iterations** → duration in minutes.
29
+ - <element-specific warnings…>
30
+
31
+ ## Needs manual work
32
+
33
+ - **[kind]** `request`: <what and why>
34
+
35
+ ## Not supported by Postman performance runs (dropped)
36
+
37
+ - **Think time / timers** — no equivalent.
38
+ - **Multiple concurrent thread groups** — a run is one collection repeated across VUs.
39
+ - **Flow control** (If/While) — requests flattened; restore with `pm.execution.setNextRequest`/`skipRequest`.
40
+ - **Cookie/Cache/DNS managers** — cookies handled automatically per VU.
41
+ - **Non-HTTP samplers** (JDBC/FTP/LDAP/Java/TCP/Debug) — HTTP only.
42
+
43
+ ## Performance run
44
+
45
+ ```bash
46
+ postman performance run <COLLECTION_UID> \
47
+ --vu-count <N> --duration <MIN> --load-profile <fixed|ramp-up|spike|peak> \
48
+ [--data-file <file>] [--pass-if "<fn>(<metric>, <value>)"]
49
+ ```
50
+
51
+ Upload the collection to a workspace first to get its UID. `--pass-if` is a suggested
52
+ default unless the JMeter plan had a Duration Assertion.