# Testing Policy (mandatory)

A build or change is NOT done until the workflow has been EXECUTED on the
user's instance and the execution INSPECTED node by node. Node validation
(`awesomate_n8n_node_docs validate_node`) checks structure, not behaviour:
a passing validation plus a green final status is never "tested".

Applies to: new builds (SKILL.md Phase 5), changes to a live workflow (test
the change AND re-verify the live one after it is applied), and any fix to a
failing workflow. Only exception: the user explicitly waives testing for that
specific task.

## How a test runs

There is no manual or pin-data execution on this platform. E2E = publish +
production webhook + poll executions:

1. Get approval to go live, then publish the workflow through the n8n MCP
   server's publish tool (or the user switches it on in n8n). Production
   webhooks only respond while the workflow is published.
2. Run it. Three ways, pick the one that fits: the n8n MCP server's execute
   tool; a POST to the PRODUCTION webhook URL (`{instanceUrl}/webhook/<path>`)
   with the fixture as the body; or ask the user to trigger it themselves
   (submit the form, send the email). Real side effects DO run: emails
   actually send. Address them to the user's own email, prefix subjects
   `[TEST]`, use obviously fake data (`test+<runId>@…`, "TEST SUBMISSION"),
   and tell the user before firing. Non-email side effects (CRM writes,
   payments, SMS): STOP and ask first.
3. Find the run: `awesomate_n8n_executions {workflowId}` lists the newest
   executions; the one you just caused is at the top.
4. Inspect: `awesomate_n8n_executions {executionId, debug: true}`. Read the
   node list, per-node output, and which branches ran. When consent is off,
   debug data is unavailable and the call falls back to the non-debug
   detail (final status + failing node only). State that in the report; you
   inspected less than usual.

A green final status is not inspection. Do not enable
`saveExecutionProgress` to get richer data. Keep it FALSE on every workflow
you write (write-amplification incident); `debug: true` is the inspection
path.

## Fixtures (payload classes)

The body you POST is what the workflow sees at `$json.body`. Run at minimum
one of each class:

| Class | Payload |
|---|---|
| happy-path | Realistic valid input, obviously fake values |
| empty | `{}` / missing fields entirely |
| malformed | Wrong types, missing required fields, junk strings |
| error-`<api>` | Input that drives a named upstream API to a realistic error (nonexistent id → 404, bad enum → 400): one per external dependency |

Awesomate sets no cap on test runs; the only cost is the side effects, so
plan the fixture set before firing rather than spraying the user's inbox.

## Error-path testing (required, minimum 3)

1. Failed upstream call (error-`<api>` fixture)
2. Empty payload
3. Malformed payload

Verify `onError` branches ACTUALLY ROUTE: in the execution's node list,
confirm the error path's nodes ran and the post-failure happy-path nodes
did not. Final status alone proves nothing: an execution whose error
branch routed can still finish green.

## Multi-trigger gotcha

A webhook fire reaches the webhook trigger only. A schedule (or any
non-webhook) branch NEVER runs from it. It is untested unless exercised
deliberately:

- Temporarily wire the branch behind a webhook trigger (update the workflow
  through the n8n MCP server), fire it, then REMOVE the temporary trigger
  before the workflow stays live.
- Never leave live a workflow carrying a temporary test trigger: it is a
  world-callable production URL.
- If the branch cannot be exercised this way, list it under "needs human"
  in the report. Do not report it as tested.

## What Claude cannot verify → human checklist

List explicitly, per test run:

- Real side effects landing (the `[TEST]` email in their inbox, the CRM
  record, the SMS)
- OAuth/credential-gated calls that could not be exercised
- External services actually pointing at the production webhook URL
- Schedule/non-webhook branches that never fired (see above)

Ask the user to confirm each ("check your inbox for [TEST] …") and record
their answer in the report.

## Test Report (required in every handoff)

```
## Test Report: <workflow> @ <instance>
Executed: <executionIds + payload class for each>
Inspection: debug / non-debug fallback (consent off)
Passed: <node paths verified, outputs checked>
Error paths: <fixture → which branch routed → result>
Not verifiable by Claude (needs human): <list + why>
Post-test state: restored ✔ (checklist below)
```

## Post-test state restore

- [ ] Temporary test triggers/nodes removed
- [ ] Throwaway test workflows unpublished, then deleted through the n8n
      MCP server (with the user's OK) unless they want them kept
- [ ] `[TEST]` rows written to data tables during tests cleaned up (in
      n8n's Data tables, or by the workflow's own delete step)
- [ ] Live workflow's published state matches what the user expects
- [ ] After a change to a live workflow: the ORIGINAL production URL
      re-verified with a fire (the path is unchanged, so the old URL must
      still respond)
- [ ] User told which `[TEST]` artifacts (emails, records) to expect and
      discard
