| name | morph-autotest |
| description | Autonomous multi-session browser testing engine with test synthesis, code-informed subflow planning, self-healing retry, run history persistence, viewport testing, and CI/CD integration. Uses `morph_browser_test_url` for browser automation. |
Morph Autotest
Runs browser validation as short, code-informed subflow sessions using morph_browser_test_url. It reads code first when code is available and returns markdown that helps the next agent decide what to inspect, fix, or rerun.
Skill Architecture
This skill is organized as a main SKILL.md plus focused sub-docs:
| Sub-doc | Phase | Scope |
|---|
synthesis.md | 1 | PRD → Subflow[] plan, deduplication, code file tagging |
execution.md | 2 | Tool wrapper, RunManifest, sequential loop, retry, auth decision tree |
healing.md | 3 | Safe healing protocol, task rephrasing, HealingLog |
api-testing.md | 4 | Network log inference, Zod structured assertions |
persistence.md | 5 | Run history, auth profiles, flaky signatures, baseline system |
ci-cd.md | 6 | Headless mode, JSON report, GitHub Actions workflow |
viewport.md | 7 | Viewport subflow generation, responsive grouping |
Purpose
Use this skill when the goal is to validate a real user flow, a changed feature, or a risky surface with browser automation while also understanding how the code is wired.
This skill is for verification and fixing decisions, not demo-style validation or vague exploratory theater.
Non-negotiable rules:
- The slash command is only the launcher and question-asking orchestrator.
- All reasoning, target classification, preflight checks, mode selection, subflow splitting, code analysis, failure diagnosis, and markdown reporting live in this skill.
- The final output is markdown, not a raw data dump.
- The diagnosis must combine browser evidence and code evidence.
Product Contract
Slash Command Responsibilities
The slash command must:
- Start an interactive question flow.
- Collect the minimum required context.
- Stop at the preflight gate if any required input is missing.
- Hand the normalized context to
morph-autotest.
- Never duplicate planning or diagnosis logic from this skill.
The slash command must not:
- expose technical tuning parameters to the user,
- implement its own session splitting,
- decide tool routing separately from this skill,
- produce its own independent report format.
Skill Responsibilities
morph-autotest must:
- Classify the target as
public url or local/private.
- Normalize the user intent into a testing brief.
- Enforce the preflight guard.
- Read code first when code is available.
- Build a per-subflow execution plan.
- Route execution to
morph_browser_test_url after preflight passes.
- Analyze failures using browser evidence plus code search.
- Produce a markdown report with PRD alignment and agent next actions.
[DONE:1]
Minimum Input Model
The slash command should collect these inputs through conversation, without explicit parameters:
target
- Public URL, or
- A local/private target that will fail preflight until a public URL exists, such as a tunnel or staging URL.
focus
- Feature, page, component area, or bugfix area to prioritize.
expected outcome
- What should happen when the flow succeeds.
risk area
- What is most likely to break, what changed recently, or what should receive extra scrutiny.
- If the user does not know, infer a provisional risk area from the PRD, target route, or changed feature, then mark that inference explicitly.
auth context
- Only if the flow is gated.
- Phase-2 auth strategy is explicit:
profile -> cookies -> username/password -> blocked.
profileId / profileAlias can now be used when a local registry entry exists and sticky API key affinity can be resolved.
- Prefer profile-first for recurring protected runs, then cookies, then username/password.
- Collect login URL, username/email, password or token handling instructions, tenant/workspace selection, MFA limitations, any safe test-account caveats, whether reusable cookies already exist, and whether a Morph browser profile alias/id already exists for the environment.
PRD markdown
- Preferred source of truth.
- In interactive mode: if the user does not already have one, draft a temporary markdown baseline from the conversation. Execution cannot start until confirmed.
- In headless/CLI mode: pass via
--prd ./path/to/prd.md (file is read automatically) or inline via --prd-markdown (multi-line, requires quoting in shell).
Question Order
Ask in this order unless the user already supplied the answer:
- What URL should I test?
- Please provide the PRD or acceptance criteria in markdown. If unavailable, I can draft one for approval first.
- What exact user flow or feature should I focus on?
- What outcome should count as correct?
- What changed or what area feels risky?
- Do I need login or any special auth context?
If the PRD is already available, read it first and use it to narrow or confirm focus, expected outcome, and risk area instead of asking redundant questions.
Inference Rules
The AI may infer:
- likely mode from user intent,
- likely risk area from the PRD, route, or wording,
- likely subflows from the route or feature name,
- likely code search targets from file structure.
The AI must not infer:
- credentials,
- cookies,
- acceptance criteria that the user has not approved,
- whether auth is optional when access is required,
- whether a local URL is reachable by Morph remote browsers.
[DONE:2]
Session Splitting Heuristics
This system is E2E in intent but sessionized in execution.
Unit of Execution
The default unit is a subflow, not a page.
Examples:
login -> redirect -> dashboard ready
open product detail -> add to cart -> cart badge updates
open checkout -> fill shipping form -> validation passes
apply filter -> results update -> state persists
When to Split into a New Session
Create a new session when one of these happens:
- The goal changes to a new user intent.
- The route transition starts a new business step.
- A major state transition happens, such as guest -> authenticated, list -> detail, form -> confirmation, or cart -> checkout.
- The remaining work would exceed the step budget.
- A new risk area deserves isolated evidence.
- The flow branches into success path vs validation/error path.
Do not split only because the DOM changes within the same coherent subflow.
Defaults
smoke: 2-4 sessions
regression: 3-5 sessions
journey: 4-7 sessions
focused: 1-3 sessions
If the requested scope is too broad, reduce it to the highest-value subflows from the PRD and risk area instead of pretending to cover the whole app. The final report must state what was covered and what was intentionally left out.
Step Budget per Session
- Default target: 5-10 steps
- Soft ceiling: 12 steps
- If a subflow needs more than that, split it again instead of stretching one task.
- If auth is required, include auth inside the first protected subflow session instead of making a separate auth-only session unless auth itself is the subject under test.
- Do not combine auth recovery, multi-page exploration, persistence checks, and edge-case validation into one session.
Splitting Examples
Checkout
- Open product surface and choose item
- Add to cart and confirm cart state
- Fill checkout form and validate inputs
- Submit checkout and verify confirmation
Dashboard filter feature
- Login and reach dashboard ready state
- Change filters and verify result updates
- Refresh or navigate away and verify state persistence
- Exercise risky edge case from PRD
[DONE:3]
Testing Modes
Choose the mode from user intent, PRD, and risk profile.
smoke
Use when the user wants a quick confidence pass.
Goal:
- verify the top path works,
- catch obvious regressions,
- keep the session count small.
Expected output:
- pass/fail per critical subflow,
- explicit note of what was not covered,
- concise PRD alignment summary for only the highest-priority criteria.
regression
Use when validating a bugfix, recent change, or narrowly scoped risky surface.
Goal:
- test changed areas plus adjacent risk,
- verify the bugfix path and the nearby breakable path.
Expected output:
- changed/risky subflows,
- likely regression source if failed,
- PRD alignment per affected acceptance criterion.
journey
Use when the user wants an end-to-end experience validated.
Goal:
- cover the full user journey,
- still split execution into short subflows.
Expected output:
- ordered sequence of sessions,
- state handoff explanation between sessions,
- PRD alignment across the full journey.
focused
Use when the user names a narrow feature or bug.
Goal:
- stay tightly scoped,
- prioritize diagnosis over breadth.
Expected output:
- one primary scenario and optional edge case,
- strongest code suspect mapping,
- exact next fix suggestion.
PRD Alignment Rules
For every mode:
- map each tested subflow to the relevant PRD or acceptance criteria bullets,
- mark each criterion as
aligned, violated, untested, or unclear,
- never claim alignment if the browser evidence is ambiguous.
[DONE:4]
Code Analysis Phase
If code is available, code analysis is required before execution.
When It Is Mandatory
Run code analysis before browser execution when:
- the workspace contains the app code,
- the task targets a local codebase that matches the URL under test,
- the user asks for diagnosis, regression coverage, or agent next actions,
- auth, forms, or route behavior are likely relevant.
What to Search For
Use warpgrep_codebase_search to find:
- route entrypoints,
- page or screen components,
- auth middleware, guards, hooks, and login forms,
- form handlers and validation logic,
- API touchpoints or mutations,
- components named in the PRD or focus area,
- suspect files related to the changed or risky subflow.
Suggested search goals:
route for [feature/path]
component rendering [feature/page]
auth protected [route/feature]
form submit validation [feature]
api call mutation fetch [feature]
How It Affects Planning
Code analysis should influence:
- which subflows exist,
- where auth is inserted,
- what success and failure states should look like,
- which edge case deserves its own session,
- which files should be named in the final report,
- which route should be used as the explicit starting point for each browser task.
If code is unavailable, say so explicitly and continue with browser-only evidence, while lowering confidence in diagnosis. The report should say Diagnosis confidence: low and explain that source-backed suspect mapping was not possible.
[DONE:5]
Execution Routing
Tool Routing
Use morph_browser_test_url when:
- the target is a public URL,
- the task is direct environment validation,
- the run should stay browser-first and URL-first.
Every browser task should start from an explicit route or URL, not from an assumed app state.
Local or Non-Public Targets
If the target is local, private, or otherwise unreachable by Morph remote browsers:
- stop at preflight,
- explain that Morph browser testing requires a public URL,
- request a public URL such as a tunnel or staging URL,
- do not pretend the run can proceed.
Preflight Blocking Conditions
Block execution when any of these are missing:
- clear target,
- approved PRD markdown,
- focus and expected outcome,
- required auth context,
- valid public URL for URL mode,
- valid public URL for browser execution.
For protected flows, auth readiness should be evaluated in this order:
profileId / profileAlias with valid sticky-key registry resolution
- reusable
cookies
username/password
- otherwise
blocked
If preflight fails, the final result must be BLOCKED and the report must say exactly which prerequisite is missing plus the next unblock step.
[DONE:6]
Failure Analysis Flow
When a session fails or returns ambiguous evidence:
- Classify the failure from browser evidence first.
- Search the codebase for the most relevant route/component/handler.
- Map the failure to likely files or ownership areas.
- Compare the observed behavior to the approved PRD markdown.
- Produce a diagnosis and next action.
Failure Classes
bug
- The app behavior clearly contradicts the expected outcome or PRD.
flaky
- The result looks timing-sensitive, racey, or inconsistent.
env issue
- Backend, auth, data fixture, deployment, or inaccessible target prevents a valid product judgment.
unclear
- The recording or result text is insufficient to conclude.
When to Invoke Code Search Again
Run warpgrep_codebase_search after failure when:
- the failing element or route is identifiable,
- the issue looks tied to validation, disabled state, auth redirect, data fetch, or component wiring,
- the final report needs concrete file suspects.
Mapping Rules
Map failures to:
- route file or page entry,
- primary component,
- form handler or action,
- API call or mutation source,
- guard/middleware if auth or redirect behavior is involved.
PRD Gap Rules
Explicitly state whether the failure means:
- the flow breaks,
- the flow works but violates expectation,
- the expectation is untested,
- the expectation cannot be judged because of environment/setup issues.
Hard Rules For Failed Sessions
For every failed or unclear session:
- never stop at browser symptoms when code is available,
- never produce a diagnosis without at least one concrete route, component, handler, guard, or API touchpoint suspect,
- never write a next action that another agent cannot execute directly,
- never use placeholders like
investigate further, check the flow, or inspect validation logic without naming where to inspect.
Hard Rules For Browser Tasks
For every generated browser task:
- start from an explicit URL or route,
- name one primary subflow only,
- include a clear stop condition,
- fail fast if auth state is missing instead of saying
if possible or assuming the app is already authenticated,
- avoid unrelated exploration,
- avoid bundling persistence checks, edge cases, and the main happy path into one task unless the subflow is still within the step budget.
[DONE:7]
Evidence Fusion
The final diagnosis must never rely only on the browser summary.
Always combine:
- browser observations,
- video or artifact links,
- code search findings,
- PRD criteria mapping.
Fusion Pattern
For each failed or risky session:
- State what the browser showed.
- State what part of the code most likely explains it.
- State whether that behavior matches the PRD.
- State what the fixing agent should inspect next.
Diagnosis Quality Bar
A diagnosis is weak if it only repeats browser output or only says look at auth, check validation, or similar generic advice.
A diagnosis is acceptable if it names the likely route, component, handler, or API touchpoint tied to the observed failure.
A diagnosis is strong if it:
- ties the browser symptom to a concrete code suspect,
- states which PRD criterion is violated or left unclear,
- gives an executable next action for the fixing agent.
This is the core difference between a simple browser runner and this skill.
[DONE:8]
Preflight Guard Checklist
Execution may start only if all required items below are satisfied.
Required Data
- target is known,
- focus is known,
- expected outcome is known,
- risk area is known or explicitly none,
- PRD markdown exists and is approved,
- auth context exists if the flow is gated,
- target is reachable by the relevant Morph browser tool.
Command Question Flow
- What should I test?
- Provide the PRD or acceptance criteria in markdown.
- What part should I focus on?
- What should happen if it works?
- What area is risky or recently changed?
- Is login required? If yes, provide the auth context.
- If no PRD exists, draft a temporary one and ask the user to approve it.
If the PRD already answers items 3-5, confirm them briefly instead of asking them from scratch.
Stop Conditions
Do not run if:
- the user has not approved the PRD markdown baseline,
- auth is required but none of the usable auth inputs are available (
profileId / profileAlias, cookies, or username/password),
- the user insists on profile-first execution but sticky-key profile resolution cannot be satisfied for the requested
profileId / profileAlias,
- the URL is local/private for Morph browser testing,
- the target still has no usable public URL,
- expected outcome is still too vague to judge.
If the run is blocked because no usable public URL exists, the report should recommend creating a public tunnel or providing an equivalent public staging URL.
[DONE:9]
Final Markdown Report Schema
Use this shape every time, even if some sections are short.
# Morph Autotest Report
## Overall Status
- Target:
- Mode:
- Overall result: PASS | PARTIAL | FAIL | BLOCKED
- Diagnosis confidence: HIGH | MEDIUM | LOW
- Focus:
- Expected outcome:
- Risk area:
- Coverage boundary:
## Preflight Summary
- Target readiness:
- PRD readiness:
- Auth readiness:
- Execution route used:
## Session Results
### Session 1 - [name]
- Goal:
- Status:
- PRD criteria covered:
- Key browser observation:
- Artifact links:
- Code suspects:
- Diagnosis:
- Next action:
### Session N - [name]
- Goal:
- Status:
- PRD criteria covered:
- Key browser observation:
- Artifact links:
- Code suspects:
- Diagnosis:
- Next action:
## PRD Alignment
- Aligned:
- Violated:
- Untested:
- Unclear:
## Root-Cause Hints
- [hint 1]
- [hint 2]
## Recommended Next Actions For Agent
1. [most important fix path]
2. [second investigation path]
3. [optional rerun or validation path]
## Recording Index
- Session 1: [video/webp/network/console links]
- Session 2: [video/webp/network/console links]
Reporting Style Rules
- Be direct and specific.
- Avoid marketing language.
- Prefer concrete suspects over generic advice.
- If confidence is low, say why.
- If no code was available, state that diagnosis confidence is limited.
- Every failed or unclear session should name at least one concrete suspect file, route, component, guard, handler, or API touchpoint when code is available.
- Every next action should be executable by another agent without guessing the inspection target.
[DONE:10]
Internal Schemas
interface PRDInternal {
target: string;
url: string;
mode: "smoke" | "regression" | "journey" | "focused";
criteria: PRDCriterion[];
riskAreas: string[];
focus: string;
}
interface PRDCriterion {
id: string;
text: string;
priority: "critical" | "high" | "medium" | "low";
subflowIds: string[];
status: "aligned" | "violated" | "untested" | "unclear";
}
interface AuthContext {
target: string;
strategy: "profileId" | "profileAlias" | "cookies" | "credentials" | "blocked";
profileId?: string;
profileAlias?: string;
cookies?: Array<{ name: string; value: string; domain: string }>;
credentials?: { username: string; password: string };
notes?: string;
}
Execution Workflow Summary
When using this skill in practice:
- Enforce preflight.
- Read code when available.
- Build subflow sessions (see
synthesis.md).
- Resolve auth strategy (see
execution.md auth decision tree).
- Execute subflows via the tool wrapper in
execution.md.
- Apply self-healing on flaky/auth-transient failures (see
healing.md).
- Save run manifest and update healing log (see
persistence.md).
- Extract API evidence from network recordings (see
api-testing.md).
- Diagnose failures using browser evidence plus code search.
- Return the markdown report + JSON report (see
ci-cd.md).
For CI/CD use, skip step 1-3 and use headless mode flags described in ci-cd.md.
Examples
Example Request: URL
"Test the checkout flow on our staging site. Focus on shipping form validation. The risky part is that we refactored the address API. I will paste the PRD in markdown."
Example Request: URL
"Test https://staging.example.com/dashboard. Focus on filters and state persistence. The risk is the new query-param sync behavior."
Example Cases
Case: checkout submit button stays disabled
Weak output:
Diagnosis: checkout form failed to submit
Next action: inspect validation logic
Strong output:
Code suspects: app/checkout/page.tsx, src/features/checkout/useCheckoutForm.ts
Diagnosis: browser shows all required fields filled but submit remains disabled; the likely issue is a derived validity or disabled guard that never flips to ready state, which violates the PRD submit-success criteria.
Next action: inspect the disabled-state condition in app/checkout/page.tsx and compare it with the validity output in src/features/checkout/useCheckoutForm.ts.
Case: login succeeds but protected redirect loops
Weak output:
Diagnosis: auth flow is broken
Next action: inspect auth flow
Strong output:
Code suspects: middleware.ts, src/auth/requireUser.ts, app/dashboard/page.tsx
Diagnosis: login success state is reached, but the dashboard-ready condition is never satisfied after redirect; likely mismatch between session guard logic and the protected route readiness check.
Next action: inspect middleware.ts redirect conditions and compare them with the authenticated branch expected by app/dashboard/page.tsx.
Case: no public target is available yet
Expected blocked output:
Overall result: BLOCKED
Diagnosis confidence: LOW
Preflight Summary: public target unavailable
Next action: create a public tunnel or provide a public staging URL for equivalent regression coverage.
Case: user has no formal PRD
There are three paths:
-
Interactive mode (/morph_autotest with no args): Draft a temporary PRD in markdown from the conversation. Ask the user to approve it. Do not start execution until confirmed.
-
Inline PRD (JSON or flag): Pass prdMarkdown inline — no file needed. Example JSON: {"targetUrl":"https://staging.example.com","prdMarkdown":"## Checkout\n- [ ] Submit enables when all fields valid"}.
-
Headless mode (CLI flags without PRD): Run without PRD — smoke mode works without formal criteria. Report will show prdAlignment: untested for all subflows. Appropriate for quick validation or exploratory runs.
For interactive mode: draft the PRD, show it, ask for approval, then proceed. The draft should extract criteria from what the user described as expected outcome and risk area.
Example Browser Task Shapes
Bad task shape:
Starting from the authenticated app if possible, test dashboard filters and persistence.
Why it is bad:
- start state is ambiguous,
- auth readiness is assumed,
- the scope mixes the main interaction and persistence check,
- the task invites timeout and unnecessary exploration.
Better task shape:
Open https://staging.example.com/dashboard.
If redirected to login, stop and report that auth is not ready.
Validate only the filters subflow:
1. Change the status filter to Active.
2. Verify the result list updates.
3. Stop after confirming the update.
Separate persistence follow-up:
Open https://staging.example.com/dashboard.
If redirected to login, stop and report that auth is not ready.
Validate only the filter persistence subflow:
1. Change the status filter to Active.
2. Refresh once.
3. Verify the filter state persists.
4. Stop after this check.
Example Next Actions
Good next actions:
- Inspect
app/checkout/page.tsx and the address submit handler for disabled-state logic.
- Compare the dashboard filter PRD criteria against the query-param sync code in
src/features/filters/useFilters.ts.
- Rerun only the confirmation subflow after fixing the redirect guard.
Bad next actions:
- Investigate the app.
- Something is wrong with the UI.
- Try again later.