conductor/TESTING.md

542 lines
20 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Conductor Manual Testing
This document is the durable manual-testing checklist for Conductor. Automated
test results belong in `BASELINE.md`; this file covers behavior that needs a
person to verify in the running application.
Do not mark a workflow accepted from automated coverage alone. Record the date,
tester, environment, and any observations in the result block for that workflow.
## Status Summary
| Workflow | Status |
|---|---|
| Slice 1 components and editor synchronization | Accepted 2026-07-18 |
| Anonymous REST action authoring and referenced deletion | Accepted 2026-07-19 |
| Visual Button `onClick` assignment | Accepted 2026-07-19 |
| Guided request-input query insertion | Accepted 2026-07-20 |
| Complete request-input execution | Accepted 2026-07-28 |
| Response bindings and variable authoring | Accepted 2026-07-29 |
| Page-load actions | Accepted 2026-07-29 |
| Final Slice 2 end-to-end acceptance | Pending |
## Test Environment Setup
### 1. Start Docker Desktop
1. Start Docker Desktop on the host computer.
2. If using WSL, open Docker Desktop settings.
3. Select **Resources**, then **WSL Integration**.
4. Enable integration for the WSL distribution containing this repository.
5. Apply the changes and restart Docker Desktop if prompted.
6. From the repository root, verify that Docker is available:
```bash
docker info
```
Expected result: the command displays client and server information without a
connection or WSL-integration error.
### 2. Start Conductor
From the repository root, run:
```bash
docker compose up --build
```
Leave this terminal running. In another terminal, run:
```bash
docker compose ps
curl http://localhost:4000/api/health
```
Expected results:
- The `frontend` and `backend` services are running.
- The health request returns JSON containing `"status":"ok"`.
- `http://localhost:3000` opens the Conductor application.
If startup fails, capture `docker compose ps` and:
```bash
docker compose logs backend frontend
```
Do not continue until both services and the health endpoint work.
## Canonical JSON and Runtime State
Several workflows ask you to inspect canonical JSON:
1. Select **JSON Editor** in the application navigation.
2. Locate the relevant section under `project`, such as `actions`, `bindings`,
or `variables`.
3. Do not add runtime-only fields merely to test them.
Runtime values are expected to exist only while Preview is running. Canonical
JSON must not gain fields containing:
- current input or selection values;
- loading flags;
- action responses;
- action or component errors;
- updated runtime variable values.
Configured component defaults and declared variable defaults are canonical and
are expected to remain in JSON.
## Test 1: Request-Input Authoring and Execution
Purpose: verify that a current component or variable value can be inserted into
an executed REST request template without using compatibility-only `inputMap`.
Partial status: adding the `item` query row and guided component insertion was
confirmed on 2026-07-20. The remaining steps still need acceptance.
### A. Create the test project
1. Open `http://localhost:3000`.
2. Create a new project, or open a disposable test project.
3. In **Visual Editor**, add a **Text Input**.
4. Select the Text Input and give it a unique component name such as
`itemInput`.
5. Add a **Button** and name it `lookupButton`.
6. Optionally add a **JSON Viewer** named `requestResult`; it will be useful in
the response-binding test.
7. Open **Actions & Bindings**.
8. Select **Add REST action**.
9. Configure:
- Name: `Look up item`
- Method: `GET`
- URL: `https://httpbin.org/anything`
- Authentication: confirm it remains **Anonymous**
10. Finish the action edit, then return to **Visual Editor**.
11. Select `lookupButton` and assign `Look up item` as its `onClick` action.
Expected result: JSON contains a Button event referencing the action ID, but no
`inputMap` is created.
### B. Add the guided query reference
1. Return to **Actions & Bindings**.
2. Edit `Look up item`.
3. Find **Query parameters** and select **Add row**.
4. Enter `item` in the key field. The value may initially remain blank.
5. Find **Request value reference** in the same action editor.
6. Select `itemInput (TextInput)` as the source.
7. Select `Query: item` as the destination.
8. Select **Insert reference**.
9. Return to the Query parameters section.
Expected result: the value of `item` is:
```text
{{components.itemInput.value}}
```
10. Open **JSON Editor** and find the action's `queryParameters`.
Expected canonical fragment:
```json
"queryParameters": {
"item": "{{components.itemInput.value}}"
}
```
11. Search the document for `inputMap`.
Expected result: no `ComponentEvent.inputMap` was added.
12. Return to the action editor and inspect the Request value reference
destination choices.
Expected result: URL, header, query, and body destinations may be offered. Path
parameters are not offered.
### C. Execute the component reference
1. Open **Preview**.
2. Enter a recognizable value in the Text Input, for example:
```text
manual-test-742
```
3. Select the Button once.
4. Wait for the request to complete.
5. Inspect the response or the browser Network panel. For the httpbin endpoint,
the response body should echo the request URL or query arguments.
Expected result: the outgoing URL contains an encoded query parameter equivalent
to:
```text
?item=manual-test-742
```
6. While still in the same project, open **JSON Editor** again.
Expected results:
- The template remains `{{components.itemInput.value}}`; it was not replaced by
`manual-test-742`.
- No loading, response, error, or current component value was added to JSON.
### D. Verify raw template editing still works
1. Edit `Look up item` again.
2. Add a raw URL suffix, header value, or second query parameter containing
literal text or a supported template.
3. Add a body template temporarily if desired. A GET body need not be executed;
this step checks that the raw editor remains usable.
4. Confirm the raw value synchronizes to JSON.
5. Confirm the previously inserted `item` query reference is unchanged.
Expected result: guided insertion does not disable or overwrite subsequent raw
URL, header, query, or body editing.
### E. Verify a variable request reference
1. In **Actions & Bindings**, create a variable:
- Name: `testRegion`
- Type: `string`
- Default value: `east`
2. Edit `Look up item`.
3. Add a query parameter named `region`.
4. In **Request value reference**, choose variable `testRegion`.
5. Choose `Query: region`, then select **Insert reference**.
6. Confirm JSON contains:
```text
{{variables.testRegion}}
```
7. Execute the Button in Preview.
Expected result: the outgoing query includes `region=east`, while canonical JSON
retains the variable declaration and default rather than a runtime copy.
### Request-input result
- [x] Docker services and health endpoint passed.
- [x] Guided `item` query-reference insertion looked correct (2026-07-20).
- [x] Canonical component template and absence of `inputMap` confirmed.
- [x] Path parameters confirmed absent from guided destinations.
- [x] Runtime component value appeared in the outgoing request.
- [x] Runtime state remained absent from canonical JSON.
- [x] Raw template editing regression passed.
- [x] Variable reference resolved in an executed request.
Tester/date: User, 2026-07-28
Notes or defects: All request-input checks passed. The tester initially looked
below the query-parameter editor for Request value reference; the control is at
the top of the expanded Request parameters section. No product defect found.
## Test 2: Response Bindings and Variables
Purpose: verify visual CRUD for canonical `project.bindings` and
`project.variables`, response delivery in Preview, legacy compatibility, and
runtime-state separation.
### A. Test typed variable declarations
1. Open the test project in **Actions & Bindings**.
2. In **Variables**, select **Add variable**.
3. Create `statusText`:
- Type: `string`
- Default: `Not run`
- Description: `Latest manual test status`
4. Create `retryCount` with type `number` and default `2`.
5. Create `enabled` with type `boolean` and default `true`.
6. Create `metadata` with type `object` and default:
```json
{"source":"manual"}
```
7. Create `items` with type `array` and default:
```json
[]
```
8. Inspect **JSON Editor**.
Expected result: `project.variables` contains typed declarations. Number and
boolean defaults are JSON numbers and booleans, not quoted strings; object and
array defaults have the correct JSON shapes.
9. Edit `metadata`, replace its default with malformed JSON, and try to save.
Expected result: an actionable validation message appears and the invalid draft
does not replace the canonical variable value.
10. Correct the JSON and save it.
Expected result: the corrected default updates canonical JSON.
### B. Create and execute a component response binding
1. Ensure the project contains `Look up item` and a JSON Viewer named
`requestResult`.
2. Ensure `lookupButton` runs `Look up item` on click.
3. In **Actions & Bindings**, select **Add response binding**.
4. Select `Look up item` as the REST action response source.
5. Set Response path to `body` to map the upstream body, or leave it blank to
map the complete normalized response envelope.
6. Select `requestResult (JsonViewer.value)` as the target.
7. Inspect **JSON Editor**.
Expected results:
- The new record is in top-level `project.bindings`.
- Its source begins `actions.<actionId>.response`.
- Its target is `components.requestResult.value`.
- Its trigger is exactly `onSuccess`.
- No `action.responseMapping` was added.
8. Open **Preview**, enter a value in `itemInput`, and select the Button.
Expected result: after a successful request, the JSON Viewer displays the mapped
response value.
### C. Create and execute a variable response binding
1. Return to **Actions & Bindings**.
2. Add another response binding.
3. Select `Look up item` as the source action.
4. Use a response path appropriate to the httpbin response, such as `body.url`.
5. Select `statusText (variable)` as the target.
6. Confirm the new binding uses `onSuccess`.
7. Execute the Button successfully in Preview.
8. Execute any request that consumes `{{variables.statusText}}`, or otherwise
observe its downstream behavior.
Expected results:
- The runtime variable receives the mapped response value.
- `project.variables.statusText.defaultValue` remains `Not run` in canonical
JSON.
- No runtime variable value is saved into canonical JSON.
### D. Edit and delete bindings
1. Edit the component response binding.
2. Change its response path, save/finish the edit, and confirm JSON updates.
3. Change its supported target and confirm JSON updates.
4. Delete that binding and accept the confirmation.
Expected results:
- Edits update only the selected top-level binding.
- Deletion removes only that binding.
- **Add response binding** remains enabled afterward.
### E. Verify target restrictions
1. Add or select an unsupported input component such as Text Input.
2. Start adding or editing a response binding and inspect Target choices.
Expected result: unsupported targets such as `TextInput.value` are not offered.
3. If two components have the same name, inspect the Target choices again.
Expected result: the ambiguous duplicate component name is not offered as a new
target, and existing ambiguous bindings receive a diagnostic.
### F. Verify variable reference warnings
1. Ensure `statusText` is referenced by a response binding or request template.
2. Select **Delete** for `statusText`.
Expected result: the confirmation identifies the binding or action references
that would become unresolved.
3. Cancel and confirm the variable remains.
4. Repeat deletion and accept it only in a disposable project.
Expected result: diagnostics identify the now-unresolved references; unrelated
variables and bindings remain unchanged.
### G. Verify legacy `onClick` compatibility
This test needs a pre-existing legacy action-response binding authored through
JSON. Do not use the visual editor to create a new legacy binding.
1. In a disposable project, use **JSON Editor** to add an action-response binding
with `"trigger": "onClick"` and apply the valid JSON.
2. Open **Actions & Bindings** and inspect the binding.
Expected result: it is displayed with an informational legacy diagnostic and can
still execute for a supported component target.
3. Edit the legacy binding.
Expected result: `onClick` is shown only because this record is already legacy.
4. Change the trigger to **On success**.
Expected results:
- Canonical JSON changes to `"trigger": "onSuccess"`.
- The editor no longer offers `onClick` for that migrated record.
- A newly added response binding never offers `onClick`.
### H. Verify failure and ephemeral state
1. Temporarily change the action URL to a URL that will fail or return an error.
2. Execute the Button in Preview.
Expected results:
- The UI exposes a usable loading state followed by an error state.
- `onSuccess` response bindings do not apply a failed response.
- Loading flags, errors, and responses do not appear in canonical JSON.
3. Restore the valid action URL.
### I. Verify save and reload
1. Save the project.
2. Reload it from the project picker.
3. Reopen **Actions & Bindings**.
4. Confirm actions, Button events, request templates, response bindings, and
variable declarations/defaults are preserved.
5. Open **Preview** and execute the successful workflow again.
Expected result: configured behavior survives persistence, while previous
runtime responses, errors, loading state, input values, and modified runtime
variables do not.
### Response-binding and variable result
- [x] Typed variable declarations/defaults passed.
- [x] Invalid variable draft remained outside canonical JSON.
- [x] Component response binding executed with `onSuccess`.
- [x] Variable response binding executed without changing its canonical default.
- [x] Binding edit and delete passed.
- [x] Unsupported and ambiguous targets were excluded.
- [x] Referenced-variable deletion warning passed.
- [x] Legacy `onClick` compatibility and one-way migration passed.
- [x] Failure and ephemeral-state checks passed.
- [x] Save/reload persistence passed.
Tester/date: User, 2026-07-29
Notes or defects: Typed declarations, invalid-draft isolation, component onSuccess mapping, and variable onSuccess mapping passed. The two-request variable check proved runtime statusText changed while its canonical Not run default remained intact. Boolean true authoring initially failed and was fixed with an explicit selector. The original httpbin.org endpoint intermittently returned 503; onSuccess correctly withheld those failures. The verified httpbingo.org endpoint produced successful binding results. Binding edit and selected deletion also passed, with the other binding preserved and Add response binding re-enabled. The tester requested a later Actions and Bindings UI revisit because records read as a continuous text stream rather than distinct scannable items. Unsupported TextInput targets and ambiguous duplicate component-name targets were also excluded as expected. Referenced-variable warning, cancellation, accepted deletion, and unresolved-reference diagnostics also passed without changing unrelated records. Legacy onClick execution, informational diagnostics, and one-way migration to onSuccess also passed; new records did not offer onClick. Failure and ephemeral-state checks passed after fixing the clipped Button error: the complete 503 message is readable, onSuccess withheld the failed response, canonical state remained clean, and a later success cleared the stale error. Save/reload preserved canonical configuration, reset all prior runtime state, and the successful workflow executed after reload. Complete response-binding and variable manual acceptance passed.
## Test 3: Page-Load Actions
Status: accepted by the user on 2026-07-29 after the rebuilt Docker Compose workflow passed.
Execute this workflow against the rebuilt Docker Compose application before
declaring the page-load increment or Slice 2 accepted:
1. Create an anonymous REST action that returns Dropdown options or Table rows.
2. Assign the existing action to the page's visual `onLoad` configuration.
3. Add an `onSuccess` response binding to the Dropdown or Table.
4. Inspect JSON and confirm only canonical page event, action, and binding
configuration was added.
5. Enter Preview and verify the action executes once when Preview initializes.
6. Verify loading, successful population, empty results, and failure behavior.
7. Leave and re-enter Preview and verify initialization is predictable and does
not write runtime values into canonical JSON.
8. Save and reload the project and repeat the test.
9. Delete the referenced action after accepting its reference warning, or use JSON Editor to create a dangling reference, and verify the Visual Editor shows an actionable missing-action diagnostic.
10. Repeat with an empty successful response and confirm the target presents a usable empty state rather than stale prior data.
### Page-load result
- [x] Visual `onLoad` assignment passed.
- [x] Initial successful population passed.
- [x] Loading, empty, and failure states passed.
- [x] Runtime state remained ephemeral.
- [x] Save/reload passed.
- [x] Missing-reference diagnostics passed.
Tester/date: User, 2026-07-29
Notes or defects: Test 3 passed. The populated Table exposed a non-blocking Preview layout limitation: the white page/canvas background retains its configured or minimum size instead of growing with runtime-rendered Table output. TASKS.md now tracks content-aware Preview sizing. It also tracks Table pagination as a separate design item that requires discussion of client-side versus server-side pagination before implementation.
Automated checkpoint: 4 focused suites / 9 tests, 18 full frontend suites / 486 tests, frontend production build, and the 13 / 2 / 2 schema matrix passed under Node 20/npm 10 on 2026-07-29. Docker Compose rebuilt, both services started, backend health passed, and the frontend responded on port 3000. Automation and smoke checks do not mark this workflow accepted.
## Final Slice 2 Acceptance
Run this only after Tests 13 pass and component-deletion diagnostics are
complete.
### Workflow launcher
1. Build a small form with at least one input, a Button, and a response display.
2. Configure an anonymous action, request reference, Button event, and response
binding entirely through visual controls.
3. Execute it successfully in Preview.
4. Trigger a failure and confirm usable error behavior.
5. Save, reload, and execute it again.
### Dependent data
1. Populate a Dropdown through a page-load action and response binding.
2. Select a Dropdown value.
3. Use that selection in a second Button-triggered request.
4. Map the second response to another component or variable.
5. Confirm loading, empty, successful, and failed behavior.
### Read-only dashboard
1. Populate a Table through a page-load action.
2. Select a row.
3. Display details in a supported response target where the current Slice 2
model allows it.
4. Confirm refresh and failure behavior.
### Canonical and persistence regression
1. Inspect JSON after all configuration is complete.
2. Confirm there is no new `inputMap` and no `action.responseMapping` behavior.
3. Confirm no credentials or secrets were introduced.
4. Confirm runtime values, loading, responses, and errors are absent.
5. Save and reload the project.
6. Confirm Visual Editor, JSON Editor, Actions & Bindings, and Preview agree.
### Final result
- [ ] Request-input workflow accepted.
- [ ] Response-binding and variable workflow accepted.
- [ ] Page-load workflow accepted.
- [ ] Workflow launcher passed without routine JSON editing.
- [ ] Dependent-data workflow passed.
- [ ] Read-only dashboard workflow passed.
- [ ] Failure handling passed.
- [ ] Canonical synchronization and save/reload passed.
Tester/date:
Notes or defects:
## Recording Results
After a manual workflow is completed:
1. Update its checkboxes in this document.
2. Record the tester, date, environment, and any deviations.
3. Record manual acceptance separately from automated coverage in:
- `CODEX.md`
- `SLICE2.md`
- `BASELINE.md`
4. Do not mark a broader workflow accepted when only one checkpoint passed.
5. File unresolved defects in `TASKS.md` with enough detail to reproduce them.