@cloudbeat/atlas-cli 0.3.0 → 0.4.1
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/README.md +46 -19
- package/dist/api.js +20 -0
- package/dist/cli.js +34 -6
- package/dist/commands/analyze.js +118 -0
- package/dist/commands/capacity.js +104 -0
- package/dist/commands/docs.js +57 -0
- package/dist/commands/files.js +18 -4
- package/dist/commands/plan.js +100 -0
- package/dist/commands/record.js +11 -1
- package/dist/commands/results.js +13 -7
- package/dist/commands/schema.js +86 -0
- package/dist/commands/skills.js +111 -0
- package/dist/commands/tests.js +73 -0
- package/dist/docs/agent-setup.md +109 -0
- package/dist/docs/agent-tasks.md +169 -0
- package/dist/docs/ai-agents.md +90 -0
- package/dist/docs/auth.md +74 -0
- package/dist/docs/automation.md +150 -0
- package/dist/docs/ci.md +105 -0
- package/dist/docs/clusters.md +48 -0
- package/dist/docs/commands.md +155 -0
- package/dist/docs/files.md +86 -0
- package/dist/docs/generators.md +52 -0
- package/dist/docs/getting-started.md +85 -0
- package/dist/docs/index.json +110 -0
- package/dist/docs/projects.md +50 -0
- package/dist/docs/recorder.md +143 -0
- package/dist/docs/results.md +79 -0
- package/dist/docs/running.md +80 -0
- package/dist/docs/skills.md +88 -0
- package/dist/docs/test-plans.md +92 -0
- package/dist/docs/troubleshooting.md +79 -0
- package/dist/plan.js +250 -0
- package/dist/skills/AGENTS.md +70 -0
- package/dist/skills/atlas-analyze/SKILL.md +104 -0
- package/dist/skills/atlas-correlate/SKILL.md +89 -0
- package/dist/skills/atlas-load-test/SKILL.md +154 -0
- package/dist/skills/atlas-record/SKILL.md +167 -0
- package/dist/skills/atlas-run/SKILL.md +109 -0
- package/dist/skills/atlas-test-plan/SKILL.md +281 -0
- package/package.json +5 -3
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# Atlas load testing
|
|
2
|
+
|
|
3
|
+
This project uses [Atlas](https://atlas.cloudbeat.io) for load testing. The
|
|
4
|
+
`atlas` CLI drives it; `atlas-rec` records scenarios from a browser.
|
|
5
|
+
|
|
6
|
+
Every command takes `--json`, and failures print JSON on standard error with a
|
|
7
|
+
meaningful exit code (`0` pass, `1` a threshold was breached, `2` a usage or
|
|
8
|
+
authentication problem, `3` the run failed or the server was unreachable).
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
atlas schema --json # every command, argument and option
|
|
12
|
+
atlas docs # the documentation, offline
|
|
13
|
+
atlas docs troubleshooting # one topic
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## The flow
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
atlas whoami --json # who am I, which account
|
|
20
|
+
atlas projects --json # what can I see
|
|
21
|
+
atlas files list -p <project> --json # test plans and data files
|
|
22
|
+
atlas files download -p <project> <file> -o ./<file> # before editing anything
|
|
23
|
+
atlas plan check ./<file> -p <project> # will it run, and report?
|
|
24
|
+
atlas files upload -p <project> ./<file> # same name replaces, no version history
|
|
25
|
+
atlas capacity --json # machines, clusters, usage allowance
|
|
26
|
+
atlas run -p <project> --jmx <plan> --servers <n> --wait --gate "error_rate<1,p95<2000"
|
|
27
|
+
atlas results <testId> --json # aggregation report
|
|
28
|
+
atlas timeseries <testId> --json # the shape of the run
|
|
29
|
+
atlas errors <testId> --full # what failed, with request and response
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Recording a scenario, driven from the command line:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
atlas-rec start <url> -o flow.jmx # opens a browser, returns a session
|
|
36
|
+
atlas-rec snapshot # what is on the page
|
|
37
|
+
atlas-rec click --text "Sign in" # act on it
|
|
38
|
+
atlas-rec tx new "Checkout" # name the step that comes next
|
|
39
|
+
atlas-rec stop # write the plan
|
|
40
|
+
atlas-rec suggest flow.capture.json # values that change per session
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Rules that prevent real damage
|
|
44
|
+
|
|
45
|
+
- **A run costs machine time on someone's account.** Confirm before starting one
|
|
46
|
+
that is not a smoke test, and never stop a run you did not start.
|
|
47
|
+
- **Smoke-run first**: one machine, two users, a minute. Then check the results
|
|
48
|
+
actually contain data before scaling up.
|
|
49
|
+
- **Load multiplies by machines.** Each machine runs the whole plan, so total
|
|
50
|
+
users = users-in-the-plan x machines.
|
|
51
|
+
- **A test that measured nothing looks better than one that worked.** A missing
|
|
52
|
+
thread group with zero errors, a run that ended in seconds, or fast 200s that
|
|
53
|
+
return the login page all mean the test failed, not that the application is
|
|
54
|
+
fast.
|
|
55
|
+
- **Download before you edit or replace a stored file.** Uploading replaces it
|
|
56
|
+
and nothing keeps the old version.
|
|
57
|
+
- **Check a plan before uploading or running it.** A data file the project does
|
|
58
|
+
not have takes out a whole thread group with zero errors to explain it.
|
|
59
|
+
- **Think time is a setting, not a property.** Recorded plans pause between steps
|
|
60
|
+
using a `Settings - Sleeps` variables element; `-J` does not change it. Before
|
|
61
|
+
running a plan locally to debug it, check that element and disable it in your
|
|
62
|
+
working copy, or one user takes minutes instead of seconds. Put it back exactly
|
|
63
|
+
as it was before uploading.
|
|
64
|
+
- **A recording is a draft.** After stopping, report what was captured and ask
|
|
65
|
+
what to do next rather than uploading it. Offer to move the values every user
|
|
66
|
+
would otherwise repeat — credentials, search terms, ids — into a data file.
|
|
67
|
+
- **Report what happened**, including failed gates and uncertainty.
|
|
68
|
+
|
|
69
|
+
Full guidance is in the Atlas skills (`atlas skills install`) and at
|
|
70
|
+
https://atlas.cloudbeat.io/docs.
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: atlas-analyze
|
|
3
|
+
description: Read and explain the results of an Atlas load test - the aggregation report, the shape of the run over time, the errors behind a failure - and recognise the failure modes where a broken test looks like a healthy one. Use when someone asks how a test went, what the numbers mean, why a test failed, or why results look wrong or missing.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Reading results
|
|
7
|
+
|
|
8
|
+
```bash
|
|
9
|
+
atlas results <testId> # aggregation report, TOTAL first
|
|
10
|
+
atlas timeseries <testId> # users, response time, error rate over time
|
|
11
|
+
atlas errors <testId> # distinct errors, most common first
|
|
12
|
+
atlas errors <testId> --full # with the request and response behind each
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Add `--json` to any of them. `--label "<name>"` narrows timeseries and errors to
|
|
16
|
+
one transaction or request.
|
|
17
|
+
|
|
18
|
+
## Before interpreting anything, check the test was valid
|
|
19
|
+
|
|
20
|
+
A load test that measured nothing usually looks *better* than one that worked.
|
|
21
|
+
Rule these out first:
|
|
22
|
+
|
|
23
|
+
**Is every thread group present?** Compare the report against the plan. A missing
|
|
24
|
+
thread group with **zero errors** is the classic symptom of a data file the plan
|
|
25
|
+
could not open: every user in that group fails before sending a request, so there
|
|
26
|
+
is nothing to report as an error and the group simply vanishes while the others
|
|
27
|
+
look healthy. The cause is almost always a data file that was never uploaded to
|
|
28
|
+
the project. `atlas plan check -p <project> --jmx <plan>` names it in one line.
|
|
29
|
+
(A path from another machine, `C:\data\users.csv`, is not itself the problem —
|
|
30
|
+
Atlas resolves that to the uploaded file. Nothing uploaded under that name is.)
|
|
31
|
+
|
|
32
|
+
**Did it run for a plausible length of time?** A run that ends in a few seconds
|
|
33
|
+
with an empty dashboard did not run: the plan could not be started at all.
|
|
34
|
+
|
|
35
|
+
**Is the dashboard empty despite a full-length run?** Atlas attaches its
|
|
36
|
+
reporting to the plan when it deploys, and a file with an unusual structure can
|
|
37
|
+
defeat that — the test runs and reports nothing. `atlas plan check` says so
|
|
38
|
+
before you spend the time.
|
|
39
|
+
|
|
40
|
+
**Are the response codes real?** A wall of fast 200s that return the login page
|
|
41
|
+
is a failed test that passes every threshold. Check `atlas errors --full`, and be
|
|
42
|
+
suspicious of response times that are far better than the application's normal
|
|
43
|
+
behaviour.
|
|
44
|
+
|
|
45
|
+
**Did every machine report?** Users should add up to roughly what you asked for
|
|
46
|
+
(users-per-machine x machines). If the peak is a fraction of that, a machine was
|
|
47
|
+
not running.
|
|
48
|
+
|
|
49
|
+
## Then read the numbers
|
|
50
|
+
|
|
51
|
+
- **Percentiles, not averages.** p95 and p99 are what users feel; an average
|
|
52
|
+
hides the tail completely.
|
|
53
|
+
- **Error rate is errors over requests for the whole test**, not an average of
|
|
54
|
+
per-interval rates. The TOTAL row is authoritative.
|
|
55
|
+
- **Throughput is the result, not the goal.** If throughput flattens while users
|
|
56
|
+
keep climbing, you have found the saturation point — that is usually the
|
|
57
|
+
headline of the whole test.
|
|
58
|
+
- **Look at the shape.** `timeseries` shows where response time started to climb
|
|
59
|
+
and whether errors began at a particular user count. "It broke at about 300
|
|
60
|
+
users" is a more useful finding than any single number.
|
|
61
|
+
- **Per-transaction matters more than TOTAL.** One slow step in an otherwise fast
|
|
62
|
+
plan is invisible in the total and obvious per label.
|
|
63
|
+
|
|
64
|
+
## Explaining errors
|
|
65
|
+
|
|
66
|
+
`atlas errors --full` gives the actual request and response for each distinct
|
|
67
|
+
error. Sort out which kind you have:
|
|
68
|
+
|
|
69
|
+
- **4xx** — usually the test, not the application: a stale correlated value, an
|
|
70
|
+
expired session, data that does not exist in the target environment.
|
|
71
|
+
- **5xx** — usually the application, and worth reporting with the response body.
|
|
72
|
+
- **Timeouts / connection errors** — the application or something in front of it
|
|
73
|
+
giving up. Check when they started against the user count.
|
|
74
|
+
- **Assertion failures** — the request succeeded but returned the wrong thing,
|
|
75
|
+
such as a login page instead of the page you asked for.
|
|
76
|
+
|
|
77
|
+
A failure that appears only above a certain load is the interesting one. Report
|
|
78
|
+
the level it appeared at.
|
|
79
|
+
|
|
80
|
+
## Comparing runs
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
atlas tests -p <project> --json # recent runs with peak users, requests, error %
|
|
84
|
+
atlas results <previous> --json
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Compare like with like: the same plan, the same number of machines, the same
|
|
88
|
+
user count. A regression is only a regression if the shape of the test was the
|
|
89
|
+
same.
|
|
90
|
+
|
|
91
|
+
## Writing it up
|
|
92
|
+
|
|
93
|
+
A good report says, in this order:
|
|
94
|
+
|
|
95
|
+
1. Whether it passed, against the thresholds that were set.
|
|
96
|
+
2. What load was actually applied — users, ramp, duration, machines.
|
|
97
|
+
3. Response time under that load: p95 per key transaction, not just the total.
|
|
98
|
+
4. Where it started to degrade, from the time series.
|
|
99
|
+
5. What failed, with real examples from the error detail.
|
|
100
|
+
6. What to do next.
|
|
101
|
+
|
|
102
|
+
State the uncertainty plainly where it exists. "The test never reached the target
|
|
103
|
+
load because one machine dropped out" is a far more useful sentence than a
|
|
104
|
+
confident summary of numbers that do not mean what they appear to.
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: atlas-correlate
|
|
3
|
+
description: Handle dynamic values in a recorded load-test scenario - CSRF tokens, session ids, anything the server issues per session - by reviewing what the Atlas recorder detected and pinning the rest. Use when a recorded test plan fails on replay, returns login pages or 403s under load, or when someone asks about correlation or parameterisation.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Dynamic values
|
|
7
|
+
|
|
8
|
+
A recording captures literals. If the server issued a value for that one session
|
|
9
|
+
— a CSRF token, a session id, an order reference — replaying the literal fails,
|
|
10
|
+
usually as a 403, a redirect back to the login page, or an application error that
|
|
11
|
+
only appears when the test runs.
|
|
12
|
+
|
|
13
|
+
The recorder already handles this on evidence: a value a request sends is
|
|
14
|
+
correlated only if that exact value appeared in an **earlier response**. That rule
|
|
15
|
+
keeps it from rewriting things that merely look dynamic, but it also means it
|
|
16
|
+
cannot catch a value the browser computed on its own.
|
|
17
|
+
|
|
18
|
+
## Review what it found
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
atlas-rec suggest flow.capture.json
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Each suggestion shows the variable, the value, **where it came from** (the
|
|
25
|
+
response that defined it, and how it will be extracted) and **who sends it**.
|
|
26
|
+
Judge them:
|
|
27
|
+
|
|
28
|
+
- Source is the application, extraction looks stable, consumers make sense →
|
|
29
|
+
keep it.
|
|
30
|
+
- The value is a fixed application constant that merely appeared in a response
|
|
31
|
+
(a country code, a page size) → correlating it is harmless but pointless.
|
|
32
|
+
- A value that is sent but appears in **no** earlier response → the recorder
|
|
33
|
+
cannot correlate it, and it is exactly the kind that breaks. Find out what it
|
|
34
|
+
is: generated in the browser (a timestamp, a random id, a fingerprint), or
|
|
35
|
+
supposed to vary per user (a login, an account number).
|
|
36
|
+
|
|
37
|
+
## Pin the rest yourself
|
|
38
|
+
|
|
39
|
+
Write a rules file mapping parameter names to what should be sent instead:
|
|
40
|
+
|
|
41
|
+
```json
|
|
42
|
+
{
|
|
43
|
+
"authToken": "${authToken}",
|
|
44
|
+
"username": "${user}",
|
|
45
|
+
"requestId": "${__UUID()}"
|
|
46
|
+
}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
- `${user}` — a variable the plan reads from a data file. Per-user data belongs
|
|
50
|
+
in a CSV, not in the plan.
|
|
51
|
+
- `${__UUID()}`, `${__time()}` — JMeter functions, for values that just have to
|
|
52
|
+
be fresh and unique.
|
|
53
|
+
- A literal — when the value genuinely is a constant.
|
|
54
|
+
|
|
55
|
+
Timestamps are already replaced with `${__time()}` automatically; `--no-timestamps`
|
|
56
|
+
turns that off.
|
|
57
|
+
|
|
58
|
+
Then rebuild the plan from the same capture — no re-recording:
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
atlas-rec generate flow.capture.json -o flow.jmx --correlations rules.json
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Preset rules win over auto-correlation for the same parameter name, so a rule is
|
|
65
|
+
how you override a detection you disagree with. `--no-correlate` turns detection
|
|
66
|
+
off entirely and replays everything literally; that is a debugging tool, rarely
|
|
67
|
+
what you want.
|
|
68
|
+
|
|
69
|
+
## Prove it before scaling
|
|
70
|
+
|
|
71
|
+
Correlation is not verified until the plan runs against the application. Upload
|
|
72
|
+
it and smoke-run it (see `atlas-load-test`), then:
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
atlas errors <testId> --full
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Read the actual responses. The tells that correlation is still wrong:
|
|
79
|
+
|
|
80
|
+
- 403 / 419 / "invalid token" / "session expired" on requests that worked while
|
|
81
|
+
recording.
|
|
82
|
+
- A 200 that returns the **login page** — technically a success, functionally a
|
|
83
|
+
failed test. Response-time numbers from a run like that are meaningless, and
|
|
84
|
+
they look good, which is the dangerous part.
|
|
85
|
+
- The first iteration passes and later ones fail: something is being reused that
|
|
86
|
+
should be re-fetched per iteration.
|
|
87
|
+
|
|
88
|
+
Run it with two users and two iterations rather than one of each — a single pass
|
|
89
|
+
hides exactly this class of bug.
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: atlas-load-test
|
|
3
|
+
description: Run a load test with Atlas end to end - record or pick a test plan, upload test data, size the run, do a smoke test, run it, and report the results. Use when someone asks to load-test an application, create or run a performance test, check whether a site handles N users, or interpret a test that has already run.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Load testing with Atlas
|
|
7
|
+
|
|
8
|
+
This is the ordered flow. Work through it in order, stop at each **Ask** and wait
|
|
9
|
+
for an answer, and never skip the smoke run. Other skills cover the detail:
|
|
10
|
+
`atlas-record` (capturing a scenario), `atlas-test-plan` (downloading, editing
|
|
11
|
+
and uploading plans and data files), `atlas-correlate` (dynamic values),
|
|
12
|
+
`atlas-run` (sizing and gates), `atlas-analyze` (reading results).
|
|
13
|
+
|
|
14
|
+
A load test costs real machine time on someone's account. Treat starting one the
|
|
15
|
+
way you would treat a deploy: confirm before you spend.
|
|
16
|
+
|
|
17
|
+
## 0. Check the ground
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
atlas whoami --json # who, which account, which instance
|
|
21
|
+
atlas projects --json # what this credential can see
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
If `whoami` fails with exit code 2, the person needs to authenticate — tell them
|
|
25
|
+
to run `atlas login --token <token>` with a token from their Profile page. Do not
|
|
26
|
+
ask for their password.
|
|
27
|
+
|
|
28
|
+
If `atlas` itself is missing: `npm install -g @cloudbeat/atlas-cli`.
|
|
29
|
+
|
|
30
|
+
## 1. Pick the project
|
|
31
|
+
|
|
32
|
+
**Ask** which project, if it is not obvious from the request or already set
|
|
33
|
+
(`atlas config get`). Projects are the unit that owns test plans, data files and
|
|
34
|
+
run history. Do not create one — that is done in the web interface.
|
|
35
|
+
|
|
36
|
+
## 2. Get a test plan
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
atlas files list -p <project> --json
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Three cases, and **ask** which one applies if the request does not already say:
|
|
43
|
+
|
|
44
|
+
- **Use an existing plan as it is.** When several exist, ask which — `--jmx`
|
|
45
|
+
chooses, and the project's default may not be the one they mean.
|
|
46
|
+
- **Change an existing plan**, or add a new scenario to it. Follow
|
|
47
|
+
`atlas-test-plan`: download it first, because uploading replaces the stored
|
|
48
|
+
file and there is no version history.
|
|
49
|
+
- **Record a new one.** Follow `atlas-record`, then `atlas-test-plan` to check
|
|
50
|
+
and upload it.
|
|
51
|
+
|
|
52
|
+
## 3. Test data and a plan that will actually run
|
|
53
|
+
|
|
54
|
+
Plans usually read a CSV or TXT file per user (logins, search terms, IDs). Check
|
|
55
|
+
the plan against what the project holds, rather than assuming:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
atlas plan check -p <project> --jmx <plan>
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
That reports a data file the plan reads but the project does not have — the
|
|
62
|
+
failure that makes an entire thread group disappear from the results with **no
|
|
63
|
+
errors at all**. Upload whatever is missing, and anything that has gone stale:
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
atlas files upload -p <project> ./users.csv ./search-terms.txt
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Worth saying out loud, because it surprises people: data files are **divided
|
|
70
|
+
between machines**, not copied to each. Ten thousand rows across five machines is
|
|
71
|
+
two thousand rows each. If every machine must see every row, the run needs
|
|
72
|
+
`--no-split`. The rest of the file lifecycle is in `atlas-test-plan`.
|
|
73
|
+
|
|
74
|
+
## 4. Size the run
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
atlas capacity --json
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
This gives machines, clusters, how many are free, and how much usage allowance is
|
|
81
|
+
left. Read it **before** asking, so the question is grounded in real numbers.
|
|
82
|
+
|
|
83
|
+
**Ask** three things:
|
|
84
|
+
|
|
85
|
+
1. How many concurrent users should the test reach?
|
|
86
|
+
2. How long should it run, and over how long should users ramp up?
|
|
87
|
+
3. Fixed machines or a cluster? (Only if both are available.)
|
|
88
|
+
|
|
89
|
+
Then do the arithmetic and show your working: **each machine runs the whole plan
|
|
90
|
+
independently**, so total users = users-in-the-plan x machines. A plan with 100
|
|
91
|
+
users on 5 machines is 500 users. A plan recorded with the recorder exposes its
|
|
92
|
+
size as a run-time setting, so you can size it without editing the file:
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
atlas run -p <project> --jmx flow.jmx --servers 5 --args "-Jthreads=100 -Jrampup=300"
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
If the plan was not written that way, the thread counts are fixed inside the
|
|
99
|
+
file, and machines are the only dial you have. Say so rather than silently
|
|
100
|
+
running the wrong size.
|
|
101
|
+
|
|
102
|
+
## 5. Smoke run first
|
|
103
|
+
|
|
104
|
+
Never go straight to the full run. One machine, a couple of users, a minute or
|
|
105
|
+
two:
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
atlas run -p <project> --jmx <plan> --servers 1 --args "-Jthreads=2 -Jloops=2" --wait
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Then check it actually worked, which the exit code alone does not tell you:
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
atlas results <testId> --json
|
|
115
|
+
atlas errors <testId> --json
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
Look for: every thread group present, requests actually sent, errors understood.
|
|
119
|
+
A smoke run that finishes in seconds with no data is a broken plan, not a fast
|
|
120
|
+
application — `atlas-analyze` lists the usual causes. Fix that before scaling up.
|
|
121
|
+
|
|
122
|
+
**Ask** for confirmation before the full run, showing what you are about to
|
|
123
|
+
start: plan, machines, users, duration, and the smoke result.
|
|
124
|
+
|
|
125
|
+
## 6. The full run
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
atlas run -p <project> --jmx <plan> --servers <n> \
|
|
129
|
+
--args "-Jthreads=<per machine> -Jrampup=<seconds>" \
|
|
130
|
+
--wait --gate "error_rate<1,p95<2000"
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
`--wait` blocks until it finishes; `--gate` turns the result into a pass or fail
|
|
134
|
+
(exit code 1 when a threshold is breached). Tell the person the test id and the
|
|
135
|
+
dashboard link as soon as the run starts, so they can watch it themselves.
|
|
136
|
+
|
|
137
|
+
If they do not want to wait, drop `--wait` and poll `atlas status <testId>`.
|
|
138
|
+
|
|
139
|
+
## 7. Report
|
|
140
|
+
|
|
141
|
+
Follow `atlas-analyze`. A useful report answers: did it pass, what was the
|
|
142
|
+
response time under load, where did it start to degrade, what failed and why, and
|
|
143
|
+
what to do next. Percentiles matter more than averages, and the error detail
|
|
144
|
+
matters more than the error rate.
|
|
145
|
+
|
|
146
|
+
## Guardrails
|
|
147
|
+
|
|
148
|
+
- **Confirm before starting a full run.** Machines get powered on and billed.
|
|
149
|
+
- **Never stop someone else's run.** `atlas tests -p <project>` shows what is
|
|
150
|
+
running; if something is already going, ask before touching it.
|
|
151
|
+
- **Report what happened, not what should have happened.** If a thread group is
|
|
152
|
+
missing or a gate failed, say so plainly with the numbers.
|
|
153
|
+
- **`atlas stop` can come back unconfirmed.** If it reports machines it could not
|
|
154
|
+
reach, the test may still be running — say that rather than "stopped".
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: atlas-record
|
|
3
|
+
description: Record a browser scenario into a JMeter test plan with the Atlas recorder, including driving the browser yourself - open pages, click, fill forms, name transactions - and rebuilding the plan from a capture afterwards. Use when someone wants to create a load-test scenario from a real user flow, or asks you to click through an application and turn it into a test.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Recording a scenario
|
|
7
|
+
|
|
8
|
+
The recorder watches a real browser session and writes a JMeter plan from it.
|
|
9
|
+
A person can click through the flow themselves, or you can do the clicking. Both
|
|
10
|
+
are recorded the same way, and both can happen in the same session.
|
|
11
|
+
|
|
12
|
+
Requires `@cloudbeat/atlas-recorder` (`npm install -g @cloudbeat/atlas-recorder`).
|
|
13
|
+
It downloads its own browser on install.
|
|
14
|
+
|
|
15
|
+
## Which mode
|
|
16
|
+
|
|
17
|
+
**Ask** which the person wants, unless the request already says:
|
|
18
|
+
|
|
19
|
+
- **They click** — `atlas-rec record <url> -o flow.jmx`. Blocks until they press
|
|
20
|
+
Stop. Use this when the flow needs a human: a password only they know, a 2FA
|
|
21
|
+
prompt, a decision about what to test.
|
|
22
|
+
- **You click** — the commands below. Use this when the flow is mechanical and
|
|
23
|
+
they have told you what to do.
|
|
24
|
+
|
|
25
|
+
Either way the window is visible and they can watch, or take over.
|
|
26
|
+
|
|
27
|
+
## Driving it yourself
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
atlas-rec start https://shop.example.com -o flow.jmx -n "Checkout"
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Returns JSON with a `sessionId`. The browser is now open and recording. Later
|
|
34
|
+
commands find the session automatically when only one is running; pass
|
|
35
|
+
`--session <id>` when more than one is.
|
|
36
|
+
|
|
37
|
+
**Look before you act.** `snapshot` gives the page as an accessibility tree —
|
|
38
|
+
what is there and what can be clicked:
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
atlas-rec snapshot
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Then act. Prefer the target the snapshot actually showed you:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
atlas-rec click --role button --name "Find Flights"
|
|
48
|
+
atlas-rec click --text "Choose This Flight" # by visible text
|
|
49
|
+
atlas-rec fill "you@example.com" --selector "#email"
|
|
50
|
+
atlas-rec select "Rome" --selector "select[name=toPort]"
|
|
51
|
+
atlas-rec press Enter --selector "#search"
|
|
52
|
+
atlas-rec wait --selector "table" # or --url, or --ms
|
|
53
|
+
atlas-rec goto https://shop.example.com/cart
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Add `--nth <n>` when several things match. Snapshot again after anything that
|
|
57
|
+
changes the page — do not assume the click landed where you expected.
|
|
58
|
+
|
|
59
|
+
## Name the steps as you go
|
|
60
|
+
|
|
61
|
+
Each user action becomes a transaction in the plan, and transaction names are
|
|
62
|
+
what the results are reported against. Auto-generated names like "Rome" are
|
|
63
|
+
useless in a report. Name the step **before** you perform it:
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
atlas-rec tx new "Search flights"
|
|
67
|
+
atlas-rec click --role button --name "Find Flights"
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Check what has been captured at any point:
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
atlas-rec state # one line per transaction
|
|
74
|
+
atlas-rec state --full # every captured request
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Housekeeping while recording:
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
atlas-rec tx rename t3 "Add to cart"
|
|
81
|
+
atlas-rec req exclude r12 # keep a request out of the plan
|
|
82
|
+
atlas-rec req delete r12 # drop it from the recording entirely
|
|
83
|
+
atlas-rec pause / atlas-rec resume
|
|
84
|
+
atlas-rec scenario "Checkout"
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## Finishing
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
atlas-rec stop
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
This writes the plan and a capture file beside it, and returns both paths. The
|
|
94
|
+
plan is also written if the window is closed or the process is interrupted — a
|
|
95
|
+
recording is not lost by closing the browser.
|
|
96
|
+
|
|
97
|
+
## Signing in
|
|
98
|
+
|
|
99
|
+
Three options, in order of preference:
|
|
100
|
+
|
|
101
|
+
- `--cookies <file>` — exported cookies, so the recording starts already signed
|
|
102
|
+
in. Accepts Cookie-Editor, Netscape, a raw `Cookie:` header, or a storage-state
|
|
103
|
+
file.
|
|
104
|
+
- `--profile <file>` — saves the signed-in session on stop and reuses it next
|
|
105
|
+
time. Good for repeated recordings against the same app.
|
|
106
|
+
- Record the login itself — but then the plan contains one user's credentials and
|
|
107
|
+
every simulated user will send them. That is usually wrong: a real test needs a
|
|
108
|
+
data file of users. Say so.
|
|
109
|
+
|
|
110
|
+
Never ask for a password to type into the browser yourself. If the flow needs
|
|
111
|
+
credentials, hand the window back to the person for that step: they can type it
|
|
112
|
+
while the recording is live, and it is captured like anything else.
|
|
113
|
+
|
|
114
|
+
## After the recording
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
atlas-rec inspect flow.capture.json # transactions, hosts, response codes
|
|
118
|
+
atlas-rec suggest flow.capture.json # values that change per session
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
Read `inspect` before declaring success. Things to check:
|
|
122
|
+
|
|
123
|
+
- Every step you performed has a transaction, and the count of included requests
|
|
124
|
+
is not zero.
|
|
125
|
+
- No 4xx/5xx in `statusCodes` that you did not expect — a failed request recorded
|
|
126
|
+
as-is becomes a failing request in the test.
|
|
127
|
+
- Hosts are the application's, not a third party's. Analytics and CDN traffic is
|
|
128
|
+
filtered out already, but an embedded widget may not be.
|
|
129
|
+
|
|
130
|
+
## Then stop and agree the next step
|
|
131
|
+
|
|
132
|
+
A recording is a draft, not a test. When you have stopped, **report what you
|
|
133
|
+
captured and ask what to do with it** — do not upload it, and do not start
|
|
134
|
+
editing it, before the person has answered.
|
|
135
|
+
|
|
136
|
+
Say what is there: the scenario name, each transaction with its request count,
|
|
137
|
+
any unexpected status codes, and where the plan and capture files are. Then work
|
|
138
|
+
through the stages with them — flow, test data, dynamic values, checks, upload —
|
|
139
|
+
asking rather than deciding. Those stages are in `atlas-test-plan`, under
|
|
140
|
+
"Turning a recording into a test"; **read it before suggesting what comes next**,
|
|
141
|
+
because the question it insists on (which recorded values every simulated user
|
|
142
|
+
would otherwise repeat) is what separates a load test from a replay.
|
|
143
|
+
|
|
144
|
+
Rebuild the plan from the capture rather than re-recording whenever the change is
|
|
145
|
+
in how the plan is generated:
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
atlas-rec generate flow.capture.json -o flow.jmx --correlations rules.json
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
The same capture always produces the same plan, so this is safe to repeat.
|
|
152
|
+
|
|
153
|
+
## Things that will bite you
|
|
154
|
+
|
|
155
|
+
- **Never trigger a native dialog** (`alert`, `confirm`, a file picker). They
|
|
156
|
+
block the browser and the session stops responding. Avoid clicking anything
|
|
157
|
+
that might delete or confirm.
|
|
158
|
+
- **One click can record two requests** when a page redirects, so a step can hit
|
|
159
|
+
its destination twice per iteration. Check `inspect` and exclude the duplicate.
|
|
160
|
+
- **Everything before the first action is one transaction** — redirects, an SSO
|
|
161
|
+
hop, a failed load. Rename it to something meaningful.
|
|
162
|
+
- **The recording is one pass.** A cookie banner, an A/B variant or a retry that
|
|
163
|
+
did not happen while you clicked is not in the plan.
|
|
164
|
+
- **Recorded values are literal.** A search term, a product id, a date you picked
|
|
165
|
+
will be sent by every simulated user unless it is parameterised from a data
|
|
166
|
+
file. Flag this to the person; it is usually the difference between a realistic
|
|
167
|
+
test and a cached one.
|