Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 27 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,40 @@ Browse the **[automation-packages/README.md](automation-packages/README.md)** fo

---

## Plan samples

The **[plans](plans/)** directory is about **plans** — the implementation of an automation
scenario, whether that is a functional test case, a load test, an RPA routine or a synthetic
monitoring probe. A plan combines keywords with the controls that build up its execution
logic: loops, branches, retries, waits.

The two directories answer different questions, and most people need both:

- **[automation-packages](automation-packages/)** — *"what does a real project look like?"*
Complete, real-world blueprints for a given use case and stack: load testing with
Playwright/TypeScript, synthetic monitoring with Cypress, RPA with Selenium. Take one as
the starting point for your own project.
- **[plans](plans/)** — *"how do I express this logic in a plan?"* One plan concept per
sample, with keyword code deliberately reduced to 3-line stubs so the plan itself is the
subject. Look things up here when you are writing a plan.

| Section | Contents |
|---------|----------|
| [plans/rpa](plans/rpa/) | Seven RPA plan samples: loops and data sources, branching, resilience, sessions, scheduling, reuse |
| [plans/load-testing](plans/load-testing/) | Six load-testing plan samples: thread groups, scenarios and mixed load, test data, measurements, SLA gates |
| [plans/reference](plans/reference/) | Standalone YAML plans illustrating the syntax — the shape of a plan, and static values vs expressions |

Samples for functional testing and monitoring will follow the same structure.

---

## Other directories

These directories contain older, lower-level samples that predate Automation Packages. They remain useful as reference material for individual keywords or Step client usage.

| Directory | Contents |
|-----------|----------|
| [keywords](keywords/) | Standalone keyword examples by technology (Java, .NET, Cypress, TypeScript/Playwright, JMeter, k6, Oryon, gRPC, SoapUI, …) |
| [plans](plans/) | Example Step plan files (JSON and YAML) |
| [step-client](step-client/) | Sample projects using the Step Controller API (Java and REST) |
| [plugins](plugins/) | Example Step plugin |
| [maven-plugins](maven-plugins/) | Sample for the Step Maven upload plugin |
Expand Down
5 changes: 5 additions & 0 deletions automation-packages/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,11 @@ level: intermediate
|--------|-----------|----------|----------|-------|
| [rpa-selenium](rpa-selenium/) | selenium | java | keyword-driven | intermediate |

> The sample above is a complete RPA project. For focused examples of the **plan** itself —
> one concept at a time, with the keyword code stubbed out — see [plans/rpa](../plans/rpa/):
> seven samples covering loops and data sources, branching, resilience, sessions, scheduling
> and reuse.

### Reference

| Sample | Description | Level |
Expand Down
133 changes: 133 additions & 0 deletions plans/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
# Step plan samples

This directory is about one thing: **how to write a Step plan**.

A **plan** is the implementation of an automation scenario — a functional test case, a load
test, an RPA routine, a synthetic monitoring probe. It combines **keywords**, the building
blocks that do the work, with **controls** that build up the execution logic: loops,
branches, retries, waits.

Every sample here ships as a runnable automation package, so each plan can be validated and
executed rather than just read. Keyword code is deliberately reduced to 3-line stubs so the
plan itself is the subject.

### How this differs from `automation-packages/`

[automation-packages/](../automation-packages/) holds **complete real-world blueprints** —
a full project for a given use case and stack (load testing with Playwright/TypeScript,
synthetic monitoring with Cypress, RPA with Selenium), including its build, its keywords and
its plans. That is where you go to start a project.

This directory is the **plan-authoring reference**: one plan concept per sample, stripped of
everything else. That is where you go while writing a plan.

## Samples by use case

| Use case | Samples | Status |
|----------|---------|--------|
| [**RPA**](rpa/) | 7 samples — loops, branching, resilience, sessions, scheduling, reuse | available |
| [**Load testing**](load-testing/) | 6 samples — thread groups, scenarios, data sets, measurements, SLA gates | available |
| Functional testing | — | planned |
| Monitoring | — | planned |

## Reference

For what each control does and how to configure it, see the official
[controls documentation](https://step.dev/knowledgebase/userdocs/plans/controls/).

[reference/](reference/) holds small standalone YAML plans illustrating the syntax:

| File | Shows |
|------|-------|
| [reference/basic-plan-syntax.yml](reference/basic-plan-syntax.yml) | The shape of a plan: root artefact, `callKeyword` with inputs, capturing an output, `if`, `assert`, `check` |
| [reference/dynamic-values.yml](reference/dynamic-values.yml) | Static values vs `expression:`, where plan variables come from, dynamic keyword names and `routing` |
| [reference/performance-assert.yml](reference/performance-assert.yml) | A `threadGroup` with a `performanceAssert` — the load-testing shape, and the `after`-block rule |

## Plan formats

Step has three plan formats:

| Format | Written as | Used by these samples |
|--------|-----------|-----------------------|
| **YAML** | The tree of controls documented at [step.dev](https://step.dev/knowledgebase/userdocs/plans/controls/) | Yes — the whole `rpa/` and `load-testing/` sets |
| **Plain text** | A compact line-based syntax, one keyword call per line | No |
| **UI** | Built in the Step plan editor; [imported and exported](https://step.dev/knowledgebase/userdocs/import-export-entities/) as JSON | No — see [legacy-exports/](legacy-exports/) for what an export looks like |

**Automation packages support YAML and plain text.** Editing an automation package's plans in
the UI is planned but not currently supported.

### Where a YAML plan lives

Inside an automation package, a YAML plan can be declared either way:

```yaml
plans: # directly in the main descriptor
- name: "My plan"
root:
testCase:
children: []

fragments: # or pulled in from a fragment file
- "plans/my-plan.yml"
```

A **standalone YAML plan** — a file with a top-level `root:`, like the three in
[reference/](reference/) — is not a separate format. It is the same tree, and it can be
either incorporated into an automation package like any other plan, or created centrally in
the Step UI with **Add plan → Create from YAML**.

Plain-text plans are declared with `plansPlainText`, each entry naming a `file`, a `name` and
a `rootType`:

```yaml
plansPlainText:
- name: "Open the site"
file: "plans/open-site.plan"
rootType: TestCase
```

## Schema

All YAML here targets Automation Package schema **1.2.0**. Any Step instance serves its own
schema at:

```
<your-step-instance>/rest/automation-packages/schema
```

Point your IDE at it to get completion and validation while editing
`automation-package.yaml`.

## Frontmatter

Each sample README carries the same descriptor block used across this repository (see
[automation-packages/README.md](../automation-packages/README.md)), plus `focus: plans` to
mark it as plan-authoring material rather than a technology sample:

```yaml
---
use-case: rpa
focus: plans
framework: none
language: groovy
target-platform: web
approach: keyword-driven
level: beginner
---
```

## Running a sample

```bash
step ap execute -p <sample-dir> -u <your-step-url> --token <your-token> --projectName <your-project>
```

`--includePlans` runs a subset. It is comma-separated, so plan names containing a comma
cannot be selected individually — worth avoiding when naming plans.

`execute` runs the plans and nothing else. To register a package in a project — its plans,
keywords, **schedules** and parameters — deploy it:

```bash
step ap deploy -p <sample-dir> -u <your-step-url> --token <your-token> --projectName <your-project>
```
File renamed without changes.
23 changes: 23 additions & 0 deletions plans/legacy-exports/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Legacy plan exports

Two plans exported from the Step plan editor as JSON.

| File | Plan |
|------|------|
| `Demo_Google-search.json` | A sequence calling an Echo keyword and asserting on its output |
| `Demo_Data-driven.json` | A data-driven plan iterating over a data source |

JSON is the format Step uses to **import and export** plans. It is not meant for authoring —
these two files are kept only as a sample of the shape.

For how to produce and consume such files — exporting single or bulk entities, exporting a
plan recursively with the entities it references, and the import options — see
[Import/Export entities](https://step.dev/knowledgebase/userdocs/import-export-entities/) in
the Step documentation.

To write a plan, use YAML:

- [../reference/](../reference/) — the YAML syntax reference
- [../rpa/](../rpa/) — worked, runnable samples

See the [plans README](../README.md) for how the three plan formats relate.
68 changes: 68 additions & 0 deletions plans/load-testing/01-first-load-test/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
---
use-case: load-testing
focus: plans
framework: none
language: groovy
target-platform: api
approach: keyword-driven
level: beginner
---

# 01 — First load test

The baseline shape of a load-testing plan: a thread group repeats one transaction, from several
virtual users at once, and the plan states the SLA that transaction has to meet. Every other
sample in this set builds on this structure.

**The lesson is the commented [`automation-package.yaml`](automation-package.yaml)** — read that
for the reasoning at each node. This page orients you and collects the reference tables. The
keywords are 3-line Groovy stubs simulating a shop API, so the package runs on any Java agent —
no build, no browser, no system under test.

## What it covers

- `threadGroup` as the root of a load plan, with `users` and `iterations`
- choosing what one iteration contains — the unit your load numbers are denominated in
- `instrumentNode` for an end-to-end transaction measurement
- `performanceAssert` as the SLA gate, and the two rules about where it may go
- why a load test still needs a functional `assert`

## Where measurements come from

| Measurement | Named after | Created by | Can carry a `performanceAssert` |
|-------------|-------------|-----------|-------------------------------|
| Keyword call | the **keyword** | Step, automatically, for every call | yes |
| Instrumented node | the node's `nodeName` | `instrumentNode: true` | **no** — dashboards only |
| Custom | whatever the keyword chooses | the keyword itself — see [05](../05-measurements/) | yes |

## Two rules for `performanceAssert`

1. **It must live in an `after` or `afterThread` block.** Anywhere else the run ends in
`TECHNICAL_ERROR`: `PerformanceAssert can only be defined in an 'after' or 'after thread' block`.
`after` runs once when the thread group finishes (run-wide SLA); `afterThread` runs once per
virtual user.
2. **`measurementName` must name a keyword or custom measurement**, never an `instrumentNode` one —
that fails with `No measurement is matching the defined filters.`, the same message a misspelled
name gives. For an SLA on a multi-step transaction, emit a custom measurement — see
[05](../05-measurements/).

Set `continueOnError: true` on the `after` block, or it stops at the first breach and hides the
rest. Bound thresholds on both sides — an upper bound alone passes when the measurement is empty.

## Key files

| File | Purpose |
|------|---------|
| `automation-package.yaml` | The plan — heavily commented, this is what to read |
| `keywords/searchProducts.groovy` | Returns a product id |
| `keywords/addToCart.groovy` | Returns a cart id |
| `keywords/checkout.groovy` | Returns an order id and `CONFIRMED` |

## Running it

```bash
step ap execute -p . -u <your-step-url> --token <your-token> --projectName <your-project>
```

The report should show 6 passing transactions, 18 passing keyword calls and three passing
performance asserts.
Loading