"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.AuthoringGuideResources = void 0;
const OVERVIEW_URI = 'mabl-author://overview';
const SELECTOR_FIELDS_URI = 'mabl-author://selector-fields';
const SAVE_TOOL_MECHANICS_URI = 'mabl-author://save-tool-mechanics';
const AUTHORING_PATTERNS_URI = 'mabl-author://authoring-patterns';
const OVERVIEW_CONTENT = `# Hand-authoring mabl tests

You are writing test JSON yourself instead of having the cloud agent author
it. This is the right path when you know what the flow should look like and
want a deterministic test built from rules rather than from a trainer's live
page rendering. You pay for that by not having live xpath / bounding_*
fingerprints — you have to lean on \`locator\` + \`description\` and the
visual resolver to find elements at run time.

## Entry-point decision

| You want…                                                                  | Use                                                                              |
| -------------------------------------------------------------------------- | -------------------------------------------------------------------------------- |
| The cloud agent to render the page and capture trainer-quality selectors   | \`create_mabl_test_cloud\`                                                       |
| To record on a real page yourself                                          | The mabl trainer (record in the mabl web app)                                    |
| To write or edit the flow JSON directly because you know the structure     | This guide — \`mabl_validate\` + \`mabl_save_flow_steps\` / \`mabl_save_test_steps\` |

If you don't have a \`test_id\` + \`flow_id\` to overwrite yet, see
\`mabl-author://save-tool-mechanics\` for the cheapest scaffolding path.

---

## Test structure

Before writing individual steps, think about how to group them. A sequence of
clicks that adds an item to a cart, or eight field-fills plus a submit click
that completes a form, is one conceptual action — not eight unrelated atoms.
Wrap conceptual actions in \`StepGroup\` with an \`intent.description\` that
names the goal in plain language. Failure analysis, run summaries, and future
readers all consume that intent text; without it they only see the mechanics.

See \`mabl-author://authoring-patterns\` for the full rationale, examples,
and the step-group vs reusable-flow split.

---

## The findTarget shape decision

\`findTarget\` accepts four shapes. Pick by what you have:

| You have…                                                          | Use                                                                            |
| ------------------------------------------------------------------ | ------------------------------------------------------------------------------ |
| A Playwright locator and/or a natural-language description         | **Wrapped, new-shape**: \`{selector: {uuid, locator, description}}\`           |
| Trainer-captured fingerprint with \`xpath\` + attribute fields     | **Wrapped, trainer-shape**: \`{selector: {uuid, xpath, id, class_name, ...}}\` |
| Only a CSS query, no other context                                 | **Custom CSS**: \`{css_query: "..."}\`                                         |
| Only an XPath, no other context                                    | **Custom XPath**: \`{xpath: "..."}\`                                           |

The **wrapped** form (\`findTarget.selector.*\`) is canonical. The runtime
reads new-shape fields from \`findTarget.selector.locator\` and
\`findTarget.selector.description\` — not from a flat \`findTarget.locator\`.

Inside the wrapped form, the schema enforces a clean split:

- **Pure new-shape:** \`{uuid, locator, description}\` (and optionally
  \`find_prompt\`). No attribute fields. Resolved by Playwright locator
  first, then the description-driven visual resolver.
- **Trainer-shape:** must include \`xpath\` plus any attribute fields
  (\`id\`, \`class_name\`, \`name\`, \`tag_name\`, \`data_*\`, \`aria_*\`,
  \`bounding_*\`, etc.). \`xpath\` is the structural anchor for the legacy
  attribute-scoring resolver.
- **Blocked middle ground:** attribute fields populated without \`xpath\`.
  The validator rejects this — there's no resolver path it could take.

**If you're authoring blind (no browser session), stay in pure new-shape.**
Don't paste in \`id\` or \`class_name\` values you copied from source code
without also recording the corresponding \`xpath\`. The schema will reject
it, and even if it didn't, the legacy resolver has nothing to anchor on.

### Worked example: a single Click step

\`\`\`json
{
  "Click": {
    "find": {
      "findType": "find_one",
      "findTarget": {
        "selector": {
          "uuid": "login-submit",
          "locator": "button:has-text(\\"Log in\\")",
          "description": "Primary 'Log in' submit button on the login form"
        }
      }
    },
    "description": "Submit the login form"
  }
}
\`\`\`

For \`locator\` syntax, \`description\` good/bad examples, and \`uuid\`
reuse semantics see \`mabl-author://selector-fields\`.

## Variable conventions

Test variables substitute at run time. Reference them inside string fields
with \`{{@...}}\`.

Common examples (not exhaustive — workspaces can define more):

| Variable                          | Source                                              |
| --------------------------------- | --------------------------------------------------- |
| \`{{@app.url}}\`                  | Environment URL on the application                  |
| \`{{@app.defaults.username}}\`    | \`credentialsId\` passed to \`run_mabl_test_cloud\` |
| \`{{@app.defaults.password}}\`    | \`credentialsId\` passed to \`run_mabl_test_cloud\` |

Always use \`{{@app.defaults.username}}\` / \`{{@app.defaults.password}}\`
for credential references. Other namespaces such as
\`{{@web.defaults.credentials.username}}\` do not exist — the substitution
fails silently and the placeholder string is sent as-is, which the login
server typically rejects as "invalid email format."

To verify what variable names a specific workspace uses, call
\`get_mabl_tests\` on a passing test in that workspace and read its
\`annotatedStepDescriptions\` — it reveals the \`{{@...}}\` patterns the
workspace actually uses.

## The validate -> save -> run loop

\`\`\`
1. mabl_get_schema_resource(uri: "mabl-schema://step/<Type>")        # per-step shape
2. Compose steps[] as plain objects
3. mabl_validate(steps, testType: "browser")                         # pure structural check
4. mabl_save_flow_steps(flow_id, test_id, mode: "whole", steps[])    # or mabl_save_test_steps
5. run_mabl_test_cloud(testId, workspaceId, envId, appId,
                       credentialsId, browsers: ["chrome"])
6. get_latest_test_runs(testId)                                      # poll until terminal
7. analyze_failure(runId, testOrPlan: "test")                        # on failure
\`\`\`

For which save tool to use, when \`test_id\` is required on a save, and
what the common save-error codes mean, see
\`mabl-author://save-tool-mechanics\`.

## Common failures and what they tell you

| Symptom                                                                          | Likely cause                                                                                | Action                                                                                                                       |
| -------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
| \`mabl_validate\` rejects with \`xpath\` required                                | Attribute fields (\`id\`, \`class_name\`, etc.) mixed into a wrapped selector without \`xpath\` | Add \`xpath\`, or remove the attribute fields to keep it pure new-shape                                                      |
| \`mabl_validate\` rejects "at least one of xpath/locator/description"            | Empty descriptor                                                                            | Add a \`locator\` and/or \`description\`                                                                                     |
| Runtime "Did not find element expected to be present" on the first step          | Locator didn't resolve and the description-driven visual fallback didn't engage             | Verify the locator with a quick page inspection; tighten or simplify; ensure your account is on a runtime that supports the new-shape resolver |
| Runtime "invalid email format" during sign-in                                    | Credential variable didn't resolve — the placeholder string was sent as-is                  | Use \`{{@app.defaults.username}}\` / \`{{@app.defaults.password}}\`; verify \`credentialsId\` was passed to \`run_mabl_test_cloud\` |
| Save returns \`wrong_authoring_boundary\` or \`shared_flow_requires_acknowledgement\` | Reusable-flow handling                                                                  | See \`mabl-author://save-tool-mechanics\`                                                                                    |

When the symptom doesn't match anything above, fall back to
\`analyze_failure(runId, testOrPlan: "test")\` for the AI failure
analysis — it has access to the run log and screenshots, which this
guide does not.

## See also

- \`mabl-author://authoring-patterns\` — patterns for structuring a test
  well, starting with step grouping
- \`mabl-author://selector-fields\` — \`locator\` / \`description\` /
  \`uuid\` field details
- \`mabl-author://save-tool-mechanics\` — when to use which save tool,
  scaffolding tip, save-error codes
- \`mabl_get_schema_resource\` — progressive-disclosure JSON Schema for
  the test envelope, step index, or a single step type
- \`mabl_list_examples\` / \`mabl_get_example\` — worked example bodies
  per step type
- \`mabl_get_flow_steps\` / \`mabl_get_test_steps\` — read existing flows
  or tests as a starting point
`;
const SELECTOR_FIELDS_CONTENT = `# Selector field reference

Notes on the three fields that drive the new-shape resolver inside a
wrapped \`findTarget.selector\` descriptor.

## \`locator\`

A Playwright locator string. Accepts:

- Bare CSS: \`"button.primary"\`
- Explicit-prefix: \`"xpath=//button"\`, \`"css=button"\`
- Auto-detected XPath: \`"//button"\`
- Semantic primitives: \`"role=button[name=\\"Save\\"]"\`, \`"text=Submit"\`,
  \`"id=submit-btn"\`
- Chains via \`>>\`: \`"foo >> nth=2"\`
- Pseudo-classes: \`:has-text("x")\`, \`:visible\`, \`:nth-match\`

Variable references (standard \`{{@...}}\` syntax) are resolved before
the locator hits Playwright.

Pick the most stable identifier available: data-test-id > role= > id >
unique CSS class > generic XPath. Must resolve to exactly one element;
express narrowing inside the locator string rather than across multiple
find calls.

## \`description\`

A natural-language statement of what the element *is* and *does*. Drives
the description-driven visual resolver when the locator fails.

Describe what the element is and does, not how it looks:

- Good: "primary submit button on the checkout form"
- Good: "search input above the tests list that filters as the user types"
- Bad: "blue button on the right"
- Bad: "the element at coordinates 684, 507"

The description should still make sense if the page redesigns its colors
or spacing.

## \`uuid\`

A stable identifier you generate. The runtime keys captured fingerprints
(heal attempts, learned timeouts, confidence scores) to it.

**Reuse the same uuid for the same logical element across re-authors.**
Re-authoring with a new uuid loses the accumulated heal data and resets
confidence.

For pure-new-shape descriptors that have never been captured, any unique
string works (\`"login-email"\`, \`"tests-search-input"\`, etc.). Don't
use a real UUID format unless you have one from a prior capture.

## See also

- \`mabl_get_schema_resource(uri: "mabl-schema://step/<Type>")\` — full
  per-step JSON Schema
- \`mabl_get_example(id: ...)\` — worked example bodies
`;
const SAVE_TOOL_MECHANICS_CONTENT = `# Save tool mechanics

The mechanics that matter when picking between \`mabl_save_flow_steps\`
and \`mabl_save_test_steps\`, and what their failure modes mean.
Per-parameter docs live in the tools' input schemas — this guide covers
what those don't.

## \`mabl_validate\` is structural-only

\`mabl_validate\` is pure logic — it does not touch the API and does not
check whether locators resolve on a live page. A green validate
guarantees \`mabl_save_*\` will accept the payload at the structural
layer; it does *not* guarantee the run passes.

## \`mabl_save_flow_steps\`: single-flow edits

Use for edits scoped to one flow.

For **structural (non-reusable) flows**, pass \`test_id\` so the test
rebinds to the new flow variant in the same call. Without it, the next
test run still executes the old variant.

For **reusable flows** (referenced by multiple tests),
\`acknowledge_shared: true\` is required. Without it the save returns
\`shared_flow_requires_acknowledgement\` plus a sample of impacted tests
so you can review blast radius before re-saving.

## \`mabl_save_test_steps\`: cross-flow edits

Use for edits that span multiple flows on a test.

\`mode: "whole"\` replaces the steps of one or more flows wholesale.
\`mode: "edits"\` applies a batch of replace / insert_after / delete /
move ops to the current state. Use "edits" for surgical changes on long
flows; "whole" for rewrites of flows under ~50 steps.

Edits that land on a step inside a reusable flow are refused with
\`wrong_authoring_boundary\` plus a redirect hint pointing at
\`mabl_save_flow_steps\`. The refusal is on purpose — reusable flows have
higher concurrent-modification risk and should be saved through the
single-flow path with explicit acknowledgement.

## Scaffolding when you don't have a test_id

If you don't have a \`test_id\` + \`flow_id\` to overwrite yet, the
cheapest scaffold is a minimal \`create_mabl_test_cloud\` call with an
intent of \`"scaffold only — just open the URL."\` Wait for
\`sessionStatus: "completed"\` (~30-60s), then pull \`flow_id\` via
\`mabl_get_test_steps\` and overwrite with your steps via
\`mabl_save_flow_steps\`.

The scaffold cost (one cloud authoring session) is bounded — the agent
will do the minimum and return.

## Common save errors

| Error code                                  | Meaning                                                                | Action                                                                                                       |
| ------------------------------------------- | ---------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------ |
| \`pre_validation_failed\`                   | Steps failed \`mabl_validate\` (which save_* runs internally as a gate) | Call \`mabl_validate\` directly to see the suggestions                                                       |
| \`wrong_authoring_boundary\`                | Edit landed inside a reusable flow via \`mabl_save_test_steps\`        | Switch to \`mabl_save_flow_steps\` with \`acknowledge_shared: true\`                                         |
| \`shared_flow_requires_acknowledgement\`    | Saving a reusable flow without \`acknowledge_shared: true\`            | Review impacted-test sample in the response, then re-save with \`acknowledge_shared: true\`                  |
`;
const AUTHORING_PATTERNS_CONTENT = `# Authoring patterns

Reference for writing tests that are clear to read and easy to debug. Each
pattern is grounded in what a downstream consumer — a future author, the
failure-analysis tool, an agent reading the run — needs from the test.

## Group conceptually related steps with intents

A test's *shape* should mirror its goal. The 4 clicks that add an item to a
cart, the 8 fields that fill out a checkout form, the login sequence — each
is one conceptual action, not a list of unrelated atoms. Wrap conceptual
actions in \`StepGroup\` and label them with \`intent.description\`.

### Why

- **Readability.** A reader scanning the test sees the goals (\"Log in\",
  \"Add item to cart\", \"Submit checkout\") before drilling into mechanics.
- **Run-time analysis.** mabl's failure analysis and result reporting consume
  \`intent.description\` to summarize what the test was trying to do at the
  point of failure. Without intents, the analysis only sees
  \"Click on .btn-submit\" and has to infer the purpose.
- **Editability.** Grouped steps move and rename together. A redesign that
  changes *how* you add an item shouldn't ripple through unrelated step
  indices in the test.

### What to group

Group a sequence of steps when:

- They serve one user-visible goal you could describe in one sentence.
- They appear together — interleaving them with unrelated assertions or
  navigation would be unnatural.

Don't group:

- A single step. The wrapper adds noise without earning its keep.
- Steps that span two unrelated goals (e.g. \"Log in\" and \"Add to cart\"
  in the same group). Split into two groups, each with its own intent.

### Shape

\`\`\`json
{
  \"StepGroup\": {
    \"intent\": {
      \"description\": \"Add a Margherita pizza to the cart\"
    },
    \"steps\": [
      { \"Click\": { \"find\": { ... }, \"description\": \"Open the menu\" } },
      { \"Click\": { \"find\": { ... }, \"description\": \"Pick Margherita pizza\" } },
      { \"Click\": { \"find\": { ... }, \"description\": \"Choose size large\" } },
      { \"Click\": { \"find\": { ... }, \"description\": \"Add to cart\" } }
    ]
  }
}
\`\`\`

The group's \`intent.description\` is the **what** the user is trying to
accomplish; each child step's \`description\` is the **how**. \`StepGroup\`
is recursive — groups can nest, but only do that when the inner sub-goal is
itself worth naming.

### Step group vs reusable flow

| Use…                                            | When…                                                                                                                                    |
| ----------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| Inline \`StepGroup\`                            | The action only appears in this one test                                                                                                 |
| Reusable flow (invoked via \`EvaluateFlow\`)    | The same sequence appears in 3+ tests — extract it as a named flow that all those tests reference                                        |

Reusable flows carry their own purpose at the flow level (the flow's
\`description\`). The \`StepGroup\` pattern brings the same readability win
to non-reusable sub-tasks without forcing a flow extraction.

## See also

- \`mabl-author://overview\` — entry point: shape decision, variable
  conventions, validate -> save -> run loop, failure triage
- \`mabl-author://selector-fields\` — \`locator\` / \`description\` /
  \`uuid\` details for the steps inside a group
- \`mabl_get_schema_resource(uri: \"mabl-schema://step/StepGroup\")\` —
  full StepGroup schema
- \`mabl_get_schema_resource(uri: \"mabl-schema://step/EvaluateFlow\")\` —
  full EvaluateFlow schema (the reusable-flow invocation step)
`;
const RESOURCES = [
    {
        uri: OVERVIEW_URI,
        description: 'Entry point: when to hand-author, the findTarget shape decision, variable conventions, the validate -> save -> run loop, and a failure-triage table.',
        content: OVERVIEW_CONTENT,
    },
    {
        uri: SELECTOR_FIELDS_URI,
        description: 'Field reference for `locator`, `description`, and `uuid` inside a wrapped findTarget.selector.',
        content: SELECTOR_FIELDS_CONTENT,
    },
    {
        uri: SAVE_TOOL_MECHANICS_URI,
        description: 'When to use mabl_save_flow_steps vs mabl_save_test_steps, the scaffolding shortcut, and what each save-error code means.',
        content: SAVE_TOOL_MECHANICS_CONTENT,
    },
    {
        uri: AUTHORING_PATTERNS_URI,
        description: 'Patterns for structuring a test well, starting with grouping conceptually related steps using StepGroup + intent.description.',
        content: AUTHORING_PATTERNS_CONTENT,
    },
];
const RESOURCE_BY_URI = new Map(RESOURCES.map((resource) => [resource.uri, resource]));
class AuthoringGuideResources {
    resolve(uri) {
        return RESOURCE_BY_URI.get(uri);
    }
    list() {
        return RESOURCES.map(({ uri, description }) => ({ uri, description }));
    }
}
exports.AuthoringGuideResources = AuthoringGuideResources;
