Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
140 changes: 140 additions & 0 deletions domains/testing/skills/visual-testing/references/cli-reference.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
# MM CLI Command Reference

Complete command reference for the `mm` CLI. For core workflow and getting started, see the main skill.

## Contents

- [Syntax Rules](#syntax-rules)
- [Lifecycle](#lifecycle)
- [Interaction](#interaction)
- [Navigation & Tabs](#navigation--tabs)
- [Context](#context)
- [State, Knowledge & Seeding](#state-knowledge--seeding)
- [Advanced](#advanced)

## Syntax Rules

The CLI is strict about flag names and argument positions. Mistyped flags are silently treated as element targets, producing confusing timeout errors.

### Flag spelling is exact — lowercase, no variants

```bash
# CORRECT
mm click --testid unlock-submit
mm type --testid unlock-password "correct horse battery staple"

# WRONG — all of these silently fail with a timeout
mm click --testId unlock-submit # capital I — treated as testId "--testId"
mm click --test-id unlock-submit # hyphenated — treated as testId "--test-id"
mm click --TestId unlock-submit # PascalCase — same problem
```

The only recognized interaction flags are: `--testid`, `--selector`, `--timeout`, `--within`. Anything else (including `--testId` with a capital I) is parsed as a positional argument and used as a literal testId value, producing a locator like `[data-testid="--testId"]` which always times out.

### a11yRefs are positional arguments — no `--ref` flag

```bash
# CORRECT — ref is the first positional arg
mm click e5
mm type e2 "correct horse battery staple"

# WRONG — no --ref flag exists; "--ref" becomes the testId value
mm click --ref e5
```

### One targeting method per call

Each interaction command accepts exactly one of: positional a11yRef, `--testid`, or `--selector`. Do not combine them.

```bash
mm click e5 # a11yRef (positional)
mm click --testid unlock-submit # testId (flag)
mm click --selector "#connectButton" # CSS selector (flag)
```

### Quick reference

| What you want | Correct syntax | Common mistake |
|---|---|---|
| Click by testId | `mm click --testid X` | `mm click --testId X` (capital I) |
| Click by a11y ref | `mm click e5` | `mm click --ref e5` (no such flag) |
| Click by CSS | `mm click --selector ".btn"` | `mm click --css ".btn"` (no such flag) |
| Type by testId | `mm type --testid X "text"` | `mm type --testId X "text"` |
| Type by a11y ref | `mm type e2 "text"` | `mm type --ref e2 "text"` |

## Lifecycle

| Command | Description |
| ----------------------- | -------------------------------------- |
| `mm launch` | Launch MetaMask in headless Chrome |
| `mm cleanup` | Stop browser and services |
| `mm cleanup --shutdown` | Stop browser, services, and the daemon |
| `mm status` | Show current daemon and session status |

## Interaction

| Command | Description |
| ---------------------------- | ---------------------------------------------------- |
| `mm click <ref>` | Click element by a11y ref, testId, or selector |
| `mm type <ref> <text>` | Type text into element (uses `fill()`, clears first) |
| `mm get-text <ref>` | Read text content of element |
| `mm describe-screen` | Combined state + activeTab + testIds + a11y snapshot |
| `mm screenshot [--name <n>]` | Take and save screenshot |
| `mm wait-for <ref>` | Wait for element to be visible |
| `mm wait-for-notification` | Wait for sidepanel confirmation route, set as active |
| `mm accessibility-snapshot` | Get trimmed a11y tree with refs |
| `mm list-testids` | List visible `data-testid` attributes |
| `mm clipboard <action>` | Read from or write to browser clipboard |

All interaction commands accept `--timeout <ms>` (default 15000). This is a **single deadline budget** covering visibility wait + action combined — not a per-phase timeout.

## Navigation & Tabs

| Command | Description |
| ------------------------- | --------------------------------------------- |
| `mm navigate <url>` | Navigate to a specific URL |
| `mm navigate-home` | Navigate to the extension home |
| `mm navigate-settings` | Navigate to the extension settings |
| `mm switch-to-tab <role>` | Switch active page to a different tab by role |
| `mm close-tab <role>` | Close a tab |

Tab roles: `extension`, `notification`, `dapp`, `other`.

`mm switch-to-tab dapp` is equivalent to `mm switch-to-tab --role dapp`.

## Context

| Command | Description |
| ---------------------------- | ---------------------------------------------- |
| `mm get-context` | Get current context and available capabilities |
| `mm set-context <e2e\|prod>` | Switch workflow context |

Two contexts: `e2e` (default — local Anvil, fixtures, seeding) and `prod` (no fixtures, no local chain). Cannot switch during active session — run `mm cleanup` first.

## State, Knowledge & Seeding

| Command | Description |
| ----------------------------- | ----------------------------------------- |
| `mm get-state` | Get current extension state |
| `mm knowledge-search <query>` | Search steps across sessions |
| `mm knowledge-last` | Get last N step records from this session |
| `mm knowledge-sessions` | List recent sessions with metadata |
| `mm knowledge-summarize` | Generate session recipe |
| `mm run-steps <json>` | Execute multiple tools in sequence |
| `mm seed-contract <type>` | Deploy a test contract |
| `mm seed-contracts` | Deploy multiple test contracts |
| `mm get-contract-address` | Get deployed contract address |
| `mm list-contracts` | List all deployed contracts |

## Advanced

| Command | Description |
| ------------------------------------------------- | ----------------------------------------------------------- |
| `mm mock-network add '<json-rule-or-config>'` | Add Playwright route mocks during active session |
| `mm mock-network clear` | Clear network mocks and recorded requests |
| `mm mock-network list` | List active network mock rules |
| `mm mock-network requests [--limit <n>]` | Show recorded matched and missed mocked-origin requests |
| `mm cdp <method> [params-json] [--timeout <ms>]` | Send raw Chrome DevTools Protocol command against active page|

For mock network details, see [mock-network.md](mock-network.md).
For CDP state manipulation, see [state-manipulation.md](state-manipulation.md).
67 changes: 67 additions & 0 deletions domains/testing/skills/visual-testing/references/error-recovery.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# Error Recovery & Troubleshooting

## Contents

- [On Failure](#on-failure)
- [Error Codes](#error-codes)
- [Common Failures & Solutions](#common-failures--solutions)

## On Failure

1. Run `mm describe-screen`
2. Check the current screen:
- `unlock` → enter password and submit
- `home` → continue, but check for modals or blockers
- `onboarding-*` → complete onboarding
- `unknown` → take a screenshot and investigate
3. Query prior runs:
```bash
mm knowledge-search "send"
mm knowledge-sessions
mm knowledge-last
```
4. Capture `mm screenshot --name "debug"` for diagnosis

## Error Codes

| Code | Meaning |
| ---------------------------- | ------------------------------------------------------------------------------ |
| `MM_SESSION_ALREADY_RUNNING` | Session exists — `mm cleanup` first |
| `MM_NO_ACTIVE_SESSION` | No session — `mm launch` first |
| `MM_LAUNCH_FAILED` | Browser launch failed |
| `MM_INVALID_INPUT` | Invalid parameters |
| `MM_TARGET_NOT_FOUND` | Element not visible |
| `MM_TAB_NOT_FOUND` | Tab not found |
| `MM_CLICK_FAILED` | Click failed (post-find) |
| `MM_CLICK_TIMEOUT` | Click hung — may have completed; run `mm describe-screen` |
| `MM_TYPE_FAILED` | Type failed (post-find) |
| `MM_TYPE_TIMEOUT` | `fill()` timed out — `mm describe-screen` and retry |
| `MM_GETTEXT_FAILED` | `get-text` failed (element detached) — re-target |
| `MM_GETTEXT_TIMEOUT` | `textContent()` timed out |
| `MM_WAIT_TIMEOUT` | Wait timeout exceeded |
| `MM_PAGE_CLOSED` | Page closed during interaction — normal after some confirmations |
| `MM_SCREENSHOT_FAILED` | Screenshot capture failed |
| `MM_BATCH_TIMEOUT` | `batchTimeoutMs` deadline exceeded |
| `MM_CONTEXT_SWITCH_BLOCKED` | Cannot switch context during active session |
| `MM_SET_CONTEXT_FAILED` | Context switch failed |
| `MM_CDP_BLOCKED` | CDP method is in the destructive-blocklist |
| `MM_CDP_FAILED` | CDP command execution failed or timed out |

## Common Failures & Solutions

| Symptom | Likely Cause | Solution |
| ------------------------------------------- | ---------------------------- | ------------------------------------------------------------- |
| `MM_SESSION_ALREADY_RUNNING` | Previous session not cleaned | `mm cleanup` |
| `MM_NO_ACTIVE_SESSION` | No browser running | `mm launch` |
| Extension not loading | Extension not built | `yarn build:test:webpack` then `mm launch` |
| `EADDRINUSE` port error | Orphan processes | Check `.mm-server` for ports, kill orphaned process |
| `MM_TARGET_NOT_FOUND` | Element not visible | `mm describe-screen` to check state |
| `MM_WAIT_TIMEOUT` | Slow environment | Increase `--timeout`, inspect screenshot |
| `MM_CLICK_TIMEOUT` / `MM_TYPE_TIMEOUT` | Action hung | `mm describe-screen` to verify; retry with larger `--timeout` |
| `MM_GETTEXT_TIMEOUT` / `MM_GETTEXT_FAILED` | Element detached | `mm describe-screen` and re-target |
| `MM_PAGE_CLOSED` | Confirmation auto-closed | Expected — `mm describe-screen` to find active page |
| `MM_CDP_BLOCKED` | Destructive CDP method | Use a non-blocked method |
| `MM_CDP_FAILED` | Invalid CDP params | Check method & params; retry with `--timeout` (max 30000) |
| `MM_CONTEXT_SWITCH_BLOCKED` | Active session | `mm cleanup` before `mm set-context` |
| Fixtures not available | Running in prod context | `mm set-context e2e` |
| Stale a11yRefs after navigate | Refs not refreshed | `mm describe-screen` for fresh refs |
81 changes: 81 additions & 0 deletions domains/testing/skills/visual-testing/references/mock-network.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# Mock Network Requests

Use `mm mock-network` to stub browser network requests during an active session. Prefer this over raw CDP when you need deterministic API responses.

## Contents

- [Rules](#rules)
- [Rule Shape](#rule-shape)
- [Examples](#examples)
- [Verification Pattern](#verification-pattern)
- [In mm run-steps](#in-mm-run-steps)

## Rules

Mock rules are installed on the active Playwright browser context:

- Run `mm launch` first.
- Add rules **before** the UI action that triggers the request.
- `mm cleanup` removes all rules; `mm mock-network clear` removes rules and request history without ending the session.
- Unmatched requests on a mocked origin continue unchanged and are recorded as misses.
- **Cannot** intercept requests during extension startup before the session is fully active.

## Rule Shape

```json
{
"id": "token-prices",
"method": "GET",
"url": "https://price.api.metamask.io/v1/**",
"response": {
"status": 200,
"json": { "ethereum": { "usd": 1234.56 } }
}
}
```

| Field | Description |
| ------------------ | --------------------------------------------------------------------------------- |
| `id` | Stable identifier. Same `id` replaces the previous rule. |
| `method` | HTTP method; normalized to uppercase. |
| `url` | Absolute URL or glob. `*` matches within a segment; `**` matches any path suffix. |
| `response.status` | Optional HTTP status; defaults to `200`. |
| `response.json` | JSON response payload. |
| `response.body` | Text response payload. Use either `json` or `body`. |
| `response.headers` | Optional. JSON/text defaults include `access-control-allow-origin: *`. |

## Examples

```bash
# Single rule
mm mock-network add '{"id":"token-prices","method":"GET","url":"https://price.api.metamask.io/v1/**","response":{"status":200,"json":{"ethereum":{"usd":1234.56}}}}'

# Multiple rules
mm mock-network add '{"routes":[
{"id":"feature-flags","method":"GET","url":"https://client-config.api.cx.metamask.io/**","response":{"json":{"flags":{}}}},
{"id":"empty-nfts","method":"POST","url":"https://nft.api.metamask.io/**","response":{"status":200,"json":{"nfts":[]}}}
]}'

# Inspect and manage
mm mock-network list
mm mock-network requests --limit 20
mm mock-network clear
```

## Verification Pattern

1. Add the rule with `mm mock-network add ...`
2. Trigger the UI flow that makes the request
3. Run `mm mock-network requests --limit 20`
4. Confirm the expected request has `matched: true` and the expected `ruleId`

## In mm run-steps

Use tool name `mock_network` with the same input shape:

```bash
mm run-steps '{"steps":[
{"tool":"mock_network","args":{"action":"add","rule":{"id":"prices","method":"GET","url":"https://price.api.metamask.io/v1/**","response":{"json":{"ok":true}}}}},
{"tool":"navigate","args":{"screen":"url","url":"https://test-dapp.io"}}
]}'
```
Loading
Loading