← Plugin catalog
Productivity

Testkube Skills

Testkube v1.0.0

Publisher description

From the marketplace listing

Six skills for working with Testkube from an AI coding agent: a general orientation skill that explains what Testkube is, indexes the official docs, and routes to the others; install or reuse the Testkube CLI; set up a local Testkube OSS agent; discover the tests in a cloned repository; author and validate TestWorkflow YAML; and run and diagnose TestWorkflow executions. Setup skills check for an existing install first and reuse it, installing missing pieces only after confirming each step with the user.

Language: English · Automatically detected from descriptions.

Files & skills

File archives

Plugin package54 files · 120 KBBrowse files →
Skill instructions
installing-testkube-cli10.9 KB

View saved version →

---
name: installing-testkube-cli
description: "Install, upgrade, or verify the Testkube CLI (the `testkube` / `tk` / `kubectl-testkube` command) on Linux, macOS, or Windows. Use when the CLI is missing (`testkube: command not found`), before running any Testkube skill that shells out to `testkube`, or when a specific CLI version is required. Checks for an existing installation first and reuses it when present, and installs only after confirming with the user — never reinstalls a working CLI."
---

# installing-testkube-cli

Ensure the Testkube CLI is available before other Testkube skills use it. The CLI ships as a single binary named
`kubectl-testkube` with two convenience symlinks, `testkube` and `tk` — installing any one gives you all three.

**Always check for an existing installation first and reuse it.** Only install when the CLI is absent, or when a
specific version is required and the installed one differs. Reinstalling a working CLI is wasteful and can clobber a
version the environment depends on.

## The Core Loop

1. **Check for an existing CLI** — this comes before any install step:

   **Linux/macOS (bash/zsh):**
   ```bash
    TK_CMD="$(command -v testkube 2>/dev/null || command -v tk 2>/dev/null || command -v kubectl-testkube 2>/dev/null)"
    if [ -n "$TK_CMD" ]; then echo "$TK_CMD"; else echo "Testkube CLI not found"; fi
   ```

   **Windows (PowerShell):**
   ```powershell
   $TK_CMD = (Get-Command testkube, tk, kubectl-testkube -ErrorAction SilentlyContinue | Select-Object -First 1).Source
   $TK_CMD
   ```

   If any path is printed, the CLI is already installed. Confirm it runs:

   **Linux/macOS (bash/zsh):**
   ```bash
   if [ -n "$TK_CMD" ]; then "$TK_CMD" version; else echo "Testkube CLI not found"; fi
   ```

   **Windows (PowerShell):**
   ```powershell
   if ($TK_CMD) { & $TK_CMD version } else { Write-Host "Testkube CLI not found" }
   ```
   If no specific version was requested, **stop here and reuse the existing binary**. If a specific version was
   requested, compare the client version from `testkube version` to the target — reuse when they match; install or
   upgrade only when they differ.
2. **Only if absent or wrong version, install — after confirming with the user** — first make sure the chosen method's
   prerequisites are on PATH (see Prerequisites), then describe the exact install command, wait for the user's
   go-ahead, and run it (see Install). Recommended on Linux/macOS:
   ```bash
   curl -sSLf https://get.testkube.io -o /tmp/testkube-install.sh && bash /tmp/testkube-install.sh
   ```
   Run it with **`bash`**, not `sh` — the script uses `set -eo pipefail`, which fails under `dash`
   (the default `/bin/sh` on Debian/Ubuntu) with `Illegal option -o pipefail`.
3. **Verify** — confirm the client version prints:

   **Linux/macOS (bash/zsh):**
   ```bash
   TK_CMD="$(command -v testkube || command -v tk || command -v kubectl-testkube)"
   if [ -n "$TK_CMD" ]; then "$TK_CMD" version; else echo "Testkube CLI not found"; fi
   ```

   **Windows (PowerShell):**
   ```powershell
   $TK_CMD = (Get-Command testkube, tk, kubectl-testkube -ErrorAction SilentlyContinue | Select-Object -First 1).Source
   if ($TK_CMD) { & $TK_CMD version } else { Write-Host "Testkube CLI not found" }
   ```
4. **Report** — state whether an existing CLI was reused or a new one installed, and the resulting version.

## Rules

1. **MUST check for an existing CLI before installing.** Run `command -v testkube` (or `tk` / `kubectl-testkube`)
   first. If it resolves, reuse it — do not download or reinstall.
2. **MUST confirm with the user before installing or upgrading.** Describe the exact install command (and version)
   and wait for the user's go-ahead before running it — never install unprompted.
3. **MUST NOT reinstall a working CLI.** Install only when the CLI is absent, or when a required version differs from
   the one reported by `testkube version`.
4. **MUST verify after installing.** `testkube version` must print a client version before reporting success.
5. **MUST NOT install the cluster agent here.** This skill installs only the client binary. Deploying the Testkube
   agent/control plane into a cluster is separate (`testkube init standalone-agent`, Helm). See
   https://docs.testkube.io/articles/install/overview.

## Prerequisites

The installed client binary has no runtime dependencies, but each install *method* needs a few tools on PATH. Check
them before installing; if any are missing, install them with the OS package manager first (confirm with the user, per
Rule 2).

| Method | Requires on PATH |
|--------|------------------|
| Install script (recommended) | `curl` and `jq` — the script exits early if either is missing |
| Manual download | `curl` or `wget`, plus `tar` |
| Ubuntu / Debian (APT) | `sudo`, `apt-get`, `gnupg`, `wget` |
| macOS (Homebrew) | `brew` |
| Windows (Chocolatey) | `choco` |

Quick check for the recommended script method:

```bash
command -v curl && command -v jq || echo "install curl and/or jq first (e.g. sudo apt-get install -y curl jq)"
```

## Install

Only reached when step 1 finds no existing CLI, or when a required version differs from the installed one.

| Platform | Command |
|----------|---------|
| Linux / macOS (script) | `curl -sSLf https://get.testkube.io -o /tmp/testkube-install.sh && bash /tmp/testkube-install.sh` |
| macOS (Homebrew) | `brew install testkube` |
| Ubuntu / Debian (APT) | see [Ubuntu / Debian](#ubuntu--debian-apt) below |
| Windows (Chocolatey) | `choco install testkube -y` (after adding the source) |
| Specific version | Use the export flow in [Install script (recommended)](#install-script-recommended): export `TESTKUBE_VERSION=<version>`, then run the installer |
| Beta channel | `curl -sSLf https://get.testkube.io \| bash -s -- beta` |

### Install script (recommended)

The script auto-detects OS (Linux/Darwin) and arch (x86_64/arm64/i386), downloads the matching release tarball
from GitHub, and installs into `/usr/local/bin` (using `sudo` only if that directory isn't writable). For Windows,
use the Chocolatey method below or install manually.

 ```bash
 curl -sSLf https://get.testkube.io -o /tmp/testkube-install.sh && bash /tmp/testkube-install.sh
 ```

Pin a version by exporting `TESTKUBE_VERSION` first (pick a release from
https://github.com/kubeshop/testkube/releases):

 ```bash
 export TESTKUBE_VERSION=<version>
 curl -sSLf https://get.testkube.io -o /tmp/testkube-install.sh && bash /tmp/testkube-install.sh
 ```

### No-sudo / non-interactive install

The script installs into `/usr/local/bin`, which usually needs `sudo`. In a non-interactive session
(CI, an agent shell, no TTY) `sudo` can't prompt for a password and the script fails with
`sudo: a terminal is required to read the password`. When you can't use `sudo` interactively, install
the binary into a writable directory that's already on PATH (e.g. `~/.local/bin`) — no root needed:

> **Release tags have NO `v` prefix.** The tag and the version in the filename are the bare number,
> e.g. `2.11.0` — the download path is `releases/download/2.11.0/testkube_2.11.0_...`, NOT
> `releases/download/v2.11.0/...`. A `v`-prefixed URL 404s. Set `VER` to the bare number (no `v`).

```bash
VER="${TESTKUBE_VERSION:-2.11.0}"   # bare version, NO 'v' prefix; releases at github.com/kubeshop/testkube/releases
TARBALL="testkube_${VER}_Linux_x86_64.tar.gz"
curl -sSLf "https://github.com/kubeshop/testkube/releases/download/${VER}/${TARBALL}" -o "/tmp/${TARBALL}"
tar -xzf "/tmp/${TARBALL}" -C /tmp kubectl-testkube
mkdir -p "$HOME/.local/bin"
install -m 0755 /tmp/kubectl-testkube "$HOME/.local/bin/kubectl-testkube"
ln -sf "$HOME/.local/bin/kubectl-testkube" "$HOME/.local/bin/testkube"
ln -sf "$HOME/.local/bin/kubectl-testkube" "$HOME/.local/bin/tk"
```

Confirm `~/.local/bin` is on PATH (`echo "$PATH" | tr ':' '\n' | grep -F "$HOME/.local/bin"`); if not,
pick another writable PATH dir. Swap `Linux_x86_64` for your OS/arch (`Darwin_arm64`, etc.).

### Homebrew

```bash
brew install testkube      # upgrade later with: brew upgrade testkube
```

### Ubuntu / Debian (APT)

```bash
sudo apt-get update && sudo apt-get install -y gnupg wget
sudo install -m 0755 -d /etc/apt/keyrings
wget -qO- https://repo.testkube.io/key.pub | sudo gpg --dearmor -o /etc/apt/keyrings/testkube.gpg
echo "deb [signed-by=/etc/apt/keyrings/testkube.gpg] https://repo.testkube.io/linux linux main" | sudo tee /etc/apt/sources.list.d/testkube.list
sudo apt-get update
sudo apt-get install -y testkube
```

### Windows (Chocolatey)

```powershell
choco source add --name=kubeshop_repo --source=https://chocolatey.kubeshop.io/chocolate
choco install testkube -y
```

### Manual

When you can't run the script (air-gapped, custom install dir, CI without curl-pipe):

1. Download the tarball for your OS/arch from https://github.com/kubeshop/testkube/releases — file name is
   `testkube_<version>_<OS>_<arch>.tar.gz` (e.g. `testkube_2.11.0_Linux_x86_64.tar.gz`). The tag and
   `<version>` are the bare number with **no `v` prefix** (`2.11.0`, not `v2.11.0`) — a `v`-prefixed URL 404s.
2. Extract `kubectl-testkube` and move it onto PATH:

```bash
tar -xzf testkube_<version>_<OS>_<arch>.tar.gz kubectl-testkube
sudo mv kubectl-testkube /usr/local/bin/kubectl-testkube
sudo ln -sf /usr/local/bin/kubectl-testkube /usr/local/bin/testkube
sudo ln -sf /usr/local/bin/kubectl-testkube /usr/local/bin/tk
```

## Upgrade / reinstall

Confirm with the user first (Rule 2) — describe the exact command and target version, then re-run the same install
command. The script and Homebrew both overwrite the existing binary with the chosen release. To downgrade, pin
`TESTKUBE_VERSION` (script) or use a manual download.

## Common Mistakes

- **Reinstalling when the CLI is already present** — always run the step-1 existence check first and reuse what's there.
- **`testkube: command not found` after install** — `/usr/local/bin` isn't on PATH, or the shell cached the old lookup.
  Run `hash -r` (bash/zsh) or open a new shell, then `which testkube`.
- **Script aborts immediately** — missing `curl` or `jq`. Install them via your package manager first.
- **`Illegal option -o pipefail`** — you ran the script with `sh`/`dash`. It requires `bash` (`set -eo pipefail`).
  Re-run with `bash /tmp/testkube-install.sh`.
- **`sudo: a terminal is required to read the password`** — the script needs `sudo` for `/usr/local/bin` but there's
  no interactive TTY (CI/agent shell). Use the [No-sudo / non-interactive install](#no-sudo--non-interactive-install)
  into a writable PATH dir like `~/.local/bin`.
- **`curl: (22) ... 404` on the release download** — you added a `v` to the version. Testkube release tags have **no
  `v` prefix**: the URL is `releases/download/2.11.0/testkube_2.11.0_...`, not `.../v2.11.0/...`. Use the bare number.
- **Chocolatey can't find the package** — add the source first:
  `choco source add --name=kubeshop_repo --source=https://chocolatey.kubeshop.io/chocolate`.
- **Confusing CLI with cluster install** — this skill installs only the client binary; the cluster agent is separate.

Referenced files: 1

installing-testkube-oss-agent11.3 KB

View saved version →

---
name: installing-testkube-oss-agent
description: "Set up a local Testkube OSS standalone agent — deploy the open-source Testkube agent into a Kubernetes cluster for local testing (k3d by default when a fresh local cluster is needed; minikube, kind, k3d, or remote all work). Use when you need a local OSS Testkube environment and none is running yet. Checks for an existing Testkube agent in the current cluster of ANY type first and reuses it; installs missing pieces only after confirming each step with the user."
---

# installing-testkube-oss-agent

Set up a self-contained local Testkube OSS install: a Kubernetes cluster with the **Testkube standalone agent**
deployed into its `testkube` namespace. Standalone (OSS) mode has **no web dashboard** — everything is driven through
the CLI. **k3d** (k3s in Docker) is the default when you need a *fresh* local cluster, but any cluster works.

**Always check for an existing Testkube agent first — in the current cluster of any type (minikube, kind, k3d,
remote) — and reuse it.** Only create a cluster or deploy the agent when none is running, and **confirm each mutating
step with the user before running it** — these commands install binaries, create clusters, and deploy into them.

## The Core Loop

Run these in order. Reuse whatever already exists; confirm every mutating step with the user before running it.

1. **Check prerequisites** — install any missing ones with the OS package manager first (confirm with the user, per
   Rule 2).

   Always required:
   ```bash
    TK_CMD="$(command -v testkube 2>/dev/null || command -v tk 2>/dev/null || command -v kubectl-testkube 2>/dev/null)"  # Testkube CLI — else use installing-testkube-cli
    if [ -n "$TK_CMD" ]; then echo "$TK_CMD"; else echo "Testkube CLI not found; use installing-testkube-cli"; fi
   command -v kubectl                                  # kubectl — talk to the cluster
   command -v helm                                     # helm — testkube init standalone-agent invokes Helm internally
   command -v curl                                     # curl — k3d install script
   ```

   Only when you need a fresh local k3d cluster (steps 3–4):
   ```bash
   docker info >/dev/null 2>&1 && echo docker-ok       # Docker daemon must be running
   ```

   Required always: the **Testkube CLI**, **`kubectl`**, **`helm`**, and **`curl`**. **Docker** is required only when
   creating a k3d cluster. `k3d` itself is installed in step 3 if it's missing and you need a fresh local cluster.
2. **Check for an existing Testkube agent — in the current cluster of ANY type — and reuse it.** The agent may
   already be running in minikube, kind, k3d, or a remote cluster; detection is cluster-agnostic. Before creating
   anything:
   ```bash
   TK_CMD="$(command -v testkube || command -v tk || command -v kubectl-testkube)"
   kubectl config current-context      # which cluster are we pointed at?
    if kubectl get namespace testkube >/dev/null 2>&1; then kubectl get pods -n testkube; else echo "testkube namespace not found"; fi   # is a Testkube agent Running here?
   if [ -n "$TK_CMD" ]; then "$TK_CMD" version; else echo "Testkube CLI not found; use installing-testkube-cli"; fi  # does it print a SERVER version too?
   ```
   If the `testkube` namespace has Running agent pods and `testkube version` shows a server version, it is already
   installed — **stop here and use it**, whatever the cluster type. If the agent runs in a different cluster, list
   contexts and switch to it rather than creating a new one:
   ```bash
   kubectl config get-contexts
   kubectl config use-context <context-with-the-agent>   # e.g. minikube, kind-..., k3d-testkube
   ```
   Steps 3–4 create a *fresh local* cluster with k3d — **skip both entirely if you already have a usable cluster**
   (minikube, kind, k3d, remote) and just deploy the agent into it (step 5).
3. **Install k3d (if missing)** — confirm with the user, then:
   ```bash
   command -v bash
   curl -fsSL https://raw.githubusercontent.com/k3d-io/k3d/v5.7.4/install.sh -o /tmp/k3d-install.sh
   TAG=v5.7.4 bash /tmp/k3d-install.sh
   ```
   Skip if `command -v k3d` already resolves, or if you're reusing minikube/kind/another cluster (e.g. `brew install k3d`).
4. **Create the cluster (if missing)** — confirm, then:
   ```bash
   k3d cluster create testkube
   ```
   Skip if you already have a running cluster to use — reuse it (e.g. `minikube start` / an existing `k3d cluster
   list` entry). k3d merges its context into your kubeconfig and switches to it.
5. **Deploy the agent (if missing)** — confirm, then:
   ```bash
   TK_CMD="$(command -v testkube || command -v tk || command -v kubectl-testkube)"
   if [ -n "$TK_CMD" ]; then "$TK_CMD" init standalone-agent --no-confirm; else echo "Testkube CLI not found; use installing-testkube-cli"; fi
   ```
   (`testkube init oss` is an alias.) Skip if the `testkube` namespace already has the agent Running. **Get the
   user's approval before running this (Rule 2).** Note: `testkube init standalone-agent` prints
   `Do you want to continue? [Y/n]` and reads the answer from the terminal (`/dev/tty`) — piping `yes` or any answer
   to stdin does **not** reach it, so in a non-interactive / agent / CI shell the command hangs forever. Once the user
   has approved out of band, run it non-interactively: prefer the **Helm alternative below** (inherently
   non-interactive), or pass `--no-confirm` (the human approval Rule 2 requires has already happened — see Rule 6).
   Only when a real human is at the terminal should you leave the prompt for them to answer.
6. **Verify** — wait until the API server pods are `Running` (and MinIO if installed — it is by default), then confirm
   CLI ↔ server:
   ```bash
   TK_CMD="$(command -v testkube || command -v tk || command -v kubectl-testkube)"
   kubectl get all -n testkube
   if [ -n "$TK_CMD" ]; then "$TK_CMD" version; else echo "Testkube CLI not found; use installing-testkube-cli"; fi  # must print client AND server versions
   ```
   The `testkube-api-server` pod often shows several restarts in the first ~2 minutes while it waits for MongoDB
   or PostgreSQL, MinIO, and NATS to become ready — this is normal startup behavior, not a failure. Wait for `Ready 1/1`, 
   not for zero restarts.
7. **Report** — state what was reused vs newly installed, and the cluster/context name.

## Rules

1. **MUST check for an existing agent in the current cluster (any type) before creating anything.** If a Testkube
   agent is running in the active kube context — minikube, kind, k3d, or remote — and `testkube version` shows a
   server version, reuse it; do not spin up a new cluster or redeploy.
2. **MUST confirm every mutating step with the user before running it.** Installing k3d, creating a cluster, deploying
   the agent, and teardown all change the local system — describe the exact command and wait for the user's go-ahead
   before each one.
3. **MUST reuse existing pieces individually.** If you already have a running cluster (minikube/kind/k3d/remote),
   deploy into it instead of creating one. Skip k3d install if `k3d` is on PATH; skip cluster create if a usable
   cluster exists; skip `testkube init standalone-agent` if the agent is already Running.
4. **MUST verify before reporting success.** `testkube version` must print both a client and a server version.
5. **MUST NOT tear down without explicit confirmation.** `testkube purge` and cluster delete commands destroy the
   local environment — never run them unprompted.
6. **The user must approve the init step (Rule 2) — but that approval need not be typed into the CLI's own prompt.**
   `testkube init standalone-agent` reads its `[Y/n]` prompt from the terminal, so in a non-interactive / agent / CI
   shell it hangs (piping `yes` does not help). Never skip the user's approval. Once they have approved, run
   non-interactively via the Helm alternative or with `--no-confirm` — the human approval is what matters, not who
   types `Y`. Leave the prompt for the user to answer only when a real human is interacting with the terminal.
7. **REQUIRED SUB-SKILL:** the Testkube CLI must be present — use installing-testkube-cli. Also needs `kubectl`,
   `helm`, and `curl` on PATH. Docker (`docker info`) is required only when creating a k3d cluster. `k3d` is installed
   by step 3 when needed.

## Helm alternative (Step 5)

Equivalent to `testkube init standalone-agent`, useful for pinning chart values / CI:

```bash
helm repo add kubeshop https://kubeshop.github.io/helm-charts
helm repo update
helm upgrade --install testkube kubeshop/testkube \
  --create-namespace \
  --namespace testkube \
  --set installCRDs=true
```

## Teardown

Destructive — **confirm with the user first** (Rule 5).

1. **Remove the agent** (any cluster type):
   ```bash
    TK_CMD="$(command -v testkube || command -v tk || command -v kubectl-testkube)"
    if [ -n "$TK_CMD" ]; then "$TK_CMD" purge; else echo "Testkube CLI not found; use installing-testkube-cli"; fi  # or: helm delete --namespace testkube testkube
   ```

2. **Delete the cluster only if this skill created it** — match the cluster type from setup:
   - **k3d** (created in step 4): `k3d cluster delete testkube`
   - **minikube**: `minikube delete` (or the profile-specific delete command)
   - **kind**: `kind delete cluster --name <cluster-name>`
   - **Remote / shared cluster**: do **not** delete the cluster — only purge the agent unless the user explicitly asks
     to remove the whole cluster.

## Common Mistakes

- **Creating a new cluster when an agent already runs elsewhere** — the step-2 check is cluster-agnostic; if minikube,
  kind, or a remote cluster already has the agent, switch context and reuse it instead of spinning up k3d. List
  clusters with `kubectl config get-contexts` (and `k3d cluster list` for k3d specifically).
- **`docker info` fails / k3d cluster create hangs** — Docker isn't running. k3d needs a live Docker daemon; start Docker
  Desktop or `systemctl start docker` first. Docker is not required when reusing an existing remote/minikube/kind cluster.
- **`testkube: command not found`** — the CLI isn't installed; see installing-testkube-cli.
- **Using bare `testkube init`** — current CLI requires a profile; use `testkube init standalone-agent` (alias: `oss`)
  for OSS standalone mode.
- **Aborted `init` leaves orphaned processes / a stuck Helm release** — killing the wrapper of an `init` attempt
  (TaskStop, Ctrl-C, timeout) can leave `testkube init` child processes running that still hold a Helm lock, so the
  next attempt fails with `another operation (install/upgrade/rollback) is in progress`. Before retrying:
  `pkill -f 'testkube init'`, then check `helm list -n testkube` for a stuck release and `helm uninstall` (or roll
  back) it. This is also why a non-interactive install path (Helm, or `--no-confirm` after approval) is safer than
  leaving the CLI hung on its TTY prompt.
- **`testkube version` shows no server version** — kubeconfig points at the wrong context, or the agent pods aren't
  `Running` yet. Run `kubectl config get-contexts` to identify the cluster with the agent, switch to it with
  `kubectl config use-context <context-with-the-agent>`, and re-check `kubectl get pods -n testkube`.
- **Expecting a dashboard** — standalone/OSS mode has none. The dashboard ships with the Testkube Control Plane, a
  separate install (see https://docs.testkube.io/articles/install/overview).

Referenced files: 1

test-discovery1.42 KB

View saved version →

---
name: test-discovery
description: "Walk a cloned repository, identify test files by framework and language, and report what was found in either a machine-readable JSON manifest or a human-readable Markdown report. Use when a repository has been cloned locally and you need to know what tests exist, what framework runs them, and what command executes them. The JSON output is consumed by programs (the testworkflow-author skill, cloud-api ingestion, CI); the Markdown output is meant for a person to read and opens cleanly in any plain-text editor. This skill does NOT execute tests, install dependencies, or write any TestWorkflow YAML — it observes and reports."
---

# test-discovery

Walk a cloned repository at the given path, identify the tests inside, and emit a structured JSON manifest describing
what was found. Output goes to stdout as a single JSON document. The consumer is typically the `testworkflow-author`
skill or the Testkube cloud-api discovery ingestion.

Scope:
- Read-only walk of the local filesystem
- Detect language and framework from marker files (config, manifest, lock files) and content signals
- Group findings into suites; a suite is one framework + one working directory
- Attach evidence + confidence to every suite
- Report ambiguity via `status: needs_input`; report failures via `status: error`

Out of scope: running tests, installing dependencies, writing TestWorkflow YAML, cloning repos, calling network APIs.

Referenced files: 2

testkube24.7 KB

View saved version →

---
name: testkube
description: "Orientation and routing for Testkube — the open testing platform that runs tests as Kubernetes-native TestWorkflows. Use when the user mentions Testkube, TestWorkflow, TestWorkflowTemplate, TestTrigger, a Testkube webhook, the `testkube` / `tk` / `kubectl-testkube` CLI, or a Testkube Control Plane or agent, and no more specific Testkube skill covers the task. ALSO use when the user asks to run tests (k6, Playwright, Cypress, JMeter, Postman, e2e, load) somewhere plain local execution cannot reach — in a Kubernetes cluster, in CI, on a schedule, or sharded at scale — even if Testkube is never named. Explains the platform model, indexes https://docs.testkube.io, and routes to the specialist skills (installing-testkube-cli, installing-testkube-oss-agent, test-discovery, testworkflow-author, testworkflow-runner). Prefer current docs over pre-trained knowledge. Orients and routes only — does NOT install, author YAML, or run executions, and says so when the tests should simply be run locally."
---

# testkube

[Testkube](https://testkube.io) is an open testing platform that runs tests inside Kubernetes. A test is declared as a
`TestWorkflow` — a Kubernetes custom resource describing which container image to run, which repository to check out,
and which commands to execute. Testkube turns that resource into a Kubernetes Job and reports back status, logs,
artifacts, and JUnit results. Any framework that runs in a container runs in Testkube: Playwright, Cypress, k6, JMeter,
Postman, Selenium, Go, Maven, Gradle, Robot Framework, and anything else with a CLI.

Testkube runs in two shapes. **Open-source standalone** is a single agent in one cluster, driven entirely from the CLI.
**Control Plane** (Testkube Cloud or on-prem) adds a dashboard, multi-environment management, and multiple connected
agents with distinct capabilities. Which shape is in play changes what commands and features are available — see
[Deployment topologies](#deployment-topologies) before answering questions about capabilities.

**This skill orients and routes.** It teaches the platform model, indexes the docs, and points at the skill that does
the actual work. It does not install, author, or execute anything itself.

## Retrieval sources

Testkube ships faster than any model's training data. Fetch, do not recall.

| Need                                     | Source                                                                          |
| ---------------------------------------- | ------------------------------------------------------------------------------- |
| Anything conceptual, current behavior    | https://docs.testkube.io — fetch the page                                        |
| CLI verbs, flags, resource names         | `testkube <verb> <resource> --help` — run it                                     |
| TestWorkflow field-level schema          | `../testworkflow-author/assets/workflow-schema.yaml`                             |
| TestWorkflowTemplate schema              | `../testworkflow-author/assets/template-schema.yaml`                             |
| Live CRD shape in a cluster              | `kubectl explain testworkflow.spec --recursive`                                  |
| Deep TestWorkflow concepts               | `../testworkflow-author/references/docs-concepts.md`                             |
| Worked YAML (22 frameworks)              | `../testworkflow-author/examples/` — indexed in `../testworkflow-author/references/examples-catalog.md` |
| REST API                                 | https://docs.testkube.io/openapi/overview                                        |
| CRD reference                            | https://docs.testkube.io/articles/crds                                           |
| What changed recently                    | https://docs.testkube.io/changelog                                               |
| A doc URL that 404s, or a page not indexed below | https://docs.testkube.io/sitemap.xml — every live page, authoritative     |

When the docs and any bundled reference file disagree, **the docs win** — reference files are snapshots.

The [Docs index](#docs-index) below is curated and can go stale. **If a link from it 404s, do not guess a replacement
slug — fetch the sitemap and find the current URL.**

## Rules

These are mandatory. Violating any rule produces answers that look authoritative and are wrong.

1. **MUST hand off to a specialist skill when one matches.** This skill orients; it does not execute. See
   [Skill index](#skill-index).
2. **MUST fetch the doc page before answering a factual question** about Testkube behavior, CLI flags, or CRD fields.
   **MUST NOT** answer from memory — pre-trained knowledge of Testkube is stale and skews toward the deprecated
   `Test` / `TestSuite` API.
3. **MUST NOT invent CLI flags, CRD fields, or `apiVersion` values.** Verify against `--help`, the bundled schemas, or
   the docs.
4. **MUST NOT author or edit TestWorkflow YAML here** — that is `testworkflow-author`.
5. **MUST NOT run, watch, or diagnose executions here** — that is `testworkflow-runner`.
6. **MUST say so plainly when no skill covers the task**, then route to the doc URL and the relevant
   `testkube ... --help`. See [Not covered by a skill](#not-covered-by-a-skill).
7. **MUST NOT steer a local test run onto Testkube.** If the tests can just be run where the user is, say so, name the
   plain command, and stop. This skill loads on generic "run my tests" phrasing precisely so it can rule Testkube
   *out* as well as in.

## Quick decision trees

### "Run my k6 / Playwright / e2e tests" — is Testkube the right answer?

Start here whenever the request is about running tests but never named Testkube. Testkube is not the answer to every
such request, and saying so is a valid outcome.

```
Where do these tests need to run?
├── right here, once, on this machine
│     └──► NOT Testkube. Run the framework directly — `npm test`, `npx playwright test`,
│          `k6 run`, `pytest`, `mvn test`. Say so plainly and stop. Do not load
│          another skill, do not author a workflow.
│
├── in a Kubernetes cluster, or against services only reachable from inside one
├── on a schedule, or triggered by a cluster event (deploy, rollout)
├── sharded, in parallel, or at load-test scale beyond one machine
├── in CI, with logs, artifacts and JUnit results kept centrally
└── identically for every engineer and every pipeline
      └──► Testkube fits ──► see "I want to run my tests with Testkube" below
```

If the request is genuinely ambiguous ("run my e2e tests" in a repo with a working local runner), **ask where they
should run before assuming Testkube.** A local test run needs no platform.

### "I want to run my tests with Testkube"

```
Is the `testkube` command available?
├── no  ──► installing-testkube-cli
└── yes
    │
    Is there a Testkube environment to run against?
    ├── no, and I want a local one  ──► installing-testkube-oss-agent
    ├── no, and I want Cloud/on-prem ──► docs: /articles/install/overview
    └── yes
        │
        Do I know what tests exist and what runs them?
        ├── no  ──► test-discovery   (emits test-manifest.json)
        └── yes
            │
            ──► testworkflow-author  (writes + validates workflow.yaml)
            │
            ──► testworkflow-runner  (runs it, diagnoses failures)
```

### "I need a Testkube environment"

```
Local cluster, open source, CLI-driven, no dashboard
  └──► installing-testkube-oss-agent

Testkube Cloud or on-prem Control Plane (dashboard, multi-env, licensed runners)
  └──► docs: /articles/install/overview, /articles/multi-agent-runner-helm-chart

Not sure which one I need
  └──► docs: /articles/install/feature-comparison
```

### "My workflow failed"

```
──► testworkflow-runner   reads logs, identifies root cause, reports exit code
    │
    ├── root cause is a workflow config problem (wrong image, missing step, bad command)
    │     └──► hand the finding to testworkflow-author to fix the YAML, then re-run
    │
    ├── root cause is a real test assertion failure
    │     └──► the workflow is fine; the tests found a bug
    │
    └── root cause is environment (agent down, no license, image pull)
          └──► installing-testkube-oss-agent (local) or docs: /articles/install/overview
```

### "I want tests to run automatically"

```
On a schedule                       ──► cron in the workflow spec: testworkflow-author
                                        (see examples/cron-trigger.yaml)
On a Kubernetes event (deploy, etc) ──► TestTrigger — docs: /articles/test-triggers  [no skill]
From a CI/CD pipeline               ──► docs: /articles/cicd-overview, /articles/github-actions  [no skill]
From another workflow               ──► `execute` step: testworkflow-author
                                        (see examples/suite-execute.yaml)
Overview of every trigger mechanism ──► docs: /articles/triggering-overview
```

### "I want to be notified when a test finishes"

```
HTTP callback to an external system ──► Webhooks — docs: /articles/webhooks           [no skill]
Reusable webhook definition         ──► Webhook templates — docs: /articles/webhooks  [no skill]
CDEvents / Kubernetes events        ──► docs: /articles/cd-events                     [no skill]
```

### "I want to share setup across workflows"

```
──► TestWorkflowTemplate — docs: /articles/test-workflow-templates, /articles/templates
    │
    ├── writing or consuming the template YAML  ──► testworkflow-author
    │                                               (see examples/jmeter-template.yaml,
    │                                                examples/step-level-use.yaml)
    └── CRUD on templates in a live environment ──► `testkube create/get/delete testworkflowtemplate --help`
```

## Skill index

| I need to...                                                              | Skill                           | Does NOT                                            |
| ------------------------------------------------------------------------- | ------------------------------- | --------------------------------------------------- |
| Install, upgrade, or verify the `testkube` CLI                            | `installing-testkube-cli`       | Deploy an agent or cluster                          |
| Get a local OSS Testkube environment running                              | `installing-testkube-oss-agent` | Set up a Control Plane; install the CLI itself      |
| Find out what tests a cloned repo has and what runs them                  | `test-discovery`                | Execute tests, install deps, or write YAML          |
| Write or fix TestWorkflow / TestWorkflowTemplate YAML                     | `testworkflow-author`           | Run the workflow                                    |
| Run a workflow, read logs, diagnose a failure                             | `testworkflow-runner`           | Edit workflow YAML                                  |
| Anything else (webhooks, triggers, integrations, resource CRUD, RBAC)     | *none ships in this plugin*     | — see [Not covered by a skill](#not-covered-by-a-skill) |

The skills chain: `test-discovery` → `testworkflow-author` → `testworkflow-runner`, with the two `installing-*` skills
as prerequisites. `installing-testkube-oss-agent` treats `installing-testkube-cli` as a **REQUIRED SUB-SKILL**.

## Concept glossary

**TestWorkflow** — the core resource (`apiVersion: testworkflows.testkube.io/v1`, `kind: TestWorkflow`). Declares
content (git checkout or inline files), container image, and an ordered list of steps.
See https://docs.testkube.io/articles/test-workflows

**TestWorkflowTemplate** — a reusable building block with the same schema shape (`kind: TestWorkflowTemplate`).
Workflows pull it in with `use` (top-level or step-level) or `template` (isolated). Templates cannot include other
templates. See https://docs.testkube.io/articles/test-workflow-templates

**TestWorkflowExecution** — one run of a workflow, with its own id, status, step results, logs, and artifacts. This is
what `testkube run` produces and what `testkube get testworkflowexecution` reads.

**Execution model** — Testkube creates a Kubernetes Job, which creates a Pod. Steps run as **sequential init
containers**; the last step runs as the main container. All steps share the `/data` volume; git content lands in
`/data/repo`. Job, Pod, and ConfigMaps are cleaned up afterward.
See https://docs.testkube.io/articles/test-workflows-high-level-architecture

**Control Plane** — the central component (Testkube Cloud or on-prem) providing the dashboard, organizations,
environments, and coordination of connected agents. Not present in OSS standalone.

**Agent** — a Testkube deployment in a cluster that connects to a Control Plane. Since 2.7.0 an agent carries any
combination of four capabilities: **runner** (executes workflows — requires a license), **listener** (watches
Kubernetes events for TestTriggers), **gitops** (syncs resources from a namespace into the Control Plane), and
**webhook** (emits webhooks, CDEvents, Kubernetes events).
See https://docs.testkube.io/articles/agents-overview

**Standalone Agent** — the open-source single-cluster deployment. No Control Plane, no dashboard; driven from the CLI.
See https://docs.testkube.io/articles/install/standalone-agent

**Organization / environment** — Control Plane scoping. An organization holds environments; each environment is a
logical boundary for workflows, executions, and connected agents.

**TestTrigger** — a Kubernetes-event-driven rule ("when this Deployment rolls, run that workflow"). Defined by a
YAML/JSON manifest, served by a listener agent. See https://docs.testkube.io/articles/test-triggers

**Webhook / WebhookTemplate** — outbound HTTP notification on execution events (start-test, end-testworkflow, and
friends), with a custom payload; templates make the definition reusable.
See https://docs.testkube.io/articles/webhooks

**Artifacts** — files collected from steps via `artifacts.paths` glob patterns, stored in MinIO or S3-compatible
storage. Testkube automatically scans `.xml` artifacts for JUnit reports.
See https://docs.testkube.io/articles/test-workflows-artifacts and
https://docs.testkube.io/articles/test-workflows-reports

**Expressions** — the `{{ }}` templating language available in most string fields: arithmetic, comparisons, string and
JSON functions, `secret()`, `shellquote()`, plus built-ins like `execution.id`, `workflow.name`, `config.*`, `matrix.*`,
`failed`, `passed`. See https://docs.testkube.io/articles/test-workflows-expressions

**`Test` / `TestSuite` (legacy)** — the pre-TestWorkflow API. **Deprecated.** New work uses TestWorkflows.
See https://docs.testkube.io/articles/legacy-deprecation

## Deployment topologies

Getting this wrong is the most common source of confidently incorrect Testkube answers. Establish which topology is in
play before describing capabilities.

| | **OSS standalone agent** | **Control Plane (Cloud / on-prem)** |
| --- | --- | --- |
| Dashboard | none — CLI only | yes |
| Scope | one cluster, one namespace | many environments, many connected agents |
| Auth | local kubeconfig / API URI | `testkube login`, org + environment context |
| Runner agents | n/a | yes (licensed) |
| Listener / GitOps / webhook agents | n/a | yes |
| License | not required | required for licensed capabilities |
| Set up with | `installing-testkube-oss-agent` | https://docs.testkube.io/articles/install/overview |

Full matrix: https://docs.testkube.io/articles/install/feature-comparison

## Docs index

All URLs below are under `https://docs.testkube.io`. This index is curated, not generated — if a link 404s, get the
current URL from https://docs.testkube.io/sitemap.xml rather than guessing a slug.

**Start here**

| Page | URL |
| --- | --- |
| Documentation home | https://docs.testkube.io/ |
| Open source overview | https://docs.testkube.io/articles/open-source |
| Quickstart (OSS) | https://docs.testkube.io/articles/getting-started-with-open-source |
| Hands-on tutorial | https://docs.testkube.io/articles/tutorial/quickstart/overview |
| Testkube for AI agents | https://docs.testkube.io/articles/ai-agents |

**Install**

| Page | URL |
| --- | --- |
| Install overview | https://docs.testkube.io/articles/install/overview |
| Standalone agent (OSS) | https://docs.testkube.io/articles/install/standalone-agent |
| Runner agent Helm chart | https://docs.testkube.io/articles/multi-agent-runner-helm-chart |
| Install with Helm | https://docs.testkube.io/articles/install/install-with-helm |
| Advanced install | https://docs.testkube.io/articles/install/advanced-install |
| OSS vs Control Plane | https://docs.testkube.io/articles/install/feature-comparison |
| MongoDB administration | https://docs.testkube.io/articles/mongodb-administration |

**Concepts**

| Page | URL |
| --- | --- |
| Testing pipeline | https://docs.testkube.io/articles/testing-pipeline |
| Architecture | https://docs.testkube.io/articles/architecture |
| Agents overview | https://docs.testkube.io/articles/agents-overview |
| Agent CLI commands | https://docs.testkube.io/articles/multi-agent-cli |
| Environment management | https://docs.testkube.io/articles/environment-management |
| Using Testkube | https://docs.testkube.io/articles/using-testkube |

**TestWorkflows**

| Page | URL |
| --- | --- |
| Overview | https://docs.testkube.io/articles/test-workflows |
| Creating | https://docs.testkube.io/articles/test-workflows-creating |
| Running | https://docs.testkube.io/articles/test-workflows-running |
| Execution architecture | https://docs.testkube.io/articles/test-workflows-high-level-architecture |
| Templates | https://docs.testkube.io/articles/test-workflow-templates |
| Official templates | https://docs.testkube.io/articles/templates |
| Basic examples | https://docs.testkube.io/articles/test-workflows-examples-basics |
| Content (git, files) | https://docs.testkube.io/articles/test-workflows-content |
| Artifacts | https://docs.testkube.io/articles/test-workflows-artifacts |
| Reports (JUnit) | https://docs.testkube.io/articles/test-workflows-reports |
| Services | https://docs.testkube.io/articles/test-workflows-services |
| Parallelization | https://docs.testkube.io/articles/test-workflows-parallel |
| Matrix & sharding | https://docs.testkube.io/articles/test-workflows-matrix-and-sharding |
| Expressions | https://docs.testkube.io/articles/test-workflows-expressions |
| Step data sharing | https://docs.testkube.io/articles/test-workflows-step-sharing |
| Suites (`execute`) | https://docs.testkube.io/articles/test-workflows-test-suites |

**Automation & integrations**

| Page | URL |
| --- | --- |
| Triggering overview | https://docs.testkube.io/articles/triggering-overview |
| Test triggers | https://docs.testkube.io/articles/test-triggers |
| Webhooks | https://docs.testkube.io/articles/webhooks |
| CDEvents | https://docs.testkube.io/articles/cd-events |
| GitOps | https://docs.testkube.io/articles/gitops-overview |
| CI/CD overview | https://docs.testkube.io/articles/cicd-overview |
| GitHub Actions | https://docs.testkube.io/articles/github-actions |
| Integrations | https://docs.testkube.io/articles/integrations |
| MCP server (preview) | https://docs.testkube.io/articles/mcp-overview |

**Reference**

| Page | URL |
| --- | --- |
| CLI reference | https://docs.testkube.io/cli/testkube |
| OpenAPI / REST | https://docs.testkube.io/openapi/overview |
| CRDs | https://docs.testkube.io/articles/crds |
| Licensing | https://docs.testkube.io/articles/licensing |
| Telemetry | https://docs.testkube.io/articles/telemetry |
| Legacy deprecations | https://docs.testkube.io/articles/legacy-deprecation |
| Logs & artifacts | https://docs.testkube.io/articles/logs-and-artifacts |
| Examples & guides | https://docs.testkube.io/articles/examples/overview |
| Changelog | https://docs.testkube.io/changelog |

## CLI orientation

Learn the shape of the CLI, then discover the details with `--help`. Do not recall flags.

The same binary is installed under three names — `testkube`, `tk`, and `kubectl-testkube` (invoked as
`kubectl testkube`). Resolve it defensively before use:

```bash
TK_CMD="$(command -v testkube || command -v tk || command -v kubectl-testkube)"
[ -n "$TK_CMD" ] || echo "Testkube CLI not found; use installing-testkube-cli"
```

Commands follow `testkube <verb> <resource> [name] [flags]`:

| Verb | Purpose |
| --- | --- |
| `create` | Create a resource, usually from `-f <file>`; `--update` upserts |
| `get` | List resources, or show one by name |
| `update` | Update an existing resource |
| `delete` | Delete a resource |
| `run` | Start a workflow execution (`-f` streams and blocks until terminal) |
| `watch` | Follow a running execution |
| `cancel` | Cancel executions |
| `download` | Fetch artifacts from an execution |

Resource names and their aliases:

| Resource | Aliases |
| --- | --- |
| `testworkflow` | `testworkflows`, `tw` |
| `testworkflowexecution` | `testworkflowexecutions`, `twe`, `twexecution` |
| `testworkflowtemplate` | `testworkflowtemplates`, `twt` |
| `testtrigger` | `testtriggers`, `tt` |
| `workflowtrigger` (v2) | `workflowtriggers`, `wt` |
| `webhook` | `webhooks`, `wh` |
| `webhooktemplate` | `webhooktemplates`, `wht` |

Context and status:

```bash
testkube version                 # CLI + server version, current context and namespace
testkube status                  # feature / resource status
testkube login                   # authenticate against a Control Plane
testkube set context --help      # switch org / environment / namespace
testkube dashboard               # open the dashboard (Control Plane only)
testkube --help                  # full verb list, including agent, mcp, debug, diagnostics
```

Full reference: https://docs.testkube.io/cli/testkube

## Not covered by a skill

**No skill in this plugin covers the tasks below.** Say so, then use the doc page and the `--help` output.

| Task | Docs | CLI |
| --- | --- | --- |
| Webhooks | https://docs.testkube.io/articles/webhooks | `testkube create webhook --help` |
| Webhook templates | https://docs.testkube.io/articles/webhooks | `testkube create webhooktemplate --help` |
| Test triggers | https://docs.testkube.io/articles/test-triggers | `testkube create testtrigger --help` |
| Workflow triggers (v2) | https://docs.testkube.io/articles/triggering-overview | `testkube create workflowtrigger --help` |
| TestWorkflowTemplate CRUD | https://docs.testkube.io/articles/test-workflow-templates | `testkube create testworkflowtemplate --help` |
| GitOps sync | https://docs.testkube.io/articles/gitops-overview | `testkube agent --help` |
| CI/CD integration | https://docs.testkube.io/articles/cicd-overview | — |
| Control Plane install | https://docs.testkube.io/articles/install/overview | `testkube init --help` |
| Agents & runners | https://docs.testkube.io/articles/agents-overview | `testkube create runner --help` |
| MCP server (preview) | https://docs.testkube.io/articles/mcp-overview | `testkube mcp --help` |
| Licensing | https://docs.testkube.io/articles/licensing | — |

## Gotchas

- **Answering from memory** — pre-trained knowledge of Testkube is stale and biased toward the deprecated
  `Test` / `TestSuite` API. Fetch the doc page or run `--help` before stating a fact.
- **Recommending `kind: Test` or `testkube create test`** — that is the legacy API. New work uses `TestWorkflow`.
- **Assuming a dashboard exists** — the OSS standalone agent has none. `testkube dashboard` is a Control Plane feature.
- **Assuming runner / listener / gitops / webhook agents are available** — those are Control Plane capabilities, and
  runner agents require a license. They do not exist in OSS standalone.
- **Expecting sidecars in steps** — steps run as init containers, so operator-injected sidecars (Istio, Linkerd) are
  not reachable from them. Container merging exists partly to mitigate this.
- **Expecting a fresh filesystem per step** — steps in one pod share `/data`. Parallel workers do not: use
  `transfer` / `fetch`.
- **Guessing doc URLs** — `docs.testkube.io/...` and `testkube.io/docs/...` both resolve, but invented slugs 404.
  Use the [Docs index](#docs-index) or search from https://docs.testkube.io/.
- **Doing the specialist skill's job** — if the request is "write this workflow" or "run and debug this", stop routing
  and hand off. This skill produces orientation, not artifacts.
- **Answering "run my tests" with Kubernetes** — this skill loads on generic test-running phrasing, so it will
  sometimes load when the right answer is `npm test`. Give that answer. Reaching for a cluster the user never asked
  for costs them an install and buys them nothing.

Referenced files: 1

testworkflow-author18 KB

View saved version →

---
name: testworkflow-author
description: "Create and validate Testkube TestWorkflow YAML files. Use when writing test workflow YAML, choosing step types, or when the user asks to create a Testkube TestWorkflow. Covers shell steps, container run steps, execute composition, templates, services, artifacts, config parameters, and cron triggers. By default it takes free-form requirements and writes a YAML file; it can OPTIONALLY take a structured JSON authoring request and/or emit the finished workflow as JSON for programmatic callers, without changing the default behavior. Does NOT run workflows — that is the testworkflow-runner skill's responsibility."
---

# testworkflow-author

Create and validate Testkube TestWorkflow YAML files. This skill writes the workflow and validates its schema. It does
NOT run the workflow or analyze execution results — the `testworkflow-runner` skill handles that.

Write files in the current working directory. Default to the filename `testworkflow.yaml` unless a different path is
specified. Do not invent credentials, secrets, tokens, or private URLs — if you need them, describe what you need in
your final message (see Credentials below).

## Input and output: default behavior vs. optional JSON mode

**Default (UNCHANGED — this is what you do unless the invocation explicitly opts in below).**
Requirements arrive as free-form natural language. You write the workflow to a YAML file in the current
working directory (default filename `testworkflow.yaml`), validate it, and describe the result in your
final message. Nothing about this behavior changes. If you are unsure which mode you are in, you are in
this one — it is the correct default.

**Optional JSON mode (opt-in only).** Some callers are programs, not people. When — and only when — the
invocation explicitly opts in, you may take a structured JSON authoring request as input, emit the
finished workflow as a structured JSON envelope as output, or both. The two directions are independent;
either can be requested without the other.

Opt-in signals:
- **JSON input**: the invocation supplies a JSON object (an authoring request) as its payload, or a path
  to a `.json` request file. Read requirements from it instead of from prose.
- **JSON output**: the invocation contains a phrase like "output as JSON", "respond with JSON",
  "format: json", or gives an output path ending in `.json`. Emit the JSON envelope below to stdout
  instead of prose.

**What does NOT change in JSON mode.** The entire Core Loop and every Rule still apply — read lock files,
match image versions, install dependencies in a separate step, validate with `--dry-run`. The YAML you
produce in JSON mode is byte-for-byte the YAML you would have written to disk in default mode. JSON mode
only changes how requirements come in and how the finished workflow is handed back; it is a thin wrapper
around the exact same authoring, never a different authoring. When no opt-in signal is present, ignore
this section entirely.

### JSON input schema (authoring request)

When JSON input is provided, it has the shape below. Only `framework` (or an explicit `testCommand`) is
required; every other field is optional and, when absent, falls back to the same inference you do today
(read lock files, pick the framework's default command and image). This shape is intentionally compatible
with a `suites[]` entry from the `test-discovery` skill, so that skill's output can be piped straight in.

```json
{
  "workflowName": "playwright-e2e",
  "framework": "playwright",
  "language": "typescript",
  "workingDir": "/data/repo",
  "content": { "git": { "uri": "https://github.com/acme/app", "revision": "main" } },
  "image": "mcr.microsoft.com/playwright:v1.49.0-noble",
  "installCommand": "npm ci",
  "testCommand": "npx playwright test",
  "envVars": ["BASE_URL", "TEST_USER"],
  "artifacts": ["playwright-report/**", "test-results/**"],
  "config": {}
}
```

If required information is missing and cannot be inferred, emit the `needs_input` envelope rather than
guessing (same discipline as the Credentials rule). Full field list: `assets/json-mode-input.schema.json`.

### JSON output envelope

When JSON output is requested, emit exactly one JSON document to stdout — no prose, no code fences; it
starts with `{` and ends with `}`:

```json
{
  "schemaVersion": 1,
  "status": "success",
  "workflow": {
    "name": "playwright-e2e",
    "filename": "testworkflow.yaml",
    "yaml": "apiVersion: testworkflows.testkube.io/v1\nkind: TestWorkflow\nmetadata:\n  name: playwright-e2e\nspec:\n  ..."
  },
  "validation": { "method": "dry-run", "passed": true, "errors": [] },
  "notes": []
}
```

- `workflow.yaml` is the complete workflow as a string — identical to the file the default mode writes.
- If a target file path was also given, still write the YAML file; stdout only mirrors it inside the envelope.
- `validation.method` is `"dry-run"` when the `testkube` CLI was available, else `"skipped"` (say why in `notes`).

Alternate statuses (same JSON discipline — never guess, report instead):

```json
{ "schemaVersion": 1, "status": "needs_input", "reason": "<short tag>", "message": "<one sentence>", "context": {} }
```

```json
{ "schemaVersion": 1, "status": "error", "code": "<short tag>", "message": "<one sentence>" }
```

Full envelope schema: `assets/json-mode-output.schema.json`. Contract tests: `tests/testworkflow-author-json-mode/`.

## The Core Loop

Every TestWorkflow task follows this sequence:

1. **Review context** — check for context from previous steps (what tool was chosen, what version, how to run it, what
   files exist).
2. **Gather requirements** — test tool, environment variables, expected artifacts, resource needs.
3. **Read dependency files** — read the lock file (package-lock.json, go.sum, poetry.lock, Gemfile.lock, pom.xml) to
   determine exact resolved versions. If no lock file exists, read the manifest (package.json, go.mod, etc.)
4. **Read schema** — load `references/schema.md` with the `read` tool (Rule 7)
5. **Choose step types** — use the Decision Tree and Step Type Guide below
6. **Write the YAML** — load a matching example from `examples/` as your starting template (e.g.
   `examples/playwright-git.yaml` for Playwright, `examples/go-build-lint.yaml` for Go,
   `examples/k6-inline.yaml` for K6)
7. **Validate** — `testkube create testworkflow --dry-run -f <file>`
8. **Fix and re-validate** — address every validation error before proceeding

## Credentials

When the workflow requires credentials, tokens, or secrets you do not have, describe what you need clearly in your final
message. Do not guess or use placeholder values. The credential will be provided on your next invocation.

### How to reference credentials in workflows

Use Testkube-managed `credential()` expressions:

```yaml
env:
  - name: API_KEY
    value: '{{ credential("my-api-key") }}'
```

Or Kubernetes Secret references:

```yaml
env:
  - name: API_TOKEN
    valueFrom:
      secretKeyRef:
        name: my-secret
        key: token
```

If you don't know the credential name, say what you need in your response and it will be provided.

## Rules

These are mandatory. Violating any rule produces a broken workflow.

1. **MUST install dependencies in a separate step.** If the project has a dependency manifest (package.json, go.mod,
   requirements.txt, Gemfile, pom.xml, build.gradle), add a dedicated install step BEFORE the test step. Never assume
   dependencies are pre-installed in the container image. Example: `npm ci`, `go mod download`,
   `pip install -r requirements.txt`.

2. **MUST read the lock file to determine resolved versions.** Semver ranges in manifests (`^1.52.0`, `~2.3`, `>=1.0`)
   do NOT tell you what version gets installed. Read package-lock.json, go.sum, poetry.lock, Gemfile.lock to find the
   actual resolved version. If no lock file exists, run the install command and check what was resolved, or use the
   latest stable image for the tool.

3. **MUST match the container image tag to the resolved dependency version.** The image tag must match the major.minor
   version from the lock file. Example: if package-lock.json resolves `@playwright/test` to `1.61.1`, use image
   `mcr.microsoft.com/playwright:v1.61.1-noble`. A mismatch causes `browserType.launch: Executable doesn't exist` or
   equivalent errors.

4. **MUST use `npx`/equivalent for locally-installed CLI tools.** After `npm ci`, binaries are in `node_modules/.bin/`,
   not on PATH. Run tools via `npx <tool>` (Node.js), `python -m <module>` (Python), or the built binary path (Go).
   Never assume a tool is globally available just because its package is installed.

5. **MUST set `condition: always` on artifact collection steps.** Artifacts (reports, screenshots, traces) are most
   valuable when tests fail. Without `condition: always`, the artifact step is skipped on failure — exactly when you
   need it most.

6. **MUST understand that `--dry-run` validates schema only.** A passing dry-run means the YAML structure is valid. It
   does NOT mean the workflow will succeed at runtime. Missing dependencies, wrong image versions, and incorrect
   commands all pass dry-run without error.

7. **MUST read `references/schema.md` before writing any YAML.** This reference covers the most-used fields
   with examples. Load it with the `read` tool before starting to write. Do not rely on memory alone.

## Decision Tree

### Choosing a step type

```
Need to run a test?
├── Single command, default image?
│   └── shell step (simplest)
├── Different image or custom env per step?
│   └── run step
├── Reuse an existing pattern (official/community template)?
│   └── template step
├── Compose multiple existing workflows or tests?
│   └── execute step
├── Run same test with varying parameters (matrix/shard)?
│   └── parallel step
├── Need a companion service (database, Selenium, Docker-in-Docker)?
│   └── services
└── Need pre/post cleanup that always runs?
    └── setup / after
```

## Schema Quick Reference

The 15 most-used spec fields. See `references/schema.md` for the full schema.

| Field                       | Purpose                            | Example                                 |
| --------------------------- | ---------------------------------- | --------------------------------------- |
| `spec.content`              | Where test code comes from         | `{git: {uri, revision}}` or `{files}`   |
| `spec.container.image`      | Default container image for steps  | `"node:22"`                             |
| `spec.container.resources`  | CPU/memory requests and limits     | `{requests: {cpu: 128m, memory: 128Mi}}`|
| `spec.container.workingDir` | Working directory for all steps    | `"/data/repo"`                          |
| `spec.steps[].shell`        | Inline shell command (simplest)    | `"npm test"`                            |
| `spec.steps[].run`          | Step with custom container/image   | `{image, shell, env}`                   |
| `spec.steps[].execute`      | Run other workflows or tests       | `{workflows: [{name}]}`                 |
| `spec.steps[].template`     | Use a TestWorkflowTemplate         | `{name: "official/k6", config: {...}}`  |
| `spec.steps[].parallel`     | Parallel matrix or sharding        | `{count: 5}`                            |
| `spec.steps[].artifacts`    | Collect output files               | `{paths: ["**/*"]}`                     |
| `spec.config`               | Parameterized inputs for workflow  | `{VUS: {type: integer, default: 5}}`    |
| `spec.events`               | CronJob triggers                   | `[{cronjob: {cron: "0 * * * *"}}]`      |
| `spec.services`             | Sidecar containers (DB, Selenium)  | `{chrome: {image, readinessProbe}}`     |
| `spec.setup` / `spec.after` | Pre/post hooks, same as steps      | `setup: [{shell: "..."}]`               |

## CLI Quick Start

Commands for authoring. Full flags: `references/cli-reference.md`.

```bash
# Validate a workflow (schema check only — does NOT guarantee runtime success)
testkube create testworkflow --dry-run -f workflow.yaml

# Create a workflow (use --update if it already exists)
testkube create testworkflow -f workflow.yaml
testkube create testworkflow --update -f workflow.yaml

# Inspect a workflow definition
testkube get testworkflow <name>
```

Note: Running workflows and reading execution logs is the `testworkflow-runner` skill's job, not yours.

## Step Type Decision Guide

Detailed patterns with YAML examples: `references/step-patterns.md`.

| Step Type    | Use When                        | Key Fields                            | Example Scenario                               |
| ------------ | ------------------------------- | ------------------------------------- | ---------------------------------------------- |
| **shell**    | Single command, default image   | `shell`                               | "Run npm test in the default Playwright image" |
| **run**      | Different image/env per step    | `run: {image, shell, env, resources}` | "Lint Go code with golang:1.26 image"          |
| **execute**  | Run existing Testkube resources | `execute: {workflows, tests}`         | "Orchestrate a test suite of 3 workflows"      |
| **template** | Reuse a TestWorkflowTemplate    | `template: {name, config}`            | "Use official/k6 template with custom VUS"     |
| **use**      | Include template defaults       | `use: [{name}]`                       | "Add close-istio sidecar template"             |
| **parallel** | Matrix or sharded execution     | `parallel: {count, shards, matrix}`   | "Run K6 with 5 VUs in parallel"                |

### Step nesting

Steps can be nested: a parent step with `steps:` runs its children sequentially within that step's container context.
Use nesting for logical grouping — install deps, run tests, save artifacts — within a single container image.

### Step ordering

Steps run sequentially by default. Use `condition` to control when a step runs (`"passed"`, `"failed"`, `"always"`). Use
`optional: true` for non-critical steps whose failure should not fail the workflow.

## Gotchas

Environment-specific facts that defy reasonable assumptions.

- **Container merging**: By default, multiple simple steps may merge into one container for efficiency. Use
  `spec.system.isolatedContainers: true` for full isolation between steps.
- **Init containers**: Steps execute as init containers sequentially; the last step runs as the main container. Sidecar
  containers injected by operators (Istio, Linkerd) may not be available to init containers.
- **workingDir resolution**: Relative paths resolve against the container's WORKDIR, not the workflow root. Set
  `workingDir` explicitly to the directory where your test code lives.
- **Artifact paths**: Relative artifact paths resolve against the step's `workingDir`. Use absolute paths
  (`/data/artifacts/**`) to avoid ambiguity.
- **`{{ }}` expressions**: Usable in most string fields. `{{ config.param }}` for config values,
  `{{ services.name.0.ip }}` for service IPs, `{{ shellquote(env.VAR) }}` for safe shell quoting of env vars.
- **Image pull**: Images must come from a container registry — local images are not supported. Private registries
  require `imagePullSecrets` in `spec.pod`.
- **`activeDeadlineSeconds`**: Without this, a stuck workflow runs until the cluster kills it. Set in `spec.job` for
  workflow-level timeout, or `spec.pod` for per-pod limits.
- **Template inlining**: Templates are expanded before execution. `use` at top-level shares defaults across all steps;
  `use` at step-level scopes defaults to that step only; `template` at step-level is fully isolated.
- **`shell` auto-prepends `set -e`**: The shell step type exits on the first failing command by default. Use `run.shell`
  if you need more control over error handling behavior.
- **Playwright images**: Use `mcr.microsoft.com/playwright:v<VERSION>-noble` where `<VERSION>` matches the resolved
  `@playwright/test` version from the lock file. A bare `node` image will fail with
  `browserType.launch: Executable doesn't exist`. Check
  [Microsoft Artifact Registry](https://mcr.microsoft.com/en-us/product/playwright/about) for available tags.

## Validation Loop

Before finishing, always validate the schema:

```bash
# 1. Validate against the CRD schema
testkube create testworkflow --dry-run -f workflow.yaml

# 2. If validation fails, read the error message, fix the file, re-run step 1

# 3. Only proceed when dry-run passes
```

Never skip validation. A YAML that looks correct can still fail schema checks (missing required fields, wrong types,
invalid enum values). Remember: dry-run validates structure only — it cannot catch runtime errors like missing
dependencies or image version mismatches (see Rule 6).

## Reference Index

Load these files on demand — when the task calls for them.

| Reference                        | When to Load                                              | Status    |
| -------------------------------- | --------------------------------------------------------- | --------- |
| `assets/workflow-schema.yaml`    | When needing every available field and description        | Available |
| `assets/template-schema.yaml`    | When authoring TestWorkflowTemplates                      | Available |
| `assets/json-mode-input.schema.json`  | When taking a JSON authoring request (optional JSON mode) | Available |
| `assets/json-mode-output.schema.json` | When emitting the JSON output envelope (optional JSON mode)| Available |
| `references/schema.md`           | When writing or editing any YAML field                    | Available |
| `references/cli-reference.md`    | When needing CLI flags for create/dry-run                 | Available |
| `references/step-patterns.md`    | When choosing between step types or seeking YAML snippets | Available |
| `references/docs-concepts.md`    | When a concept (templates, merging, artifacts) is unclear | Available |
| `references/examples-catalog.md` | When seeking real-world patterns by tool/pattern          | Available |
| `examples/*.yaml`                | When needing concrete, runnable examples                  | Available |

Referenced files: 33

testworkflow-runner7.01 KB

View saved version →

---
name: testworkflow-runner
description: "Run, monitor, and diagnose Testkube TestWorkflow executions. Use when a TestWorkflow has been authored and needs to be executed, or when a previous execution failed and needs diagnosis. Reports execution results and root causes — does NOT edit workflow YAML."
---

# testworkflow-runner

Run a TestWorkflow, read execution logs, and diagnose failures. This skill handles the execution lifecycle AFTER the
workflow YAML has been written and validated by `testworkflow-author`.

This skill does NOT edit workflow YAML. If the diagnosis indicates a workflow configuration problem (wrong image,
missing step, incorrect command), report it in the deliverable — the parent agent decides whether to re-invoke
`testworkflow-author` with the fix.

## The Core Loop

1. **Review context** — check for context from previous agents (workflow file path, image chosen, install/run commands,
   known issues)
2. **Create and run the workflow** — create the workflow and start an execution. Use a blocking run so the command
   returns only when the execution completes:
   ```bash
   testkube create testworkflow -f workflow.yaml
   testkube run testworkflow <name> -f
   ```
   The default file path is `workflow.yaml`; pass the actual path if the workflow was written to a different location.
   The `-f` flag streams output and blocks until the execution reaches a terminal state (passed, failed, aborted).
3. **If failed, get logs** — use `--logs-only` to read just the execution logs. Filter by step or grep for error
   patterns:
   ```bash
   testkube get testworkflowexecution <execution-id> --logs-only
   ```
4. **Get execution details** — for full status, step results, and duration:
   ```bash
   testkube get testworkflowexecution <execution-id>
   ```
5. **Diagnose** — identify root cause using the Failure Patterns below.
6. **Report your diagnosis** — include workflow name, execution ID, status, exit code, and root cause with a
   recommendation.

## Rules

1. **MUST read the full execution logs before diagnosing.** Never guess the failure cause from the status alone. The
   error message in the logs is the source of truth.
2. **MUST report the EXACT error message from logs.** Copy the relevant error text verbatim — do not paraphrase or
   summarize it.
3. **MUST check the exit code.** Exit code 127 = command not found (missing dependency or wrong PATH). Exit code 1 =
   test assertion failure. Exit code 137 = OOMKilled.
4. **MUST NOT edit the workflow YAML.** Report what needs to change — the parent handles re-authoring.

## CLI Commands

| Command                                          | Purpose                                                              |
| ------------------------------------------------ | -------------------------------------------------------------------- |
| `testkube create testworkflow -f <file>`         | Create a workflow from a YAML file                                   |
| `testkube run testworkflow <name> -f`            | Run a workflow, stream output, block until completion                |
| `testkube get testworkflowexecution <id>`        | Get execution status, step results, duration, and artifact listing   |
| `testkube get testworkflowexecution <id> --logs-only` | Fetch execution logs (supports `--tail`, `--grep`, `--step`)    |
| `testkube download artifacts <id>`               | Download artifacts from an execution                                 |
| `testkube download artifacts <id> --mask '.*\.xml$'` | Download only JUnit XML artifacts                               |

Full CLI reference: `references/cli-reference.md`.

## Failure Patterns

| Symptom                                          | Exit Code | Root Cause                                                                                 | Recommendation                                                                                              |
| ------------------------------------------------ | --------- | ------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------- |
| `command not found`                              | 127       | Binary not on PATH — missing `npm ci`/install step, or using bare command instead of `npx` | Add install step, use `npx <tool>`                                                                          |
| `Executable doesn't exist at /ms-playwright/...` | 1         | Playwright image version doesn't match installed package version                           | Match image tag to lock file version                                                                        |
| `Please update docker image as well`             | 1         | Playwright explicitly says image/package mismatch                                          | Use the version it suggests                                                                                 |
| `OOMKilled`                                      | 137       | Container exceeded memory limit                                                            | Increase `resources.limits.memory`                                                                          |
| `ImagePullBackOff` / `ErrImagePull`              | —         | Image name wrong or registry unreachable                                                   | Verify image exists on registry                                                                             |
| `DeadlineExceeded`                               | —         | Workflow or step timed out                                                                 | Increase `activeDeadlineSeconds`                                                                            |
| `CrashLoopBackOff`                               | —         | Container crashes on startup                                                               | Check `command`/`args` or image entrypoint                                                                  |
| Non-zero exit with test output                   | 1         | Test assertion failures (actual test bugs)                                                 | Tests ran correctly but found failures — this is expected behavior, report as test failure not config issue |

## Interpreting Exit Codes

- **Exit 0**: All tests passed
- **Exit 1**: Test failures (assertions) OR general error
- **Exit 127**: Command not found — the binary doesn't exist in PATH
- **Exit 137**: OOMKilled (SIGKILL from kernel)
- **Exit 143**: SIGTERM (timeout, graceful shutdown)

When exit code is 127, the fix is ALWAYS about dependency installation or PATH — never about the test code itself.

## Reference Index

| Reference                      | When to Load                                | Status    |
| ------------------------------ | ------------------------------------------- | --------- |
| `references/analysis-guide.md` | When needing detailed diagnostic procedures | Available |
| `references/cli-reference.md`  | When needing full CLI flags for run/get     | Available |

Referenced files: 3

Package details

Publisher declarations from the archived package. These are separate from our research and the live service's terms.

Package license
MIT
Package author
Testkube
Keywords
testkube, cli, kubernetes, k3d, minikube, install, testing, discovery, testworkflow, yaml, e2e, load-testing, diagnose, docs, orientation, testworkflowtemplate, webhooks, triggers

Declared capabilities

  • Read
  • Write
  • Execute

Package observed Oct 2, 2026.

Technical details
First seen
Sep 30, 2026 · 22:02 UTC
Last seen
Oct 2, 2026 · 12:00 UTC
Collection status
Collected

plugins_6a71c05d80248191a9a73c2ea2c07978

Download plugin data (JSON)