> ## Agent Instructions > The canonical docs host is https://momentic.ai/docs. Append .md to any page URL for clean Markdown. Fetch https://momentic.ai/docs/llms.txt for the page index and https://momentic.ai/docs/llms-full.txt for every page in one file. > For an unattended setup, run `npx --yes @momentic/wizard@latest -y --platform web --editor-tools skills` (use `--platform ios` or `--platform android` for mobile). Never run an interactive command in a non-TTY shell. > You cannot complete the browser sign-in yourself. Read the API key from the MOMENTIC_API_KEY environment variable, or ask the user to create one at https://app.momentic.ai/settings/api-keys and paste it back. > Momentic's capability summary for agents is at https://momentic.ai/docs/skill.md. Install the skills with `npx skills@latest add momentic-ai/skills`. > Tests are YAML files in the user's repository. Use only the step names listed at https://momentic.ai/docs/reference/commands.md and the file structure at https://momentic.ai/docs/core-concepts/file-format.md. Do not invent step names, config keys, or CLI flags. > Web tests run on Chromium, iOS tests on simulators, and Android tests on emulators. Physical devices are not supported. # AI data use and retention Source: https://momentic.ai/docs/account/ai-data-use What Momentic sends to model providers, how long data is kept, and how to opt out. Momentic uses AI to author steps, act on the page, evaluate page state, recover from transient failures, and find the root cause of failures. These features call hosted model providers. Your tests are YAML files in your own repository, under your own version control. Momentic does not need to hold them. ## What Momentic sends to a model provider Momentic sends prompts, page context, screenshots and image-derived inputs, accessibility and HTML snapshots, step traces, and the AI output itself to a model provider. Momentic does not crawl, ingest, or retrieve private documents or document repositories. It reaches only the applications, pages, and artifacts that your test is configured to use. ## Model providers Momentic uses hosted third-party providers across several vendors for reliability: Anthropic, OpenAI, Google Vertex, xAI, Mistral, OpenRouter, AWS Bedrock, and Microsoft Azure. Momentic has zero-data-retention agreements in place with all model providers. See the sub-processor table on [Privacy and security](/docs/account/security). ## What we keep, and for how long | Data | Retention | | --------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Application logs from the CLI (OpenTelemetry) | 14 days | | AI traces (third-party LLM observability provider, Langfuse) | Retained indefinitely by default | | Run artifacts you upload (videos, DOM, network and console traces, screenshots, auto-heal traces, AI reasoning) | Visible in the dashboard for your organization. Local runs stay local unless you pass `--upload-results`. See [Results and reporting](/docs/running-tests/results). | AI memory and step caches are scoped per organization and reachable only by authenticated runs. See [AI memory](/docs/ai/memory) and [Step caching](/docs/reliability/step-cache). ## Who can see it Internal access to logs and AI traces is gated by SSO and role-based access controls. Access is limited to authorized Momentic personnel with a business need. Momentic engineers use logs and traces when you ask for debugging help. You control dashboard access with your own roles and SSO. See [API keys and team settings](/docs/account/api-keys-and-team). You can separate API keys per user, CI pipeline, and environment. ## Model training Data from self-serve accounts may be used to improve Momentic's agents. Enterprise customers can opt out of training entirely or agree to a custom fine-tuning arrangement. Enterprise customers can also get a zero-data-retention policy. Momentic does not store your context as vector embeddings. To opt out, ask your account team or write to support. ## Keep sensitive data out of a test run Run tests against dedicated test environments with faked or cleaned data. Do not put production PII, confidential documents, or unnecessary secrets in test flows. Keep credentials in [environment variables](/docs/configuration/environment-variables) or CI secret storage, not in test steps. Momentic does not process PII during tests. ## How the agents are constrained Agents receive structured page data, including screenshots and simplified HTML, and must return commands through strict tool schemas. Arbitrary free-form instructions to the model are not accepted. Prompts require agents to target elements that exist on the current page, avoid inventing elements or test data, and fail rather than guess. Every output is validated against a schema and executed by deterministic automation code. Webpage content, traces, and prior run memory are treated as untrusted input. ## Certifications and reports Momentic is SOC 2 Type 2 certified. The [Trust Center](https://trust.momentic.ai) has SOC 2 and annual penetration test reports. Read the [privacy policy](https://momentic.ai/legal/privacy) for privacy details. See [Privacy and security](/docs/account/security) for the sub-processor list. # API keys and team settings Source: https://momentic.ai/docs/account/api-keys-and-team Manage API keys, team members, roles, SSO, and billing in the Momentic dashboard. Account-level settings live in the Momentic dashboard. Start with an API key to authenticate the CLI and CI, then add teammates, configure SSO, and manage billing. ## API keys Create and revoke keys in the [dashboard](https://app.momentic.ai/settings/api-keys). Use a separate key for: * Each developer, so you can revoke one person's access without affecting others * Each CI pipeline, so you can rotate CI keys independently * Each environment (dev vs. production CI) Keys are shown once at creation; copy them somewhere safe. ### Setting a key Export the key as `MOMENTIC_API_KEY` in your shell, `.env`, or CI secrets manager: ```bash theme={null} export MOMENTIC_API_KEY=your-api-key-here ``` ## Team members Invite team members in the [dashboard](https://app.momentic.ai/settings/members). Each member gets a role that controls what they can do. ### Roles | Action | Admin | Member | | -------------------------------------------- | ----- | ------ | | Run tests, view results, manage own API keys | Yes | Yes | | See teammates on the Members page | Yes | Yes | | Invite new members at the **Member** tier | Yes | Yes | | Invite new members at the **Admin** tier | Yes | No | | Change another member's role | Yes | No | | Remove a member from the workspace | Yes | No | | Open the billing portal (plan + payment) | Yes | No | | View invoice history | Yes | No | | Manage SSO connections | Yes | No | ## SSO SSO is available on the Enterprise plan. See [Security](/docs/account/security) for SAML/OIDC setup details. ## Billing Admins manage billing in the [dashboard](https://app.momentic.ai/settings/billing). * Self-serve plans: card on file, monthly billing * Enterprise plans: annual contract, invoiced # Privacy and security Source: https://momentic.ai/docs/account/security Momentic's data handling, certifications, and sub-processors. Momentic is SOC 2 Type 2 certified. ## Quick links How Momentic handles your data. Security practices, SOC 2 certification, and annual penetration testing reports. What Momentic sends to model providers, how long data is kept, and how to opt out. ## Sub-processors | Sub-processor | Purpose | | --------------------- | ------------------ | | PostHog | Product analytics | | Datadog | Analytics | | Google Cloud Platform | Hosting | | Superhuman | Email | | Pylon | Support | | Slack | Internal processes | | Notion | Internal processes | | Google Workspace | Internal processes | | GitHub | Source code | | Linear | Issue tracking | | Sentry | Error monitoring | | Stripe | Billing | | Orb | Billing | | Anthropic | AI | | OpenAI | AI | | Microsoft Azure | AI | | Google Vertex | AI | | AWS Bedrock | AI | | xAI | AI | | Mistral | AI | | OpenRouter | AI | | Langfuse | AI observability | | WorkOS | Authentication | # Agents Source: https://momentic.ai/docs/ai/agents The specialized AI agents behind Momentic steps, the versions available for each, and what every agent does. Momentic uses several specialized AI agents. Each is versioned independently, so you can upgrade one without changing the others. Older versions stay available for backwards compatibility; set a specific version per agent in your `momentic.config.yaml` [`ai.agentConfig`](/docs/configuration/ai#ai-agentconfig) block. Momentic generally announces agent deprecations at least 90 days in advance. When upgrading an agent version, we recommend testing the migration in a branch first. In rare cases, AI model decisions can vary from version to version. The recommended agents use the latest models. They are tuned to use [memory](/docs/ai/memory) (insights saved from past runs) and custom [knowledge base](/docs/ai/knowledge-base) entries. All agents have built-in fallback mechanisms to handle AI provider outages and disruptions. During such downtime, agents may incur additional latency or exhibit different behavior. [Memory](/docs/ai/memory), the [knowledge base](/docs/ai/knowledge-base), and [failure recovery](/docs/reliability/auto-maintenance#failure-recovery) reduce the frequency and impact of AI non-determinism on your tests. | Agent | Recommended | p50 latency | Older versions | | ------------------ | ----------- | -------------------- | -------------- | | `locator` | `v4` | 3.6s | `v2`, `v3` | | `assertion` | `v4` | 2.8s | `v2`, `v3` | | `visual-assertion` | `v4` | 2.7s | `v2`, `v3` | | `text-extraction` | `v3` | 4.2s | `v2` | | `failure-recovery` | `v2` | Variable (multiturn) | `v1` | ## What each agent does Locates elements from a natural language description, used by **Click**, **Type**, and **Element check** steps. Strongly respects single quoted text values, builds more accurate caches, and achieves 15% lower latency compared to `v3`. Scores 10% better on our internal web automation benchmark. Evaluates natural language statements against a snapshot of the page, used by **AI check** steps. Strongly respects single quoted text values and discerns visual detail more accurately. Improves by 8% on our internal web assertion benchmark with 22% reduced latency compared to `v3`. Evaluates natural language statements from a viewport screenshot. Reasons about position more accurately than previous versions. Scores 12% better on our internal visual understanding benchmark. Extracts structured data from the page given a JSON schema, used by **AI extract** steps. Handles nested objects and arrays. Generates and executes recovery steps when a recoverable failure is detected. Requires [`ai.failureRecovery`](/docs/configuration/ai#ai-failurerecovery). # App graph Source: https://momentic.ai/docs/ai/app-graph Turn real run traces into journey coverage, better AI test selection, and product risk analysis. The app graph turns test-run traces into a model of your application's user journeys. Use it to see which flows are covered, improve AI test selection, and give product risk analysis the context to connect failures to affected journeys. The app graph is in alpha and may change. [Contact us](https://momentic.ai/sales) to join the waitlist. ## How it is built Every run produces page states. The app graph builds structure from those states: 1. Each observed UI state is fingerprinted (canonical URL plus a normalized, minhashed view of the DOM) so near-identical states collapse to one. 2. A short semantic summary of each state is embedded. 3. States are clustered into a taxonomy of product areas, features, journeys, variants, and segments. The graph is versioned and recomputed as new runs come in, so coverage tracks the app as it changes rather than going stale. ## The taxonomy * **Product area** and **Feature** group the app by what it does. * **Journey** is a user-facing flow. A journey has one or more **variants** (for example, the success path and an error path), and each variant is a sequence of **segments** (steps a test would walk through). Coverage is journey-rooted: there is one row per journey and variant. A single journey can touch several product areas and features through its segments, so those surface as lists rather than a single column. ## Coverage states Each journey variant has a status derived from the latest runs of the tests that match it: | Status | Meaning | | --------------- | -------------------------------------------------------------------- | | **Covered** | At least one active, passing test covers the variant. | | **Partial** | An active test covers part of the variant. | | **Quarantined** | Every covering test is quarantined, so it is not gating. | | **Missing** | No working test. Either no test matches, or all matching tests fail. | | **Ignored** | You explicitly excluded the variant. Sticky and user-set. | When a variant is **Missing**, the reason is surfaced (no matching test vs. all matching tests failing) so a failing population does not look like an untested one. ## Proposals As runs reveal journeys the graph does not yet model, the system proposes additions (new product areas, features, journeys, variants, or segments). You review them in a proposals queue and approve or reject each one, so the model stays accurate without absorbing noise automatically. ## AI test selection [AI test selection](/docs/ai/select) can use the app graph to map a pull request's code changes to the product journeys and tests that can regress. The graph adds runtime evidence that a code index cannot derive from imports alone, including connections across API, data, and UI boundaries. Selection also works without the app graph via `--no-app-graph`. AI test selection can start with a partial graph, but selection quality improves as more runs connect application states and journeys to tests. ## Related * [What is AI-native testing?](/docs/get-started/ai-native-testing#turn-runs-into-reusable-insights) * [MCP server](/docs/coding-agents/mcp-server) for authoring tests against changed journeys. * [AI test selection](/docs/ai/select) for choosing tests to run for a code change. * [Quarantine](/docs/reliability/auto-maintenance#quarantine) for how quarantined tests affect coverage. # Knowledge base Source: https://momentic.ai/docs/ai/knowledge-base Teach Momentic about your product (terminology, agent rules, and flows) so every AI-assisted step behaves consistently across runs. The knowledge base stores information that page content cannot provide: the words your team uses, the rules a specific agent should follow, and the multi-step flows that describe how your product works. Momentic retrieves the most relevant entries on every AI-assisted step and treats them as top-priority context. This gives the agent consistent product-specific guidance. You manage it from the **Knowledge** section of the dashboard at [app.momentic.ai/knowledge](https://app.momentic.ai/knowledge). ## Knowledge types Every item is one of three types. Pick the type that matches what you're teaching. * **Terminology** defines a term your test or app uses so the agent resolves it the way your team means it. You provide a **canonical term**, a **definition**, and optional **examples** that ground how the term is used. Use this when a word is ambiguous, such as what "the selected tab" actually refers to in your UI. * **Agent rule** is a binding instruction that one agent should follow at runtime. You give it a **title**, choose the **agent** it applies to, and write the **instruction**. Only the selected agent receives the rule, so you can shape behavior precisely, such as how elements are located or how a failure is classified. Rules can also target the heal subagent, which repairs one failing test at a time, so product-specific recovery guidance reaches the agent that edits or verifies the repair without being applied to broader failure-bucketing. * **Flow** is a known workflow with an expected outcome. You describe the **intent** (the user-level goal, like "log in"), the **steps** (one per line), and the **success state** (what should be true once the flow finishes). Flows give the agent a reliable map of how a journey through your product is supposed to go. Definitions, instructions, and steps all support Markdown. Agents read these fields verbatim, so be precise. ## Adding knowledge 1. Open the **Knowledge** section, click **Add knowledge**, and choose **Create manually**. 2. Choose a type. The form shows the fields relevant to that type. 3. Fill in the content and, optionally, set a scope. 4. Save. The item is visible immediately and becomes searchable within seconds once Momentic finishes indexing it. To import many items at once, choose **Bulk upload** from the same menu instead (see [Bulk upload](#bulk-upload)). ### Scope By default, knowledge applies across your whole **organization**. You can narrow an item so it's only retrieved in a more specific context: * **Test scope** limits the item to a single test. * **Environment scope** limits the item to a specific environment. Leave a scope blank to keep it organization-wide. The detail view shows each item's scope (Organization, Test, Environment, or App). ### Bulk upload To import an existing knowledge base in one step, choose **Bulk upload** from the **Add knowledge** menu and upload or paste a **JSON array** or **CSV** of items. Up to 200 rows are accepted per upload, and the whole upload is validated together: if any row is invalid, nothing is created and the error lists the offending rows. Each row carries a `type` of `TERMINOLOGY`, `AGENT_RULE`, or `FLOW` (defaulting to `TERMINOLOGY` when omitted) plus that type's fields: * **Terminology**: `canonicalTerm`, `definition`, and optional `examples`. * **Agent rule**: `title`, `agentSubtype`, and `instruction`. * **Flow**: `intent`, `steps`, and `successState`. `examples` accept either a JSON string array or a newline-separated string (one example per line), which is convenient for a single CSV cell. Add an optional `appId`, `testId`, or `environmentId` to a row to [scope](#scope) it; omit them to keep the item organization-wide. The dialog ships JSON and CSV samples you can load as a starting point. ## Suggestions Momentic captures **candidate** knowledge from your sessions and collects it in the **Suggestions** tab for review. These are entries Momentic inferred about your product that aren't part of your knowledge base yet. * **Approve** a suggestion to promote it into your organization's knowledge base, where it starts informing agents. * **Reject** a suggestion to discard it. The **Organization** tab shows knowledge that's already in effect, and the **Suggestions** tab shows what's waiting on your review. Each tab displays a count so you can see whether there's anything to triage. ## Enabling and disabling Active knowledge can be turned on or off without deleting it: * **Enabled**: the item is live and eligible for retrieval. * **Disabled**: the item is kept but excluded from retrieval. Use the toggle on an item to switch between the two. Items that are still pending review (or otherwise not yet active) must be approved or archived before they can be toggled. System knowledge authored by Momentic is managed for you, so it can't be edited or disabled. ## Trust and conflicts Each item carries a **trust** score from 0 to 100 reflecting how authoritative it is. Manually authored knowledge is trusted more than auto-generated suggestions, and Momentic's own system knowledge is trusted highest. When two entries conflict, the agent prefers the higher-trust entry. Agent rules are treated as binding instructions and are given extra weight. ## How agents use knowledge On each AI-assisted step, Momentic semantically retrieves the entries most relevant to what the agent is doing and injects them as top-priority context. Heal runs also retrieve knowledge scoped to the test being repaired, so rules, terminology, and known flows can guide the repair for that specific failure. If an entry directly addresses the task, the agent follows it instead of guessing. When the agent relies on an entry in its written reasoning or summaries, it cites the entry inline so you can trace which knowledge influenced a decision. ## Versioning and usage Editing an item records a new version, and the **About** tab keeps the full version history alongside who changed what and when. The **Usage** tab lists the runs that cited the item, with the test each run belongs to and when it was cited, and links to each run so you can see how a piece of knowledge is being used in practice. ## Related * [What is AI-native testing?](/docs/get-started/ai-native-testing#turn-runs-into-reusable-insights) # Memory Source: https://momentic.ai/docs/ai/memory Momentic seeds AI decisions with traces from past successful runs so the agent stays consistent across executions. Natural language is ambiguous. Memory resolves references such as "the selected tab" by feeding the agent its own past decisions from successful runs. This lets the agent distinguish the currently active tab from one literally labeled "Selected". ## When memory is used Memory is used whenever a step relies on AI, including locator resolution (**Click**, **Type**) and assertions (**AI check**, **Element check**). It is treated as a form of caching and is skipped when caching is explicitly disabled. ## Storage and expiration * Stored per organization, only accessible during authenticated runs. * Expires after 30 days of inactivity. * Supported for the locator and assertion agents. Momentic automatically prunes to the most relevant traces so memory stays bounded. ## Failed steps Memory is written on every AI-assisted step, including failed ones. This keeps tests failing consistently when there's a legitimate bug. ## Enabling memory Toggle per test in the editor's AI options. Set the default via [`ai.useMemory`](/docs/configuration/ai#ai-usememory) in your config. ## Related * [What is AI-native testing?](/docs/get-started/ai-native-testing#turn-runs-into-reusable-insights) # AI test selection Source: https://momentic.ai/docs/ai/select Select the tests most likely to catch regressions from a code change, using your code index and optionally the app graph. AI test selection reads a git diff and runs a focused set of Momentic tests that covers the changed behavior. Use it in pull request CI when running every test would take too long. ## Run selected tests Run it from the root of your git repository: ```bash theme={null} npx momentic run . --ai-select ``` In supported CI providers, Momentic detects the pull request base ref. Use `--ai-select-base` when you need to set it explicitly: ```bash theme={null} npx momentic run . --ai-select --ai-select-base origin/main ``` Test files changed directly in the diff are included. Changes to shared modules do not force every consuming test to run; selection chooses representative coverage for the affected behavior. If Momentic cannot build a safe selection, it runs the full in-scope test set instead. ## How selection works Momentic combines these sources of evidence: 1. The git diff identifies the code and behavior that changed. 2. A local code index traces imports and downstream consumers in your repository. 3. Optionally, the [app graph](/docs/ai/app-graph) connects product journeys and UI states to the tests that exercised them in real runs. The app graph is not required. Pass `--no-app-graph` to select from the diff and local code evidence only: ```bash theme={null} npx momentic ai select --base origin/main --no-app-graph ``` When the app graph is enabled, it provides runtime relationships that static imports cannot express, such as a backend change surfacing in a browser flow. Selection quality improves as the graph observes more of your application and test suite. Build-graph systems such as Bazel are effective at selecting work within a declared dependency graph. Applying that approach to end-to-end tests requires teams to manually define and maintain the relationship between build targets, services, and tests. Code imports also stop at network and product boundaries: they do not show that a frontend journey depends on an API, queue, data store, or third-party integration. The app graph adds those observed runtime relationships without requiring every cross-system dependency to be orchestrated by hand. The test budget is a soft cap. Momentic can exceed it when more tests are needed to cover distinct changed behavior. ```bash theme={null} npx momentic run . --ai-select --ai-select-budget 10 ``` ## Guide selection with a prompt Use `--prompt` to add repository-specific selection guidance that Momentic cannot infer from the diff, code index, or app graph: ```bash theme={null} npx momentic run . --ai-select \ --prompt "Prioritize authentication, cart state, and checkout behavior affected by this change." ``` The prompt augments Momentic's built-in selection instructions. It does not replace them. Repeat the flag to provide multiple instructions; Momentic appends the values in command-line order. When you omit `--prompt`, the standard selection prompt is unchanged. The standalone command accepts the same flag: ```bash theme={null} npx momentic ai select . --json \ --prompt "Treat changes to shared API types as relevant to browser checkout tests." ``` ## Use the code index in GitHub Actions Check out full git history and install the code-index parsers before running the command: ```yaml theme={null} steps: - uses: actions/checkout@v4 with: fetch-depth: 0 - run: npx momentic install-codetools - run: npx momentic run . --ai-select ``` See the [complete GitHub Actions example](https://github.com/momentic-ai/examples/blob/main/.github/workflows/test-ai-select.yml) for setup, code-index caching, standalone selection output, test execution, and result uploads. ## Preview a selection Use shadow mode to compare a selection with the full test run before using it to gate pull requests. Momentic still runs every in-scope test and records which ones selection would have skipped. ```bash theme={null} npx momentic run . --ai-select-dry-run ``` To inspect a selection without running tests, use `momentic ai select`: ```bash theme={null} npx momentic ai select --base origin/main npx momentic ai select --base origin/main --json > ai-selection.json ``` The JSON result contains `selectedTests` for an explicit handoff and sets `fallbackToRunAll` when Momentic cannot produce a safe selection. ## Limit selection time AI test selection allows 180 seconds to produce a safe selection by default. If the deadline expires, Momentic discards any partial selection and falls back to running every in-scope test. Use `--timeout` to change the limit, in seconds, for the standalone command: ```bash theme={null} npx momentic ai select --base origin/main --timeout 300 ``` In JSON output, a timeout returns an empty `selectedTests` array and sets `fallbackToRunAll` to `true`. Treat this as a run-all outcome rather than a zero-test selection. ## Build a dynamic CI matrix Run standalone selection once in a planning job, convert the selected test paths into your CI system's matrix format, and pass each shard's paths to `momentic run`. This lets a small selection use one runner while larger selections create more shards. Your planner should handle three outcomes: 1. Run the paths in `selectedTests`. 2. Run every in-scope test when `fallbackToRunAll` is `true`. 3. Skip the execution job for a valid selection with no tests. The [dynamic GitHub Actions example](https://github.com/momentic-ai/examples/blob/main/.github/workflows/test-ai-select.yml) shows the complete workflow. Its [matrix builder](https://github.com/momentic-ai/examples/blob/main/.github/scripts/build-ai-select-matrix.mjs) is a small Node.js script you can adapt to another CI provider or shard size. Use `momentic run --ai-select` when you do not need to customize the handoff; it performs selection and execution in one command. ## When selection chooses zero tests A selection that picks no tests is a normal outcome for non-behavioral changes. The run group still uploads with the selection plan, and the GitHub pull request comment explains why nothing ran instead of staying silent. When onboarding onto AI selection, set your CI up so zero-test selections reach Momentic: * Always run `momentic results upload`. Do not gate the upload step on the runs directory existing or on tests having run; a zero-test run group uploads its metadata, which is what powers the pull request comment. * When you merge sharded results before uploading, pass `--allow-empty` to [`momentic results merge`](/docs/cli-reference/momentic/commands/results) so shards without runs keep their selection plans in the merged archive. * `momentic results check` treats a zero-test results directory as clean, so a check step needs no special casing. The [AI Select example workflows](https://github.com/momentic-ai/examples/blob/main/.github/workflows/test-ai-select.yml) follow this setup, including a zero-selection reporting job for the dynamic matrix pattern where an empty selection skips the execution jobs entirely. ## Benchmark Momentic achieves state-of-the-art results on our custom QAWorkflowSelect benchmark. It uses real code changes across frontend, backend, CLI, shared libraries, configuration, and non-behavioral scenarios. Each baseline receives the same code changes and candidate test files as Momentic, but does not use the app graph or Momentic's investigation workflow. Cross-functional recall uses the harder cases that span product boundaries. Metrics are macro averages across cases. | Metric | Momentic agent (GPT-5.6 Terra, medium) | GPT-5.5 Codex (medium) | Claude Opus 5 (medium) | | ---------------------------------- | -------------------------------------- | ---------------------- | ---------------------- | | Average precision | **91.8%** | 75.7% | 82.9% | | Average recall | **97.5%** | 94.5% | 95.1% | | Average cross-functional recall | **100%** | 77.8% | 91.7% | | Average F1 | **90.2%** | 75.3% | 82.9% | | Perfect cases | **85%** | 59% | 69% | | Average latency | **36.1s** | 73.2s | 38.9s | | Estimated model cost per selection | **\$0.35** | \$1.54 | \$0.96 | | Model cost saved with Momentic | - | **78%** | **64%** | Cost estimates apply the published standard uncached API rates for [GPT-5.6 Terra](https://developers.openai.com/api/docs/models/gpt-5.6-terra), [GPT-5.5](https://developers.openai.com/api/docs/models/gpt-5.5), and [Claude Opus 5](https://platform.claude.com/docs/en/about-claude/models/choosing-a-model) to the observed input and output token usage. The Momentic estimate prices its Terra root and Luna investigation tokens at the higher Terra rate. Actual costs vary with caching, long-context pricing, and provider agreements. Model output varies between runs, so these results measure the evaluated code changes rather than guarantee a particular selection. We can share the raw results and reproduction harness on request. ## Notes * The command needs enough git history to resolve the base ref. Use `fetch-depth: 0` with `actions/checkout`. * The code index currently analyzes TypeScript and JavaScript imports. With the app graph enabled, runtime evidence can still connect behavior across other boundaries. * A budget limits selection size, not safety behavior. Selection can fall back to running all tests. ## Related * [What is AI-native testing?](/docs/get-started/ai-native-testing#run-intelligently) # Agent skills Source: https://momentic.ai/docs/ai/skills Commit project-specific guidance for Momentic's runtime agents to your repository with .momentic/skills. Agent skills let you commit project-specific guidance for Momentic's runtime agents to your repository. Use them to describe how to start and reach the app under test, authentication and environment details, and any conventions the agents should follow. Agent skills are in beta and may change. ## Layout Each skill is a directory under `.momentic/skills` containing a `SKILL.md` file. You can use intermediate directories to group related skills: ```text theme={null} .momentic/ skills/ frontend/ app-startup/ SKILL.md triage/ SKILL.md ``` The directory containing `SKILL.md` defines the skill name, while the path from `.momentic/skills` identifies the skill. ### Where skills are discovered Skills conventionally live at the **repository root**. Momentic looks for a `.momentic/skills` folder starting at the project root (the directory containing `momentic.config.yaml`) and walking up through its ancestors, and uses the **first** one it finds. When your project root is a subdirectory of the repository, as in a monorepo, keep a single `.momentic/skills` at the repository root so every project in the repository shares it; a `.momentic/skills` folder nearer to a project root takes over entirely for that project. `SKILL.md` is Markdown with a YAML frontmatter block: ```markdown theme={null} --- name: app-startup description: How to build and serve the app under test. agents: [triage] --- Build the app with `pnpm build` and serve it on http://localhost:8888. Triage can assume that URL when reasoning about environment mismatches. ``` ### Frontmatter | Field | Required | Description | | ------------- | -------- | --------------------------------------------------------------------------- | | `name` | yes | Skill name. Must match the directory containing `SKILL.md`. | | `description` | yes | One-line summary of what the skill covers. | | `agents` | no | Which runtime agents the skill applies to. Omit to apply it to every agent. | The supported agent targets are `result-classification` and `triage`. ## How skills are applied * A skill applies to an agent when its `agents` list includes that agent, or when `agents` is omitted. Every applicable skill is always used. * Matching skills are combined in skill-name order, then path order when names match. Each skill's name, path, and description are added to the agent's instructions. * Target a single agent (e.g. `agents: [triage]`) to prompt that agent specifically. Target several agents to reuse the same guidance across them. * A skill with missing frontmatter, invalid YAML, an unknown agent target, an empty body, or a name that doesn't match its directory is skipped. Momentic prints a warning naming the file so you can fix it. ## Skills and prompt flags Some agents also accept prompt flags for one-off or path-specific guidance. [`momentic ai select`](/docs/cli-reference/momentic/commands/ai#select), for example, takes `--prompt`. Skills apply automatically and stack with any prompt flags, so you can commit shared guidance as skills and still pass one-off instructions per run. # List run groups Source: https://momentic.ai/docs/api-reference/analytics/list-run-groups /api-reference/openapi.json get /v1/run-groups List completed run groups with filters and pagination. # List runs Source: https://momentic.ai/docs/api-reference/analytics/list-runs /api-reference/openapi.json get /v1/runs List completed runs with filters and pagination. # API reference Source: https://momentic.ai/docs/api-reference/overview Reference for Momentic's external analytics endpoints. Use this reference to read external analytics data from Momentic. These endpoints are read-only, scoped to the org that owns the API key, and return completed runs only. ## Base URL | Environment | URL | | ----------- | ------------------------- | | Production | `https://api.momentic.ai` | ## Authentication Send the API key in an `Authorization` header on every request. ```bash theme={null} Authorization: Bearer $MOMENTIC_API_KEY ``` Create or manage keys in [API keys and team](/docs/account/api-keys-and-team). ## Shared request rules * All endpoints in this reference use `GET`. * All endpoints return completed runs only. * Multi-value query params are comma-separated. Whitespace around commas is trimmed. * `startDate` and `endDate` are optional ISO-8601 datetimes. The window may not exceed 92 days; wider windows return `400 {"error": "Date window must not exceed 92 days."}`. * Invalid query params return `400 {"error": "Invalid query: "}`. * If `startDate >= endDate`, the API returns `400 {"error": "Start date must be before end date."}`. ## Pagination List endpoints use cursor (keyset) pagination, which stays fast on deep pages. * Pass `pageSize` (max 100, default 20) to size each page. * Each response includes a `pagination` object: ```json theme={null} { "pageSize": 20, "hasMore": true, "nextCursor": "eyJmIjoxLi4ufQ", "total": null } ``` * To fetch the next page, pass the returned `nextCursor` back as the `cursor` query param. When `hasMore` is `false`, `nextCursor` is `null`. * `total` is `null` unless you pass `includeTotal=true`, which adds an exact match count at the cost of an extra aggregation. Use `hasMore` for simple "is there more?" checks instead. * Cursors are opaque; do not construct or parse them. An invalid cursor returns `400 {"error": "Invalid cursor."}`. ## Enum values | Field | Values | | --------------- | ---------------------------------- | | `status` | `PASSED`, `FAILED`, `CANCELLED` | | `trigger` | `WEBHOOK`, `CRON`, `MANUAL`, `CLI` | | `executionType` | `WEB`, `IOS`, `ANDROID` | ## Platform filtering `executionType` matches the run platform stored on each completed run. For run groups, a group matches when at least one run in the group matches the requested platform. For example, `executionType=IOS,ANDROID` returns mobile run groups. ## Endpoints Use the Analytics API section in the sidebar for the endpoint reference. # Goal-based testing Source: https://momentic.ai/docs/best-practices/goal-based-testing Build resilient tests around user outcomes, combining AI actions with precise preset steps and assertions. Goal-based tests describe the product outcome a user must reach without fixing the test to one sequence of interactions. They work best when the outcome is stable but the path can change. An AI action is how Momentic executes a goal-based step. It divides the goal into sub-goals, observes the current page or screen, executes the next steps, and evaluates the result. It repeats this process until the overall goal is complete. If a product bug or fatal execution error prevents the next sub-goal, the action stops and reports the blocker. It also stops if it exhausts its execution budget. Use a string for a straightforward goal. Use `act:` when the action needs a precondition, postcondition, cache control, or other step options. ```yaml checkout.test.yaml theme={null} fileType: momentic/test/v2 id: golden-cloud-compass steps: - Add a "Gravity Blanket" to the cart and complete checkout as a guest ``` ```yaml checkout.test.yaml theme={null} fileType: momentic/test/v2 id: golden-cloud-compass steps: - act: goal: Add a "Gravity Blanket" to the cart and complete checkout as a guest precondition: The storefront is open and the cart is empty postcondition: An order confirmation shows the purchased item and order number ``` ## Write bounded goals A strong goal has one user intent, enough context to remove ambiguity, and a clear stopping point. * Prefer `Add the cheapest in-stock blanket to the cart and open checkout`. * Avoid `Browse the store and make sure everything works`. * Include data constraints that matter, such as using a fresh email or choosing an in-stock item. * Split a long test by user outcome instead of asking one goal to cover an entire product journey. If the flow must repeat, state a finite bound or use a [while loop](/docs/core-concepts/steps#while-loops) with `maxIterations`. ## Postconditions The goal tells the AI action what to accomplish. A `postcondition` defines the product state that must be true before the action can pass. Add one to every meaningful or state-changing AI action: ```yaml theme={null} steps: - act: goal: Delete the current draft report postcondition: The draft is absent from the reports table ``` Describe a durable outcome, not a brief animation, spinner, or toast. Use a standalone assertion or element check when the checkpoint is independent of the AI action. For transient web UI, use a [run assertion](/docs/core-concepts/writing-assertions#run-assertions). ## Caching After a successful run, Momentic caches the steps generated by the AI action. Later runs replay that path instead of planning it again, making repeated runs faster and more consistent. If the cached path no longer works, failure recovery clears the cache so the action can plan a new path. Set `cache: false` when the route should be planned again on every run: ```yaml theme={null} steps: - act: goal: Open one of the currently featured products cache: false ``` The shorthand and explicit forms use the same cache behavior. See [Step caching](/docs/reliability/step-cache) for cache invalidation, branching, and failure recovery. ## Choose the right level of control Use an AI action when the outcome matters more than the exact interactions. Use a preset step when the interaction itself is part of the behavior under test. | Use | When | | ----------------------------- | -------------------------------------------------------- | | An AI action goal | The outcome is stable but the exact sequence can vary | | An AI action postcondition | The action must prove a durable outcome before it passes | | A preset step such as `click` | The exact interaction is important or already known | | An assertion or element check | A separate checkpoint must verify product state | These forms can coexist in one test. For example, an AI action can navigate a checkout flow while a preset step verifies a specific consent control and the postcondition verifies the final order. ## Knowledge base integration Use the [Knowledge base](/docs/ai/knowledge-base) to give every AI action consistent product context: * Add **Terminology** entries for product-specific names, internal aliases, and words that have a special meaning in your interface. * Add an **Agent rule** for the AI action agent when it should follow an organization-wide interaction convention or expected product behavior. * Add a **Flow** when a reusable journey has a known sequence and success state. AI actions retrieve relevant approved knowledge before they start and can look up more context while they run. When an action discovers a reusable term or flow that is not already captured, it can suggest a Knowledge base entry. The suggestion stays inactive until someone reviews and approves it, so future AI actions learn from shared product knowledge without silently changing global behavior. ## Related * [AI action reference](/docs/reference/commands/act) * [Step caching](/docs/reliability/step-cache) * [Writing assertions](/docs/core-concepts/writing-assertions) * [Knowledge base](/docs/ai/knowledge-base) # Test organization Source: https://momentic.ai/docs/best-practices/test-organization Directory layouts, naming, and labeling patterns that scale past a handful of tests. How to lay out, name, and label tests so the test suite stays navigable as it grows from a handful of tests to hundreds. ## Keep each test focused Organize a test around one user outcome. A test with dozens of unrelated steps is slower to diagnose and obscures which behavior failed. Split long journeys at durable checkpoints and share repeated setup through modules. Commit test changes with the product change they validate. Review goals, assertions, and locator changes with the same care as application code so a test cannot silently stop protecting the intended behavior. ## Start flat, split by domain later For the first 10-20 tests, keep everything in `tests/` at the project root. Once the directory becomes difficult to scan, split by **product domain**: ```text theme={null} tests/ auth/ login.test.yaml signup.test.yaml billing/ checkout.test.yaml onboarding/ welcome.test.yaml ``` ## Modules live alongside tests Put reusable [modules](/docs/core-concepts/modules) next to the tests that use them: ```text theme={null} tests/ modules/ login.module.yaml seed-org.module.yaml billing/ checkout.test.yaml ``` Or split by domain in larger projects: ```text theme={null} tests/ auth/ login.module.yaml login.test.yaml ``` ## Naming * `test.yaml` suffix for tests, `module.yaml` for modules, enforced by the default [globs](/docs/configuration/test-globs) * Lower-case kebab filenames: `checkout-with-coupon.test.yaml` * Test `id` is a kebab-case slug; keep it aligned with the filename so the on-disk identifier and on-disk path agree (e.g. `id: checkout-with-coupon` for `checkout-with-coupon.test.yaml`) * Group by **user outcome**, not implementation (`signup-with-sso`, not `click-sso-button`) ## Labels Labels are how you slice tests in the CLI and dashboard. Common labels: | Label | Meaning | | ---------------- | --------------------------------------- | | `smoke` | Critical paths run on every CI | | `regression` | Full nightly run | | `slow` | Tests > 2 min; skipped on pull requests | | `owner:payments` | Ownership for notifications | Label per-test in YAML: ```yaml checkout.test.yaml theme={null} fileType: momentic/test/v2 id: amber-meadow-compass labels: [smoke, owner:payments] steps: ... ``` Run a slice: ```bash theme={null} npx momentic run --labels smoke ``` ## Environment configuration Define [environments](/docs/configuration/environments) for every target: `local`, `dev`, `staging`, `production`. Each environment carries its own base URL, variables, and secrets. A single test runs everywhere without changes. Keep URLs, accounts, and credentials in environment variables instead of hard-coding them in tests. ## Shared fixtures Fixture data (mock users, API keys, seed scripts) lives outside `tests/`; most teams use `fixtures/` at the project root. Reference them from test variables or modules. # Product updates Source: https://momentic.ai/docs/changelog New updates and improvements ## Features ### Testing * An [AI action](/docs/core-concepts/agentic-testing) can now cache a conditional flow. When the agent meets UI that only sometimes appears, such as a cookie banner or an already-signed-in session, it records the branch as `If ` with the steps to take when the condition holds, so later runs replay the same decision from cache instead of re-running the agent. Existing caches keep replaying unchanged. Requires CLI `3.48.0` or `momentic-mobile` `1.24.0` to replay a cache that contains a conditional. See the [step cache](/docs/reliability/step-cache). * Failure recovery can now clear a stale AI action cache. When recovery has to step in because the cached actions no longer reach the goal, it drops the entry so the next run resolves the goal again from scratch instead of replaying the same dead flow. See [transient recovery](/docs/reliability/auto-maintenance#transient-recovery). * New `cache: false` option on an [`act`](/docs/reference/commands/act) step keeps the [AI action](/docs/core-concepts/agentic-testing) fully dynamic: Momentic replays nothing from cache and writes nothing to it. Use it for flows whose page content changes between runs, where a cached replay would go stale immediately. Available for web and mobile. * AI action no longer gates success on an auto-generated postcondition. When the agent claims a goal is done, an independent reviewer judges the settled app state, the actions the harness recorded, and your goal, and returns the step to the agent with its reasoning when the outcome is missing. A `postcondition` you author is still a protected requirement the reviewer must confirm. See the [AI action guide](/docs/guides/ai-actions/guide#assert-the-end-state-with-a-postcondition). * AI action can now read the page's accessibility tree, not only a screenshot, when it needs more than a screenshot can show. That covers canvas-rendered UIs and surveying the controls available before the agent gives up. * `browser.userAgent: null` disables Momentic's default user agent override so the browser presents its native user agent, which keeps UA-sniffed keybindings in step with the keys Momentic sends. The default is unchanged: browsers still present the fixed desktop Chrome user agent unless you configure otherwise. See [browser configuration](/docs/configuration/browser). ### Configuration * `momentic.config.yaml` sets project-wide element check timeouts and typing delays, so a slow CI environment no longer needs a per-step edit: [`browser.elementCheckTimeoutSeconds`, `browser.typeDelayMs`, and `browser.pressDelayMs`](/docs/configuration/browser) for web, and [`emulator.elementCheckTimeoutSeconds` and `emulator.keyPressDelayMs`](/docs/configuration/mobile) for mobile. A step that sets its own value always wins. ### Mobile * Mobile tests now wait for the screen to be ready before locating an element with AI, asking a vision model whether rendering has finished rather than only whether the screen stopped changing. A frozen splash screen and a blank content area are both perfectly still. [`emulator.smartWaitingTimeoutMs`](/docs/configuration/mobile) bounds every wait and retry on one interaction, and [`emulator.waitForStability`](/docs/configuration/mobile) now means the same thing on both platforms: settle after every step that can change the screen, off by default. * New [`emulator.jurisdiction`](/docs/configuration/mobile) (`us`, `eu`, or `as`) pins hosted emulators to a jurisdiction. Unlike `emulator.region`, which is a scheduling preference that falls back to another region when capacity runs out, a jurisdiction is a hard constraint: emulator creation fails rather than crossing the boundary, which is what data-residency requirements need. * [`installApp`](/docs/reference/mobile-commands/install-app) now works on iOS as well as Android, on local and hosted devices. The step takes a local path, a URL, or an `asset://channel/tag` reference to an app you uploaded to Momentic, so one test file can install the same build everywhere. iOS takes a `.app` bundle or a zipped `.app` bundle, and a hosted device installs from an asset reference or a public URL. Requires `momentic-mobile` `1.28.0`. * New [`emulator.localEmulatorStartTimeout`](/docs/configuration/mobile) raises the boot budget for local simulators and emulators, now 300s by default. Hosted CI runners boot a simulator far slower than a laptop does, and the boot failure now names the budget it exceeded and the setting to raise. * Running Android tests on hosted emulators no longer needs Android Studio, the Android SDK, or `adb` on your machine. The [Android quickstart](/docs/quickstart/android) and [app setup](/docs/platforms/android/app-setup) cover what is still required for local emulators. * Mobile test settings can point at an asset alias, such as `nightly`, instead of only an immutable build tag. See [hosted test environments](/docs/running-tests/hosted-test-environments). ### AI * New **AI routing** delivery mode for triage repairs: an agent attributes each distinct cause, commits repairs the branch under test caused, and opens one pull request per unrelated cause with a review requested from whoever owns it. A new **Default reviewer** setting catches repairs that attribution cannot tie to anybody. See [after a successful heal](/docs/reliability/auto-maintenance#after-a-successful-heal). * [Triage](/docs/reliability/auto-maintenance#permanent-healing) can revise a result classification when live browser evidence disproves the original diagnosis, and the revision only lands together with the repair attempt that produced the evidence. A classification you set by hand stays authoritative. * The [quarantine](/docs/reliability/auto-maintenance#quarantine) board records when a heal already proved a test unrepairable, so effort is not spent re-attempting it, and links to the run that produced the verdict. * [Triage is skipped for a run group with at least 20 failures and at least half its tests failing](/docs/reliability/auto-maintenance#large-scale-failure-limits): a suite failing that way is one outage, not many bugs worth triaging separately. * Result classification reuses an exact cache match instead of re-invoking the classifier, and short-circuits during a systemic outage where nearly every run is failing, which cuts the AI cost of a broken deploy. * Result classification separates a product defect that only the test environment reveals from a failure of that environment, so an environment problem is no longer reported as a bug in your application. * [Triage](/docs/reliability/auto-maintenance#triage) can finish with **No test change**, a successful outcome for a transient or external failure. Triage delivers a repair only when the test or a module changes, so a run no longer produces a pull request that only reformats a file. * Manual classification feedback in the run viewer now asks for a reason before you can submit it. ### Integrations * [Slack](/docs/integrations/slack) notifications can be routed per project: send auto-heal and [Explore](/docs/coding-agents/explore) alerts to different channels based on project name, project directory, repository, or branch. Rules live under **Settings > Notifications > Custom rules**, higher priority wins, and anything that matches no rule still goes to your default channel. ### Billing * Pay-as-you-go plans can set a **Monthly spend limit** under **Settings > Billing**. New tests and other credit-consuming work pause once your reported spend for the billing cycle reaches the limit, and an email alert goes out at the percentage you choose. Reported usage can lag, so small overages are possible. Managed plans are unaffected. ### Coding agents * New `$momentic-spec` skill for tests-first product specifications, installed with the other Momentic skills. MCP and Explore now live in their own [Coding agents](/docs/coding-agents/mcp-server) documentation section; the previous routes redirect. * Quarantined runs are now available through the [hosted MCP server](/docs/coding-agents/mcp-server). * MCP previews are pollable. `momentic_preview_step`, `momentic_preview_steps`, and `momentic_run_step` accept a `timeoutSeconds` limit, default 30 seconds, and longer work continues in the background under a `stepRunnerId` you collect with `momentic_poll_runner`. `momentic_preview_steps` also runs preset, AI action, and module steps through the same path. See [usage tips](/docs/coding-agents/mcp-server#usage-tips). * The MCP server can author AI action steps with caching disabled, matching the `cache: false` option in the test format. * MCP can filter run history by failure category and minimum attempt count. ### CLI * Quarantined tests run by default again in `momentic run` and `momentic-mobile run`, restoring the behavior from before `3.47.0`. Pass [`--skip-quarantined`](/docs/reliability/auto-maintenance#quarantine) to leave them out of a run. * Both CLIs print a rotating startup tip, mostly about invoking the `/momentic-test` (or `/momentic-mobile-test`) skill in your coding agent, since installing the [MCP server](/docs/coding-agents/mcp-server) and its skills does not activate them on its own. Tips never print in machine-readable output. * The setup wizard signs in without an interactive terminal, so a coding agent can run `npx @momentic/wizard@latest` on your behalf. It also offers only the editor tools it actually found on your PATH, and reports the real cause of a failed sign-in instead of a bare `fetch failed`. ### Dashboard * The run viewer's **Cache** section can now invalidate a stale entry: expand **Cached value** to read the stored locator or assertion, or choose **Clear step cache** so the next run resolves the step fresh with AI. Available for web and mobile runs, however they were triggered. See [results](/docs/running-tests/results#drilling-into-a-run). * Run groups and runs show which tests [AI selection](/docs/ai/select) picked and why: the run group's details pane gains an **AI test selection** tab with the mode, the counts, and the per-test rationale, and a run shows whether its group used selection. Selection also reads pull request and commit context, and handles a shallow CI checkout. * Directory filters on the runs and analytics pages now include subdirectories, so selecting `e2e/tests` also covers `e2e/tests/account`. The quarantine board gained the same directory filter plus saved views. * Runs and run groups produced by an outdated CLI are now flagged in the dashboard, next to the CLI version. * Filtering, searching, and paging the runs, run groups, quarantine, and pull request tables keeps the current rows on screen while the new page streams in, instead of flashing a skeleton. Hovering a row prefetches the run viewer, and live pages update when something changes rather than polling. * Thumbs up and down on AI output now record who voted, and your vote is shown when you reopen the run. * Timeout fields in the web and mobile editors show the default that applies when you leave them blank, which varies per command. ## Bug fixes * An AI action no longer caches and then repeats an action that its goal explicitly prohibited, on web and on mobile. * A run on hosted browsers now falls back to a second provider when the first cannot give it a healthy session, instead of failing the run. * [AI extract](/docs/reference/commands/extract) now honors [`browser.autoExpandIframes`](/docs/configuration/browser), so it reads a value inside an iframe without an explicit `iframe` target. An explicit target still wins. * [AI test selection](/docs/ai/select) now stops after 180 seconds and runs every in-scope test instead of holding up your pipeline. Change the limit with `--timeout`, and note that a timeout reports `fallbackToRunAll` in JSON output. Selection also accepts up to 1,000 changed files. * Failure recovery no longer forces a passing state when fresh evidence points at a bug in your application. The run fails with that evidence instead. * On iOS, [`emulator.autoAcceptAlerts`](/docs/configuration/mobile) answers a location permission prompt with **Allow While Using App** instead of leaving the test on the alert. * The sidebar usage widget no longer cuts a usage total off mid-word, and billing totals in a custom currency add up correctly. * A `retries` value of `1` is now saved in test settings instead of being dropped when the test file is written. * Keyboard shortcuts on a hosted browser now follow the hosted browser's operating system instead of the machine that runs the CLI, so a `Meta` shortcut from a Mac reaches a Linux browser as `Control`. * Auto-heal notifications say when a repair was already committed to your branch, no longer report a failed heal as covered by another test's fix, and no longer claim a test needs review when its failure was classified recoverable. * A routed repair whose reviewer GitHub refuses now falls back to another author from the same commits, then to your default reviewer, instead of reaching nobody. * Triage can identify who a failure belongs to when CI checks out a shallow clone. * Failure recovery no longer inflates `completedSteps` in `progress.json` by counting the temporary steps it injected. * A v2 test file that still uses the v1 `beforeSteps` / `afterSteps` keys now fails with a clear message instead of silently dropping those steps and dying later with an internal error. * `momentic run --skip-quarantined ` no longer swallows a test path as the flag's value and runs the whole suite. * Android runs no longer fail driver setup with an `ANDROID_HOME` error when the emulator is hosted, Appium gets more time to start on a slow machine, and a missing Android SDK fails immediately with setup instructions. * Soft Reset in the mobile editor clears step pass and fail statuses, and Android permission prompts no longer reappear after it when `autoGrantPermissions` is on. * Mobile tap steps that target x and y coordinates no longer load as an element description. * The editor no longer discards your last keystroke when you run a step straight after typing. * Failure recovery no longer hangs for hours when the browser stops responding. * Mobile typing spans no longer include the typed text. * The sidebar usage widget and the billing allocation rows no longer repeat one row per currency. * Editor performance: typing in a step no longer re-renders every step card, the browser canvas stops repainting while idle, and the web editor loads a project without a request waterfall. ## Features ### Testing * New [run assertions](/docs/core-concepts/writing-assertions#run-assertions): plain-English statements you expect to have been true at some point during a run, evaluated after the run finishes against frames sampled from the run's video. Use them for transient UI such as toasts, spinners, and pop-ups that appear and disappear too quickly for a step-based assertion to catch. Any failed run assertion fails the run, and video recording is enabled automatically for tests that define them. Available for web tests. The CLI needs [ffmpeg](/docs/core-concepts/writing-assertions#ffmpeg-requirement) to sample frames; cloud runs evaluate them on Momentic's infrastructure. * New [`fill`](/docs/reference/commands/type) alias sets an input's value in a single operation instead of typing it key by key, which is much faster for long values. Use it exactly like `type:` (for example `fill: "{{ env.PASSWORD }}"`) when per-keystroke events don't matter. * Web selector targets (the `css` field) now accept XPath expressions as well as CSS selectors. Momentic auto-detects XPath, so an expression such as `//button[@type='submit']` works in any web command's `css` field. See [targets](/docs/core-concepts/steps#targets). ### Editor * The step list now **auto-scrolls** to the currently executing step during a test run. If you scroll manually (wheel or touch), auto-scroll pauses; a **Follow execution** button appears at the bottom to re-enable it. * Multi-selecting steps and right-clicking now offers **Run selected**, so you can cherry-pick specific steps to execute without running the entire test. The `Cmd/Ctrl+Shift+Enter` shortcut runs all multi-selected steps. * Added **Move to top** and **Move to bottom** to the step right-click menu in both editors, for a single step or a multi-step selection. * Duplicate several selected steps at once from the step right-click menu. * Both editors now stream the step's execution trace live into the step detail as the step runs, so the trace waterfall fills in while the step is in flight instead of only appearing once it finishes. * Collapsed container steps (modules, conditionals) no longer unexpectedly expand when their child steps change status during a run. * Modules now expand automatically when first created or added through the step picker, so you can immediately edit their contents. * **Run to here** now starts after the last executed step, including nested steps inside modules, so it behaves as expected for partially-run tests. ### Mobile * `momentic-mobile run` now includes per-step timing in the [AI action](/docs/core-concepts/agentic-testing) trajectory output, matching web. * The mobile editor streams the step trace live into the step detail as the step runs, matching the web editor. ### AI * [Agent skills](/docs/ai/skills) (beta): commit project-specific guidance for Momentic's runtime agents to your repository under `.momentic/skills`. Each skill is a `SKILL.md` file with frontmatter that targets the `explore`, `triage`, or `result-classification` agents (or all of them), and you can group related skills in nested directories. * [Bug bash with the explore agent](/docs/guides/explore/bug-bash) (beta): `momentic ai bugbash latest` reuses the explore agent's journey discovery, walks each flow in a live browser, and files potential bugs (with severity, reproduction steps, and a screen recording) instead of authoring tests. See the new guide for prompt-file setup and reviewing findings. * The [explore agent](/docs/coding-agents/explore) now builds tests by default and always opens a live browser session so its analysis is grounded in the running app. Pass `--dry-run` to only discover and log the changed journeys without writing tests. * [`momentic ai explore`](/docs/cli-reference/momentic/commands/ai#explore) gained `explore diff [commitRange]` and `explore latest` subcommands. `explore` runs `diff` by default and, with no range, uses the current pull request's diff window. The old `--base` / `--head` / `--seed` flags still work but are deprecated. * `--granularity` levels are now clearly scoped: `low` covers the happy path of the main flows plus important failure states, `medium` covers the happy path of every interaction, and `high` covers every flow in depth including its failure modes. See the [explore agent](/docs/coding-agents/explore) reference. * The explorer shows its reasoning and tool calls in a fixed-height window that scrolls to the latest activity, so long runs stay readable. * Explore findings can now be triaged from the dashboard (beta): set a status and leave comments on a finding, flag duplicates against a canonical finding, and record a "works as intended" decision back to your [knowledge base](/docs/ai/knowledge-base) so the agent stops re-flagging it. * The **heal orchestrator** reads the locked `base..head` code diff before deciding how to repair tests, so it can tell intentional product changes apart from stale test drift. * The full **heal triage timeline** (orchestrator reasoning, recovery assessor calls, parallel subagent actions with before/after screenshots) is now captured in every heal-attempted run and viewable in the Run Viewer via the **Heal timeline** button. * [Failure recovery](/docs/reliability/auto-maintenance#transient-recovery) now shows how long the agent deliberated in the run viewer, and timeouts during recovery can only extend the wait; they no longer rewrite the step prompt. * [`momentic ai classify`](/docs/cli-reference/momentic/commands/ai#classify) reads from the result-classification cache by default when classifying multiple runs, writes new cache entries only with `--save`, and accepts `--no-cache` to skip cache reads and writes entirely. * [AI action](/docs/core-concepts/agentic-testing) can now look up your test's environment variables mid-run with a `get_environment_variables` tool, and it sees the goal you authored alongside the variable-substituted version. When a variable resolves to something empty or unexpected, the agent can notice and report it instead of silently acting on a bad value. * [AI action](/docs/core-concepts/agentic-testing) now receives context about the surrounding test (its name, description, and the steps before and after the current one), so recovery no longer undoes state that later steps depend on (for example dismissing an auth overlay a following step expects). * When an [AI action](/docs/core-concepts/agentic-testing) fails, the run now leads with a concrete summary of *why* it stopped: the blocker and the evidence the agent observed, rather than only narrating what it did. Runs that hit the agent's step budget now say so explicitly instead of showing a vague, unrelated message. ### MCP * `momentic_run_step` now returns within 30 seconds instead of blocking indefinitely. If the step range hasn't completed, the tool returns a `stepRunnerId` for polling via the new `momentic_poll_runner` tool. * `momentic_poll_runner` accepts an optional `timeoutSeconds` (0-30, default 0) to hold the poll open briefly rather than requiring busy-polling. ### CLI * New [`momentic doctor`](/docs/cli-reference/momentic/commands/doctor) and `momentic-mobile doctor` commands check installation health: CLI and Node versions, authentication, browsers, project configuration, and connectivity to the Momentic server. Pass `--fix` to remove deprecated configuration options and `--json` to emit the full report for a support ticket. Environment-related errors now point you at `doctor`. * New [`momentic list --changed`](/docs/cli-reference/momentic/commands/list) flag lists only the tests changed against the base branch, including tests that use a changed module. Pipe it into `momentic run` to re-run only what a pull request or a [Momentic auto-heal](/docs/reliability/auto-maintenance#permanent-healing) PR touched. * Terminal output across CLI surfaces is more consistent: home-directory paths render as `~`, API keys are redacted, remedy commands are highlighted, per-test warnings are shown once, and the CLI honors `CLICOLOR` / `CLICOLOR_FORCE` and no longer crashes when its output is piped to a command that exits early (for example `momentic ... | head`). * [`momentic upgrade`](/docs/cli-reference/momentic/commands/upgrade) and `momentic-mobile upgrade` now ask for confirmation before rewriting a project that is not yet on the [simplified format](/docs/get-started/migrate-to-simplified-format). Pass `--yes` to skip the prompt. * [`momentic ai triage`](/docs/cli-reference/momentic/commands/ai#triage) accepts `--interactive` to continue from the triage results into an interactive follow-up session. * A zero-test [AI selection](/docs/ai/select) is now reported instead of disappearing: the run group uploads without a `runs/` directory, [`momentic results merge --allow-empty`](/docs/cli-reference/momentic/commands/results#merge) keeps the selection plans from shards that ran nothing, `results check` treats a metadata-only directory as clean, and the pull request gets a comment saying selection ran 0 of N tests with the agent's reasoning. * Repository-committed [skills](/docs/ai/skills) are resolved from the repository root, so a monorepo's `.momentic/skills` is found when the CLI runs from a subdirectory. * New [New Relic reporter](/docs/guides/reporting/new-relic) pushes test results to New Relic as custom events, configured via the `reporting.newrelic` block in `momentic.config.yaml`. * The setup wizard now detects TLS certificate validation failures (common on corporate networks with intercepting proxies) and shows actionable guidance (`NODE_EXTRA_CA_CERTS` / `NODE_TLS_REJECT_UNAUTHORIZED`) instead of a raw stack trace. ### Dashboard * **Runs**, **Run Groups**, and the analytics pages let you save a filter combination as a named view and switch between your saved views. * The [explore](/docs/coding-agents/explore) exploration viewer (beta) now leads with findings instead of the trace, sorts bugs to the top, and adds a **View in trace** button on each finding that jumps to the responsible agent and seeks the video to the moment it occurred, all as a shareable deep link. Exploration runs that opened a pull request now link to it. * The runs page gained a **Created by Explore** filter, alongside the existing Quarantined, Recovered, and Healed filters. * The **Run Groups** list now shows each group's environment and platform, and the page gained a **Search by name** box to find a specific run group without paging through the list. * The Run Group page replaces the summary card with **View PR** and **View auto-heal PR** header buttons that link straight to the relevant pull request. * **Run group timeline bars** are now clickable: clicking a bar navigates directly to that test run's detail page, matching the existing behavior of the Y-axis labels. * The **Retries** column is back in the runs table after a brief absence. * The Run Viewer now shows how long each [AI action](/docs/core-concepts/agentic-testing) trajectory sub-step and heal-timeline span took, in the trajectory view and the step tooltip, on both web and mobile runs. * The Run Viewer's Failure analysis tab gained interactive triage feedback and a **Report error to Momentic** action, so you can send a run to us when a classification looks wrong. * The Knowledge item detail page has a **Usage** tab listing the runs that cited the item, each linking back to its run. See the [knowledge base](/docs/ai/knowledge-base#versioning-and-usage) reference. * The Usage page can break usage down by **label** (alongside trigger, test, suite, and API key). Date ranges are now anchored to your configured timezone so totals match your billing period, and the "credit usage over time" CSV export uses one row per day and group instead of one column per group. * The quarantine board shows each test's latest failure **classification** and gained a URL-persisted filter bar (category, last status, labels, and test-name search). * The Health and Failures analytics pages can now exclude quarantined tests, so quarantined runs no longer skew pass rate, flake rate, and failure-category charts. * The **Agents** and **Pull requests** pages are now in beta and open to any org with the explore or auto-heal agents enabled. * Notification settings are consolidated onto a single **Notifications** page under Features, covering cloud-run providers together with the Slack channels for test runs, auto-heal, explore, and quarantine. * The web and mobile editors now show per-step execution settings (timeout and retries) inline with the rest of a step's configuration. ### API * New [Analytics API](/docs/api-reference/overview): read-only REST endpoints for completed [runs](/docs/api-reference/overview) and run groups, authenticated with a Momentic [API key](/docs/account/api-keys-and-team). Supports cursor pagination, date-window and status filtering, and platform filtering across web, iOS, and Android. ### Integrations * Auto-heal pull requests now carry an `[auto-heal]` title tag and a dedicated description template so they are easy to spot and review. * Heal pull requests can assign and request reviews from the original commit authors of the healed tests, via two toggles in [Settings > Triage](https://app.momentic.ai/settings/triage). Both default to off. * GitHub PR status comments and Slack notifications now include a status icon and a per-run-group status table. * You can now clear the default Slack notification branch from settings. ### Configuration * New [`saveCacheOnCancel`](/docs/reliability/step-cache) option saves partial step caches when a run is cancelled or times out, instead of discarding them. * New [`disableLdistCacheValidation`](/docs/configuration/browser) browser option skips the Levenshtein-distance check during cached element resolution. ### Billing * Hosted browser session time (Azure Playwright) is now metered and settled asynchronously, so usage appears on your invoice alongside step credits. ## Bug fixes * Saving a test or module's metadata no longer rewrites the whole file, so a save that changes no content produces no diff. * Bug reproduction videos now follow the agent across tab switches, including tabs opened through the Playwright MCP browser, instead of recording a blank screen after a new tab opens. * `momentic upgrade` no longer renames user-defined JavaScript variables named `inputs` to `env` while migrating a test. * Saving a test with a long, multi-line [JavaScript](/docs/reference/commands/javascript) step no longer introduces unwanted line breaks in the code. * `Ctrl-C` now cancels promptly during `momentic ai explore`, even while the agent is running or validating steps. * Explore and heal browsers no longer close mid-run. * Browser install no longer crashes with `spawn su EACCES` when a system dependency install fails; it continues and reports the failure instead. * The [browser version mismatch](/docs/platforms/web/browsers) error now explains what to do (for example after upgrading the CLI). * Run Viewer heal playback is fixed: clicking a step seeks correctly, play resumes instead of restarting, and playback continues across multiple recorded videos. * The local editor's test options **Save** button no longer becomes disabled after switching tabs. * Fixed Slack notifications arriving mid-heal. Slack now waits for the heal to complete before posting to your channel. * GitHub run group summaries now use the same AI model as Slack summaries for consistent quality. * The Levenshtein-distance check on step-cache matching rejected valid cache hits; the threshold now accepts them. * Fixed mobile editor step list horizontal overflow. * Mobile [AI action](/docs/core-concepts/agentic-testing) V3 no longer offers the agent commands its own parser rejects, and an iOS session is documented with iOS commands rather than Android ones. ## Features ### Editor * Both the web (v3) and mobile editors gained Vim-style keyboard authoring: press `o` / `O` to insert a step after or before the current step, `Backspace` (or `Delete`) to remove the selected step(s), and `Shift+J` / `Shift+K` to extend a multi-step range selection (same as `Shift+Down` / `Shift+Up`). * Turn a multi-step selection into a reusable [module](/docs/core-concepts/modules) straight from the right-click menu in both editors with the new **Create module from steps** action. * The module creation dialog lets you pick the destination folder again, so new modules are saved where your scoped `include` patterns expect them instead of landing at the project root. * The mobile editor now shows a step number beside each step, matching the web editor and Run Viewer. * The mobile editor now includes the same **Find using description** locator control as the web editor on description-based target fields, so you can verify tap, type, element-check, scroll-to, and drag-and-drop targets before running the full test. * New [while loop](/docs/core-concepts/steps#while-loops) step repeats its body while a condition holds. The condition uses the same forms as a [conditional](/docs/core-concepts/steps#conditionals) and re-evaluates each iteration, and an optional `maxIterations` caps the number of passes (provide it on its own to repeat a fixed number of times). ### Mobile * [AI action](/docs/core-concepts/agentic-testing) V3 (the planner-style agent that drafts a flow up front, caches the resolved steps, and self-heals on failure) now runs on iOS as well as Android. * The mobile Run Viewer now shows the test's **tag** and expands [AI action](/docs/core-concepts/agentic-testing) V3 sub-steps, matching the web Run Viewer. * [`visualDiff`](/docs/reference/mobile-commands/visual-diff) now works on mobile: capture a full-screen screenshot and compare it pixel-by-pixel against a golden image stored on disk, the same way it works on web. * [`assertVisually`](/docs/reference/commands/assert-visually) now works on mobile. It evaluates the assertion from the screenshot only and skips capturing the accessibility/XML hierarchy, which helps when the screen is rendered in a way the hierarchy cannot describe (for example a WebView) or the condition is purely visual. * [`pressKey`](/docs/reference/mobile-commands/press-key) gained `repeat` and `delay`, so one step can press a key such as `backspace` several times, with an optional pause between presses, to clear a field. * `momentic-mobile run` now supports `allure` and `allure-json` reporters for iOS and Android, matching the web CLI's per-step report output. ### AI * The `locator`, `assertion`, and `visual-assertion` agents now default to **v4**, the new recommended versions, for new projects and organizations. Existing projects keep whatever version they have pinned. See the [agent configuration](/docs/configuration/ai) reference for the trade-offs. * [AI action](/docs/core-concepts/agentic-testing) V3 on web now draws on your [knowledge base](/docs/ai/knowledge-base) while authoring and healing, and can suggest new knowledge base entries for your team to review. * The [explore agent](/docs/coding-agents/explore) now supports `--granularity` for controlling plan depth, `--timeout` for bounded CI runs, seed-mode defaults of 60 minutes, JSON output, and first-class potential bug reports with reproduction steps. * Test healing now retrieves relevant [knowledge base](/docs/ai/knowledge-base) entries scoped to the test being repaired, including rules targeted at the heal subagent. ### CLI * `momentic ai heal` is now [`momentic ai triage`](/docs/cli-reference/momentic/commands/ai#triage), which groups failures, updates tests in place, and uploads a validation signal instead of only repairing tests. `heal` stays as a backward-compatible alias, so existing scripts keep working. The command also gained `--run-group-id` to target an uploaded run group, `--dry-run` to preview proposed fixes without writing them, `--json` for machine-readable output, and `--no-upload` to keep the results archive local. * The setup wizard (`npx @momentic/wizard@latest`) no longer scaffolds over an existing project. When a `momentic.config.yaml` is already present, it offers to (re)install skills, MCP, and browsers and bring the project up to date instead of overwriting your config or sample test. * New [`momentic results check`](/docs/cli-reference/momentic/commands/results) command gates CI on your local results: it exits non-zero when any non-quarantined run truly failed (failed or canceled, passed only via in-run failure recovery, or carrying a failure classification). Pass `--allow-recovered` to treat recovered runs as clean, or `--json` for a machine-readable report. * Result [classification](/docs/reliability/auto-maintenance#permanent-healing) is now controlled from `momentic.config.yaml` via `ai.classification.enabled`, and letting a classified failure pass CI is now strictly opt-in (`ai.classification.overrideExitCode`, or the `--classify-override-exit-code` switch on [`momentic run`](/docs/cli-reference/momentic/commands/run)). A new `ai.triage` block configures [`momentic ai triage`](/docs/cli-reference/momentic/commands/ai#triage). See the [AI configuration](/docs/configuration/ai) reference. * The [explore agent](/docs/coding-agents/explore) can now be run from the CLI with [`momentic ai explore`](/docs/cli-reference/momentic/commands/ai#explore) to draft tests from a git diff (beta). * [`momentic ai classify`](/docs/cli-reference/momentic/commands/ai#classify) and [`momentic ai triage`](/docs/cli-reference/momentic/commands/ai#triage) accept multiple `--run-id` values, so you can classify or triage several runs in a single invocation. * [`momentic snapshot`](/docs/cli-reference/momentic/commands/snapshot) captures a fully resolved, self-contained test zip, and [`momentic run --from-snapshot`](/docs/cli-reference/momentic/commands/run) replays it without reading modules, config, environment, or step caches from the current project. * `momentic run` and `momentic-mobile run` can emit a local [Momentic JSON report](/docs/guides/reporting/json-reporter) with structured statuses, skipped tests, failures, and classifications. * `momentic run` now writes live `progress.json` into the output directory while a run is active, and `--no-classify` skips AI classification for a one-off run even when classification is enabled in config. ### Dashboard * Failed runs without a current AI classification now show a **Classify with AI** button in the Run Viewer's Failure analysis tab, so you can start an AI classification on demand. The classification override popover also gained a **Clear manual override** action. * When auto-heal delivers changes, the Run Viewer's **Heal details** tab now links directly to the pull request or branch where the healed code landed. * The Run Viewer now shows web step cache status directly in the step detail pane, labels conditional outcomes inline as `= true` / `= false`, and groups retried steps into expandable `Attempt N` blocks. * Quarantine settings now live on a single **Quarantine** page (renamed from "Quarantine rules"), which also hosts the default Slack notification channel that previously sat on the Slack integration card. Existing links redirect automatically. ### Integrations * The GitHub App and connected-account cards now run a live health check and surface a **Needs re-auth** or **Update permissions** button when the stored authorization has stopped working or new permissions are required. * Connected accounts on your Profile now use a **Connected** dropdown to unlink. * The Slack channel picker now lists only the channels Momentic has been added to, instead of every public channel in the workspace. ## Bug fixes * [CHECK steps](/docs/reference/commands/check-element) backed by a stale cache entry no longer wait out the full timeout before relocating the element. * Creating a mobile test or module from the editor now creates the target folder instead of failing with a "directory does not exist" error. * You can now add a module before or after another module from the right-click menu, and pressing `Esc` while that menu is open no longer also closes the step detail pane. * Mobile **Single tap** steps no longer fail at runtime with `tapDelayMs requires iterations >= 2` after switching back from a Double or Triple tap. * The setup wizard now detects pnpm and yarn workspaces from a nested package, so it installs browsers instead of aborting inside a monorepo. * The file upload step no longer shows an "extension could not be detected" warning when the file source field is empty. * The Free plan billing card now shows your real step-execution quota instead of an internal token metric. * The web (v3) editor no longer briefly shows, or autosaves, another test's steps over the one you have open. * The unsaved-changes confirmation prompt is back in the web (v3) editor, so you no longer lose edits by navigating away. * The **Run to here** action is back in the web (v3) editor. * Steps dragged into a conditional can be opened again instead of staying stuck closed. * Module parameter fields keep multi-line JavaScript expressions intact instead of collapsing them onto one line. * Interactive mode no longer treats your keystrokes as editor shortcuts (or deletes the current step on Backspace) while you type into a step. * The editor keeps interactive authoring sessions open when an organization runs out of credits, instead of locking you out mid-edit. * [TYPE steps](/docs/reference/commands/type) accept a blank value again to clear an input. * A [`removeRouteMock`](/docs/reference/commands/remove-route-mock) step with no key (remove all mocks) no longer crashes the CLI when the test is saved back to disk. * `--ai-select` no longer reports a passing run when it matched tests but ran none of them. * The "browser not installed" error now names the specific browser you are missing instead of suggesting a mobile command to web users. * A single corrupt local-storage cache entry is now skipped instead of crashing the whole run. * Smart waiting no longer repeats the full stability check on every retry. * Disabled tests no longer run on a schedule. * Free-tier organizations are blocked from starting runs once they exceed their limits, over-quota mobile runs are rejected instead of leaving emulators running, and usage emails no longer mention overage charges that free plans cannot incur. * The Knowledge breadcrumb now returns you to the page you came from. ## Features ### Dashboard * The [failure recovery](/docs/reliability/auto-maintenance#transient-recovery) agent's trajectory is now visible in the Run Viewer, so you can see exactly what the agent did to recover a run. * The Run Viewer header now shows **Quarantined** and **Recovered** badges alongside heal status and classification, and reveals the quarantine reason on hover. * The Runs table gained a **Healed** filter, and the **Quarantined**, **Recovered**, and **Healed** filter chips now support inline *is / is not* toggles. * The Runs table can now filter by test **label**. * Mobile assets now appear in the cloud dashboard, grouped by channel in an expand/collapse table. ### Editor * The **web editor v3** continues toward general availability with step input forms for every command type, an output section (result, agent trajectory, and trace), AI-locate and click-to-locate buttons, an export-test dialog, configurable module steps, and a "using CSS selector" targeting option. * **Click**, **Type**, and **Scroll** steps now expose a "using x, y coordinates" toggle, and skipped steps are clearly indicated. * Drag steps between the **setup**, **main**, and **teardown** sections in both editors. * Pop out the **JavaScript** step editor for more room, and run the selected step from the keyboard with `Cmd+Shift+Enter` in the mobile and v3 web editors. ### Mobile * `momentic-mobile run` reached quarantine parity with the web CLI, adding [`--skip-quarantined`](/docs/cli-reference/momentic-mobile/commands/run) and `--only-quarantined` alongside the existing `--ignore-quarantine`. ### CLI * [`momentic ai triage`](/docs/cli-reference/momentic/commands/ai#triage) gained `--exclude` to drop tests from the triage queue by name regex. * [`momentic ai classify -i`](/docs/cli-reference/momentic/commands/ai#classify) keeps an interactive chat open after classifying, so you can ask follow-up questions about the run. * [`momentic upgrade`](/docs/cli-reference/momentic/commands/upgrade) and `momentic-mobile upgrade` migrate legacy YAML to the [simplified format](/docs/get-started/migrate-to-simplified-format), with `--dry-run` to preview changes before applying them. * [`momentic init`](/docs/cli-reference/momentic/commands/init) and `momentic-mobile init` now scaffold the simplified (`fileFormat: v2`) format directly. ## Bug fixes * `momentic ai triage --only-quarantined` no longer reports `FAILED` while handing CI a passing exit code. * WARN-classified failures no longer count against your CI exit code. * JavaScript step input forms no longer show a phantom validation error before you start typing. ## Features ### Dashboard * Updated the Run Viewer with a resizable panel layout, a floating step-details card, and inline step output, matching the new editor UI. * AI action version is now displayed in the Run Viewer settings for both cloud and mobile runs. * Run page **Reset** button now clears the Search parameter along with other filters. * You can now unquarantine a test directly from the Run Viewer, not just the Quarantine page. * [Quarantine rules](/docs/reliability/auto-maintenance#quarantine) now support two new metrics: **Recovery count** and **Recovery rate**, so you can quarantine/unquarantine tests based on how often they rely on [failure recovery](/docs/reliability/auto-maintenance#transient-recovery). * New multi-step **onboarding flow** for self-serve signups: provisions an organization, lets you invite teammates, optionally connects GitHub, and hands you off to `npx @momentic/wizard@latest` for scaffolding and a first run. * Self-serve users now have access to a **Billing** page with current plan, credit usage with overage warnings, upcoming invoice, invoice history, and a plan comparison table for upgrades. * Empty states on **Runs**, **Run Groups**, and **Quarantine** now show CLI commands and docs links instead of an empty table when an org has no data yet. * Runs page celebrates your first passing test with confetti. ### Editor * **AI Action V3** is now in public beta for web and mobile. V3 is the recommended AI action engine, with planned flows, cached generated steps, and self-healing replay. V2 remains available per step as a fallback. * Replaced the CodeMirror input for **JavaScript** steps with a Monaco editor that ships with autocomplete, typed runtime globals (`env`, `setVariable`, `axios`, `faker`, `moment`, `assert`), parameter hints, and syntax validation. * [Modules](/docs/core-concepts/modules) now support a **Default retries** setting under a new **Control flow** tab. Every invocation uses the module default unless it sets its own `retries` value. * Search HTML, screen XML, and accessibility trees directly in the editor (and the run viewer) with a new inline search bar (case-insensitive, with prev/next navigation). ### Mobile * Added iOS syslog streaming to the editor's device log panel, mirroring the existing Android logcat integration. * Added a pop-out dialog for the Monaco **JavaScript** editor in the mobile test editor so longer scripts are easier to read and edit. * The mobile JavaScript editor now autocompletes `env.` with your project's environment variable names. * Mobile editor's screen XML panel now deduplicates adjacent duplicate nodes and has improved row styling. * iOS webview targets are now cached, so repeat runs that interact with webview-embedded content resolve from cache instead of paying the full AI locator cost each time. * Upgraded mobile testing dependencies to resolve security advisories. ### MCP / Copilot * Web and mobile MCP servers both support a `--daemon` flag that keeps a persistent local daemon so sessions can be shared across separate MCP server invocations. See [`momentic mcp`](/docs/cli-reference/momentic/commands/mcp#daemon) and [`momentic-mobile mcp`](/docs/cli-reference/momentic-mobile/commands/mcp#daemon). Daemon mode is not yet available on Windows for mobile. * MCP tool calls routed through the daemon now stream progress notifications back to the caller in real time, so MCP clients see incremental updates as tools execute. * Tool logs now show a **Copilot** or **MCP** prefix so you can tell at a glance whether a tool call originated from the copilot or an MCP client. * New [Devin setup guide](/docs/integrations/devin) walks through configuring web and mobile Momentic MCPs for Devin sessions. * **iOS support landed across the mobile MCP toolchain**: `momentic_session_start`, `momentic_run_step`, `momentic_preview_step`, and `momentic_test_splice_steps` all now work against iOS sessions in addition to Android. Both remote and local iOS simulators are supported via `localDeviceId` (e.g. `iPhone 17`) and `localAppPath` (path to a `.app` bundle). Session step schemas are platform-aware and reject Android-only commands (e.g. `ADB_COMMAND`, `OPEN_NOTIFICATION_DRAWER`) on iOS sessions; use `APPIUM_EXECUTE` as the cross-platform replacement. ### CLI * **[`@momentic/wizard`](#)**: new interactive onboarding CLI (`npx @momentic/wizard@latest`) that walks you from zero to a passing test in about two minutes: platform selection, browser-based sign-in, CLI installation, project scaffolding, browser install, and first test run, all in one command. Credentials are stored in `~/.momentic/auth.json` and both CLIs fall back to that file when `MOMENTIC_API_KEY` isn't set. * The wizard now picks a **single platform** per run and surfaces MCP server + skills install commands after a successful test run. * [`momentic-mobile assets list`](/docs/cli-reference/momentic-mobile/commands/assets#list): lists asset channels and tags, with `--channel`, `--platform`, `--tag-filter`, and `--json` for scripting. * [`momentic ai classify`](/docs/cli-reference/momentic/commands/ai#classify) now accepts a full run URL (`https://app.momentic.ai/runs/`) in addition to a raw run ID. * New `--video` option on [`momentic-mobile run`](/docs/cli-reference/momentic-mobile/commands/run). Pass `true`, `false`, or `on-fail` to control video capture per run; `on-fail` records every attempt but discards videos for passing tests to keep result sizes manageable. * The end-of-run failure summary now prints a **YAML pointer** to the failing step, in the style of Playwright's `>` marker: the lines around the failure with `>` highlighting the exact step in your test file (or the imported module, when the failure happens inside one). ### Configuration * New [`timezone`](/docs/configuration/browser#browser-timezone) and [`useHostTimezone`](/docs/configuration/browser#browser-usehosttimezone) browser settings. Set a project-wide default timezone in `momentic.config.yaml` instead of configuring it per-test. `useHostTimezone: true` skips the override entirely and uses the machine's native timezone. * New [`bannedAttributes`](/docs/configuration/browser#browser-bannedattributes) browser setting. Specify HTML attributes that should be stripped from the accessibility tree and ignored when comparing cached elements. Use this for framework-generated attributes (e.g. `for`, `aria-controls`, `data-dynamic-*`) whose values change on every page load, causing unnecessary cache busting and noisy AI context. ### Integrations * New GitHub installs now have **PR status comments** enabled by default, without setting the toggle in integration settings. You can still turn them off in [Settings > Integrations](https://app.momentic.ai/settings/integrations) if you prefer. ## Bug fixes * Fixed a renderer crash on extremely large pages caused by accessibility tree fetching. * Fixed a bug where step execution continued past the module boundary when using **Run to step** inside a module. * Fixed cancellations being reported as successes in some CI runs. * Fixed pending runs getting stuck by tightening queue worker recovery. * Fixed unreadable white-on-white text in the video timeline step tooltip. * Normalized platform-specific paths returned from glob so test globs work consistently on Windows. * Clear-content steps now wait briefly between attempts to reduce flakiness on slow inputs. * Mobile driver now attempts to reconnect to Appium on transient failures instead of failing the run. * Fixed wizard showing a stale dashboard URL when the sample test run fails. * Fixed CI visibility page breadcrumbs not rendering. * Fixed duplicate settings overlay appearing in the mobile editor. * Fixed iOS finish step not running on remote simulators. * Fixed the copilot occasionally hallucinating invalid config formats. * Fixed the Monaco pop-out editor opening at an unusably small size. * iOS native elements now use the `text` attribute instead of `innerText` for more reliable text extraction. * Context tab no longer drops environment variables when switching between tabs in the editor. * OpenAI `server_error` responses are now recognized by the retry classifier, preventing silent failures on transient provider outages. ## Features ### Dashboard * Delete tests directly from the test details pane, and delete runs directly from the Runs page. * Row selection and bulk unquarantine in the [Quarantine](/docs/reliability/auto-maintenance#quarantine) table. * Cache bust reasons are now shown in traces, and caches can be [isolated per environment](/docs/reliability/step-cache). * Run Details panel now supports detachable panels for side-by-side debugging. * Frontend scripts that slow down rendering are detected and logged to the console during test runs. * [Memory](/docs/ai/memory) now uses AI to pick which memory entry to read. ### Mobile * iOS closed beta is live. Reach out in Slack to join. * [Modules](/docs/core-concepts/modules) are now supported on iOS. * Geolocation mocking support for iOS. * **AI extract** is now available for mobile tests. * Swipe step now supports relative coordinates. ### MCP / Copilot * Mobile MCP launched with splice, preview, and session creation tools. * Web and mobile MCPs can install Momentic skills with `npx skills add momentic-ai/skills` (see the [MCP integration guide](/docs/coding-agents/mcp-server)). * Module creation and preview tools added to MCP. * **Conditional** steps are now supported in MCP/Copilot. * Configurable MCP session idle timeout via `--timeout-ms`, and `--port` to run the Momentic app on a custom port. * MCP now infers when to run setup and teardown steps automatically. ### CLI * [`momentic init`](/docs/cli-reference/momentic/commands/init) now scaffolds a sample config and starter tests. * `buildkite-JSON` is available as a [reporter](/docs/running-tests/results#generating-local-reports). ## Bug fixes * Fixed **Click** steps that succeeded but were still marked failed, incorrectly triggering [failure recovery](/docs/reliability/auto-maintenance#transient-recovery). * Corrected **AI action** scrolling endlessly in the wrong direction on mobile. * **Conditional** actions now handle single quotes in element descriptions. * Resolved stale images appearing in browser preview during slow page loads. * Fixed the editor jumping back to a failed step when scrolling away. * Resolved silent MCP/Copilot crashes caused by unhandled type errors. * Fixed mobile taps timing out and crashing ADB connections. * Playwright-JSON reporter no longer reports `retries: 1` or produces malformed JSON. * Fixed video timestamp discrepancies in the Run Viewer. * Local apps no longer exit on non-critical errors. * Changing a step type to **Module** now sets default parameters correctly. * Removed the force-click fallback when Global Locator Redirect finds no eligible elements. * Fixed Run Viewer display for **Conditional** steps. * Long unbroken strings no longer overflow trace views. ## Features ### Dashboard * AI settings used during a test run are surfaced in the Run Viewer for easier debugging. * Runs that passed via [failure recovery](/docs/reliability/auto-maintenance#transient-recovery) now show recovery details and a **Recovered** badge in the Run Viewer, with a **Recovered** filter on the Runs table. * Failure Recovery now handles a wider range of scenarios, including failures within modules and longer action sequences, with a clearer UI for recovery details and suggested steps. * Multi-select filters on Runs, Run Groups, and Analytics. * Date-range picker and CLI version filter on the Runs and Run Groups pages. * Search bar on the [Quarantine](/docs/reliability/auto-maintenance#quarantine) page to filter by test name, plus a directory filter on quarantine rules. * Video player supports speed controls and smoother playback. * Network tab dropdowns in the Run Viewer now support multi-select. * Assertion V4 model rolled out with improved accuracy. * **Page check** assertions are now scoped to the document body, reducing false positives from non-visible page content. ### Editor * Test retries are now optional per-test and fall back to the organization's [`momentic.config.yaml`](/docs/configuration/momentic-config#retries) when unset. * Run a single step within a **Conditional** without triggering the assertion. ### MCP / Copilot * Granular MCP tools: individual tools for each step type instead of a single monolithic tool, with skill files for guided workflows. * Consolidated test and environment listing into a single MCP tool. * Added `resetSession` parameter to `momentic_run_step` for in-place session restart. * Added request listener, request recording, and mock route step types for AI agents. * Custom headers and device pixel ratio support on the MCP server. * [`momentic mcp`](/docs/cli-reference/momentic/commands/mcp) now accepts a flag to override headful/headless browser mode. * Caching is now supported in Copilot for faster repeat interactions. * New parameter for outputting test results to files. ## Bug fixes * Fixed an error when opening the Settings > AI page and the AI configs page failing to load due to a type error. * Fixed runs that passed via failure recovery not displaying the recovered badge. * Failed **Conditional** child steps are now properly skipped when using **Run to step**. * Fixed video timeline scrubber sync issues on short runs. * Test details panel now correctly updates the title when switching tests. ## Features ### Dashboard * Organization-level default browser setting (Chrome, Chromium, or Chrome for Testing) in [Settings](https://app.momentic.ai/settings/browser). Tests can use **default** to inherit this setting. * Pin specific sub-agent versions in [`momentic.config.yaml`](/docs/configuration/momentic-config) for consistent AI performance across CLI releases. * Video Player in the Run Viewer to watch recorded test run videos directly in the browser. * Filter the Analytics page by individual test for more targeted insights. ### Editor * **Conditional** steps now support JavaScript as an assertion, enabling programmatic branching logic. * [Memory](/docs/ai/memory) now supports **Conditional** steps, so assertion memory is saved and resolved for conditional blocks. * Undo/Redo is now supported in the editor. ### Mobile * [Failure recovery](/docs/reliability/auto-maintenance#transient-recovery) now available for mobile tests. * **Rotate Orientation** step added for mobile tests. * Error messages and details are now shown for failed mobile runs. * Undo/Redo is supported in the mobile editor. * iOS support: **AI check**, **AI tap**, WebView support, and iOS-specific agents launched. ## Bug fixes * Fixed the Save button remaining enabled after saving, which also prevented the Reset button from working. * **Conditional** steps no longer throw errors when used inside modules, and saving a new module parameter option no longer errors. * Cached modules now work reliably: auth state is no longer incorrectly restored when an invalidation rule is configured. * Modules can no longer be added inside other modules via the step chooser. * Fixed a full-page error when clicking a single day on the Usage page and a server components error affecting certain accounts on the same page. * Fixed editor performance issues and excessive battery drain during prolonged dashboard use. * **AI check** and **AI extract** steps are significantly faster. ## Features ### Dashboard * Runs that passed via [failure recovery](/docs/reliability/auto-maintenance#transient-recovery) are now visually indicated on the Runs page. * The Run Viewer auto-focuses and scrolls to the first failed step when opening a test result. * Navigate between steps in the Run Viewer using the arrow keys. * New `disableConsoleLogs` and `disableNetworkLogs` browser settings control log collection during remote runs, reducing CPU usage. ### Editor * AI reasoning and thoughts are now visible in the step pane. ### Mobile * **Screen check** step now available for mobile. * Added **Uninstall app** step type. * Step retries are supported for mobile tests. * **Element check** step now available for mobile. * **Drag and drop** step supported on mobile. * [Memory](/docs/ai/memory) is now supported for mobile tests. * APK asset details now shown in the mobile test overview. ### MCP / Copilot * Copilot now supports images for richer context. * MCP tool descriptions clarify how modules are edited. ## Bug fixes * Massive console logs no longer cause high CPU usage and crashes in remote runs. * Modules in the Run Viewer can now be collapsed again after expanding. * Fixed elements bleeding through the Run Viewer details panel. * Editing an assertion in a **Conditional** step no longer causes child steps to disappear, and **Conditional** steps now save correctly inside modules. * Fixed cached-action slowness for certain customer accounts. * Fixed mobile module updates not saving, and incorrect input values in model input forms. ## Features ### Dashboard * Released V3 AI models for locator, assertions, and visual assertions. Enable them in [Settings](https://app.momentic.ai/settings/ai) or via [`momentic.config.yaml`](/docs/configuration/ai). * With V3 locator models enabled, Momentic caches contextual elements in addition to the targeted element. * Videos of test runs can now be captured via the `--record-video` flag or [`recordVideo: true`](/docs/configuration/momentic-config#recordvideo). * Test caches now merge back into `main` when using GitHub or GitLab integrations. * Quarantined-test notifications can be routed to a specific Slack channel. * **AI smart waiting** prompt overhaul: faster models and better prompts for stability checks. * New `disableFullStory` [config option](/docs/configuration/browser#browser-disablefullstory) since FullStory's DOM mutation tracking can crash test automation. * Updated to the latest Playwright. ### Editor * Added **Conditional** step to support if-style branching: write an **AI check** assertion and perform nested steps when it passes. * **AI action** now supports **Drag and Drop** as a sub-step. * Env var search bar added to the editor. ### Mobile * Mobile editor UI refresh. * Geolocation mocking for Android. * **Close app** step and WebView speed improvements. * **AI action** v0 for mobile. * **Drag and drop** for mobile. * Mobile logs improvements in the editor. * Local-only mode for mobile tests, matching the web [CLI-only org setting](/docs/cli-reference/momentic/overview). ### MCP / Copilot * MCP/Copilot can now reference and use [modules](/docs/core-concepts/modules). * Notifications sent back to the caller from MCP during long-running actions. * Improved MCP tool descriptions for external agents (e.g. Roo). * Improved context management and richer return values from tools. ### CLI * New [`momentic quarantine list`](/docs/cli-reference/momentic/commands/quarantine) command prints all quarantined tests. * HTTP proxy support. * Test retries can be configured per step and per test. * More verbose logging for `momentic upgrade` and the correct upgrade command surfaced in version-check output. ## Bug fixes * Smart waiting now handles element-location stability when the cache cannot be used. * Updated libraries with security advisories across the CLI. * AI now considers alternative elements if the original target is ineligible, and **AI action** no longer attempts to interact with ineligible elements. * Improved V3 locator agent accuracy and reduced false positives. * Removed the conflict-resolution dialog between editor and disk; auto-save is now simpler. * Fixed a visual bug where **AI action** couldn't add child steps correctly. * Faster load times for quarantine rules. * Responses from recorded or mocked network calls are no longer redacted due to memory limits, and memory usage associated with storing network requests is reduced. * Error messages now reference a step's position within its test correctly. * Fixed incorrect detection of element changes between cache resolution and interaction, and mouse-drag command reliability. * Fixed typing into webviews and mobile taps crashing ADB. * Resolved a visual bug where Copilot could significantly extend page height, and network tab header overlap. * Runs search is now case-insensitive. ## Features * Tests that are Quarantined are now labeled as such in the Analytics page. * **Type** steps now support using relative positioning when interacting with an element. * V3 models for assertions, visual assertions, and locators are now in beta and can be enabled in Settings. * More verbose logs for long-running scripts are now shown in the Console tab. * Added a column in the Quarantine table for the last date the test was run. * Icon elements using the `` tag are now visible in the a11y tree. ## Bug fixes * Fixed a bug that caused caches to reset to the original cache after Element Check steps executed. * Resolved an issue where focusing the dashboard caused unexpected behavior. * Resetting a test while it is saving now shows a toast notification instead of quietly failing. * Test results with many steps are no longer truncated. * Locator no longer picks elements based on momentic-id if removed and added back into the DOM. * Scrolling now works as expected for XML viewers. * Larger pages are now pruned more efficiently to prevent delays caused by excessive RAM usage. * Sorting tests in the Quarantine table now works as expected. ## Features ### MCP Server * Use AI models to interact with your local Momentic tests via the desktop server. * Create and modify your tests without leaving your IDE. * Get started using MCP [here](model-context-protocol). ### Mobile App * Create and run tests written in natural language for Android. * Upload your APK and collaborate with your team on testing your mobile app. * See the [documentation](model-context-protocol). ### Additional features * Support for network [request mocking](request-mocking) for testing your frontend without running a backend, overwriting feature flag configurations, or testing error states. * Revamped Network tab for easier readability and navigation. * Tests that are removed from Quarantine no longer reenter Quarantine if they fail and must meet the threshold set in the Quarantine rules. ## Bug fixes * Resolved issue where filtering network logs would show unassociated logs. * Longer lists of variables in the Context tab are no longer truncated. * **AI extract** now supports all valid JSON schemas. ## Features ### Mobile Support * Beta testing for Android [Mobile Support](https://momentic.ai/blog/mobile) is now open. [Sign up here](https://momentic.ai/sales). * Author once in natural language and run across iOS (release date TBA) and Android. ### Copilot + MCP * [Copilot + MCP](https://momentic.ai/blog/copilot-mcp) now available in the Momentic local application. * Momentic Copilot with MCP adds natural-language test creation and execution to your local development workflow. ### Failure Recovery * [Failure recovery](failure-recovery) enables Momentic to auto-correct and retry tests when transient UI or network glitches occur, so only real regressions fail the run. * Failure recovery can be enabled via [`ai.failureRecovery`](/docs/configuration/ai#ai-failurerecovery) or at the per-test level. ### Suggestions & GitHub App * [Test Suggestions and GitHub](https://momentic.ai/blog/suggestions) app now available. * Momentic can now review your pull requests, surface relevant test execution context, and suggest precise edits you can apply with one click. * You can integrate your GitHub account with Momentic today in your account's [Settings](https://app.momentic.ai/settings/integrations). ### Additional features * Rules can now be set to automate test Quarantine in your account [Settings](https://app.momentic.ai/settings/quarantine-rules). * The GitHub integration can now post status messages directly on associated pull requests. * Steps can now be edited while a test is running in the Editor. * Retries can now be set at the step level. * **Element check** can now assert against computed styles. * Teardown steps that fail will now fail the entire test. * Native Slack app now available. Enable it in your account's [Integration](https://app.momentic.ai/settings/integrations) page. * [Memory](memory) is now out of beta and available to all Momentic users. * **AI extract** steps now validate schema before execution with the v2 schema. * Default user-agent now appends `Momentic/1.0 (+https://momentic.ai)` as a suffix to support anti-botting and Vercel automation, without affecting normal application behavior. ## Bug fixes * Fixed UI bug in the Usage page impacting customers with annual plans. * `momentic list` no longer truncates test names. * Fixed UI slowness when opening a test in the Repository view. * Values of variables in the GraphQL Request step no longer converts to a string. * AI model configurations in Settings now correctly shows the models in use. * Search results in the network viewer now shows only what is passed in the search input. * **AI action** steps now show Before/After screenshots in the Run Viewer. ## Features * Added AI Settings to select the AI agent version for locators, assertions, visual assertions, and text extraction. * Added Browser Settings to toggle Visual Click, zero-opacity elements, and Global Locator Redirect. * Introduced [Memory (beta)](/docs/memory) to use traces from past test runs for improved AI consistency and reliability. * Tests can now be [Quarantined](/docs/quarantine) to prevent them from failing pipelines, either manually or through automated rules. * Runs now display additional metadata. * Added the ability to duplicate modules. * Module parameters now support persistent options for inputs. * Rows in Runs and Repository can be opened in a new tab using CMD/CTRL + Click. * **Element check** now supports assertions on tag names, computed styles, and focus state. * Added more filters to the Run, Run Groups, and Analytics pages. * Updated the Network Viewer UI to show intercepted data. ## Bug fixes * Test descriptions now correctly update in the side panel when opening tests in the Repository. * Resolved an issue preventing API key creation. * Folders in different directories can now share the same name. * Fixed an issue where values in the GraphQL Request step were being converted to strings. * Screenshots now save correctly in all Runs. * Runs and Run Group results load much faster. * Moved the interaction mode warning outside the browser preview. * Fixed a UI crash when interacting with the Network Viewer. ## Features * Support for setup and teardown steps. * Hybrid selector mode for locators. * New sidebar for the local app that shows all folders. * New step to set headers * New `momentic list` command for easier integration with CircleCI. * Skipped tests are included in JUnit XML reports. * New keydown and keyup steps. * New step to wait for requests. * New module search experience with multiple tabs. * Clearer separation of global and local module configurations. * Be able to copy environment variable paths and values. * Table rows are now links. * You can now view initial navigation in the test trace. * Page and element check builder now supports syntax highlighting. * Labels are included in Junit XML reports. * Be able to duplicate modules in the local app. ## Bug fixes * `momentic import` now supports importing a much larger volume of tests. * Fix handling of zero opacity elements. * Opening a test link directly in the local app no longer show's an empty page. * Ungrouping a module no longer causes duplicate id errors. * Improved local app performance and navigation speed. * Search query is now debounced. * Screenshots in test traces now display with the correct dimensions. * Create and edit suite now paginates tests properly. * Test options dialog now scrolls. * Fixed option parsing for the CLI. ## Momentic 2.0 Momentic 2.0 is a major update with performance improvements, new features, and expanded configuration. * Test results are now saved locally by default. * Caching is now isolated per branch to prevent cross-branch cache contamination. * Project configuration now supports feature flags, protected branches, new AI settings, and more browser controls. * Chromium has been updated to the latest version, and Chrome for Testing is now supported. * Read our [v2.x migration guide](/docs/cli/migrate-v2) for details on how to transition. ## Features * Steps now appear in the module overview panel for easier inspection. * Time zone and geolocation can be configured in test options to simulate various regions. * Option to ignore href attributes in anchor tags. * Option to invalidate cache when an element's bounding box changes. * Local app search now includes all tests and modules within nested directories and subdirectories. ## Bug fixes * Improved handling of long page content to prevent selector errors on pages with a lot of HTML. * Credits in the billing view now properly reflect additions and rollovers. * Improved locators to distinguish between nearly identical elements. * Tests now honor the configured retry count when screenshots fail to capture. * Dropdowns with a large number of options are now scrollable. ## Features * Improved accuracy of recording on lengthy sites. * **Switch tab** now accepts template strings. * Download HTML and Download A11y tree in the debug pane of the test editor. * New CLI option to ignore autogenerated `href` attributes. * Tests can now be duplicated directly from the app. ## Bug fixes * React components that change classes no longer bust the cache. * [Failure recovery](/docs/failure-recovery) no longer removes **Element check** if they fail during a test. * Resolved an issue where scrolling in the browser preview or during Scroll steps did not match real-world behavior. * Fixed an issue that would sometimes cause the usage breakdown graph in Billing to not populate. * Changing the name of a module locally now updates the file name to match. * Addressed a compatibility issue affecting users on Node.js 20.19.0 or older caused by a breaking change in an upstream telemetry dependency. The CLI now pins that dependency to prevent similar failures in the future. ## Features * You can now upload files directly in Momentic. Use the File Upload step to upload files to your application during tests. * New search for modules in the editor. * Updated the repository's tree structure to support arbitrary folder nesting, making it easier to organize your tests and modules. ## Bug fixes * Uploading files larger than 5MB no longer causes a full-page error. * **Element check** now supports empty strings. * Assertions no longer cause elements to scroll into view. * Tests will no longer auto-save if validation errors are present. * Negative assertion results are no longer cached, so they are re-evaluated on every run. * Resolved navigation errors between multiple run attempts. * Local YAML test files will remain unchanged unless explicitly modified. ## Features * **AI action** has improved reasoning and self-healing capabilities. * Test runs with multiple attempts now allow viewing results for all attempts. * Momentic now displays Git information for CLI-executed tests. ## Bug fixes * Momentic now correctly sets MIME types for uploaded files. * Fixed incorrect labeling of tests running on main branches as `HEAD`. * Suite-level environments now correctly override individual test environments. * Addressed an issue preventing removal or modification of scheduled tests. * `npx momentic queue test` no longer queues disabled tests. ## Data retention policy updates * Screenshots and stop-level details will be kept for 3 months. * Run metadata will be kept for 6 months. * Analytics will be available indefinitely. ## Features * Analytics loads much faster and provides helpful insights to identify failing or flaky tests. * You can now view suite analytics, which aggregates analytics for all tests in a suite. * You can now view historical credit usage for suites and tests. * There are now steps in the editor for copy and pasting to and from the clipboard. * The editor now has a refresh button to refresh the page. * New buttons in the editor to move a step to the top or bottom of the test. * Suites now support setup and teardown. ## Bug fixes * Enabled `--headless=new` on Chromium * **AI action** now supports interpolated variables. * Creating a new test when viewing a folder now adds it to that folder. * Selecting more than 40 tests per page when creating suites no longer breaks the dialog. * Test export now exports labels. * Duplicated tests are now created in the same folder as the original. * Accepting email invites no longer fails with 500 errors. ## Failure recovery (beta) * Review proposed steps in the run viewer and apply them directly to tests stored in the dashboard or on your local machine through a CLI command. * Can be enabled on a per-test basis or globally in organization settings. ## Test and suite cancellation * Tests and suites running on Momentic dashboard can now be cancelled through the UI. ## Usage statistics * You can now view usage statistics for your organization in [settings](https://app.momentic.ai/settings/usage). ## AI improvements * We have developed new v1 AI agents for locating elements and evaluating assertions that perform 17% better on our benchmarks. * These agents should return more detailed thoughts and reasoning steps. * We back-tested these agents extensively and followed a gradual rollout process in the last few weeks. v1 agents are now the default for all organizations. ## Bug fixes * Fix a bug where the **Page check** assertions would fail because fetching the HTML took too long. * Improve the exponential backoff algorithm for **Page check** assertions, which sometimes led to lengthy pauses. * Improve execution logic when running an individual step within a module; if all sub-steps of a module have been ran individually, the module as a whole is marked as complete now. * Fix the logic for the "run to end" button when running a cached module. * Reduce memory and CPU usage caused by streaming browser screenshots. * Bump the max number of tokens that can be generated by AI agents for **AI check** steps. * Create a randomized test ID when importing a new test via ZIP file into the cloud app. * Restore the feature of test auto-saving on load in the editor. * Fix rare cases of the Chrome browser hanging indefinitely due to an underlying Chromium bug. ## New test tree view * Click on a test in the tree view to view detailed information about the test. Including the steps, estimated credits, and included modules. * Duplicate a test with a new name. * Manually run tests against different environments. * Delete a test directly from the tree view. * Manage labels and suites directly from the test view. * Schedule tests directly from the test view. * Configure and customize notifications that you receive from Momentic. You can use variables and test data to make it more informative. ## Step updates * Wait for URL now supports case insensitive matching and negative matching. * **AI check** now support vision-only mode that is tuned for visual checks. * A module can now be treated as a auth module. This will automatically save and restore the state of the module. Turn on "Treat as auth module" to enable this feature. * You can now use XY coordinates to target elements. This is useful when you want to click on a specific part of the screen. * Pressing keys now supports a delay between each key press. This is useful when you want to simulate typing. * Empty string is a valid value for the Type step. ## Debug data You can now see the HTML as well as the a11y tree in the editor and the test results. This will help you debug issues with your tests. We've also made updates to the console log and network logs viewers. ## Suites You can now set a default environment for a suite. This will be used when running tests in the suite. ## Reporting The CLI now supports outputting JUnit XML reports for test runs. You can use this to integrate with your CI/CD pipeline. ## Knowledge base We now have a dedicated knowledge base for customers to share detailed guides and tutorials. You can access it [here](https://momentic.ai/docs/guides) if you're a current customer. ## Performance We've written an in-depth guide on Momentic's performance characteristics. Check it out [here](/docs/performance). ## Bug fixes * Fixed a race condition when updating results. * Locator redirection now works in shadow roots. * Fixed concurrency issues with the Chromium browser in the CLI. * Include IndexDB in saved and restored auth state. * Updated mirror for stable channel Chrome. * Improved table serialization. * Updated **File upload** URL validation. * Retry failed email requests. * Fixed drag and drop. * Scroll now wait for the scroll to complete. * Updated the create suite dialogs to support >35 tests at a time. * Don't throw an error if a click times out after completion. * Make sure ungrouped steps have new ids. * Support Node 18 in the CLI. * Search will now preserve folders when searching. # CLI reference Source: https://momentic.ai/docs/cli-reference Pick the right Momentic CLI for web or mobile testing. Momentic ships two test-runner CLIs. They share a common shape (same flags for config, dashboard upload, sharding, reporting) but target different platforms. A third CLI, `mo`, drives [Mo](/docs/mo/index) sessions rather than running tests. Web test runner: drives Chromium, Google Chrome, and Chrome for Testing. Mobile test runner: drives iOS simulators and Android emulators. Mo agent: start, follow, and control Mo sessions from a terminal. Private beta. ## Shared flags Both CLIs accept the same flags for running tests, uploading results, and reporting: * `--upload-results`: push run data to the dashboard. * `--output-dir `: where to write local results. * `--shard-index` / `--shard-count`: shard a large test set across jobs. * `--labels `: run only tests with matching labels. See each CLI's `run` page for the full option list: * [`momentic run`](/docs/cli-reference/momentic/commands/run) * [`momentic-mobile run`](/docs/cli-reference/momentic-mobile/commands/run) # mo archive Source: https://momentic.ai/docs/cli-reference/mo/commands/archive Archive a Mo session you no longer need. Move a finished session out of the active list. Archiving stops any running work, tears down the session machine, and keeps the transcript and [report](/docs/mo/reports) in the dashboard. The session stops accepting new messages. ```bash theme={null} mo archive ``` ## Arguments The session to archive. ## Output On success the command prints `Archived Mo session .` ## Notes * Only the user who started a session can archive it. Archiving someone else's session fails with a not-found error. * Run your last [`mo download`](/docs/cli-reference/mo/commands/download) before archiving, because archiving removes the session machine. * `mo send` to an archived session fails. Unarchive the session in the dashboard to continue it. * Archiving does not stop a tunnel. Run [`mo tunnel stop`](/docs/cli-reference/mo/commands/tunnel) separately. # mo download Source: https://momentic.ai/docs/cli-reference/mo/commands/download Copy a file from a Mo session machine to your computer. Pull artifacts out of a session: recordings, logs, HAR files, or anything else Mo wrote to disk on its machine. Ask Mo for the path in the session, then download it. ```bash theme={null} mo download --session-id ``` ## Arguments Path of the file on the session machine. ## Options The session machine to copy from. Where to save the file. If the path is an existing directory, the file keeps its original name inside it. Otherwise the CLI uses the path as the file name and creates any missing parent directories. When omitted, the CLI saves the file under `MOMENTIC_ARTIFACTS_DIR` if that variable is set, or under `/.momentic-artifacts`. ## Output On success the command prints the local path it wrote and nothing else, so you can capture it in a script: ```bash theme={null} local_path=$(mo download /home/user/checkout.har --session-id "$session_id") ``` The CLI writes to a temporary name first and renames the file into place, so a failed download never leaves a partial file behind. ## Examples Save a recording next to your test results: ```bash theme={null} mo download /home/user/checkout.webm \ --session-id "$session_id" \ --output ./test-results/checkout.webm ``` Collect every artifact from a CI run into one folder: ```bash theme={null} export MOMENTIC_ARTIFACTS_DIR="$CI_ARTIFACTS/mo" mo download /home/user/report.json --session-id "$session_id" ``` ## Notes * The session machine must still exist. Download before you [`mo archive`](/docs/cli-reference/mo/commands/archive) the session. * `download` copies a single file. To fetch a directory, ask Mo to zip it first. # mo licenses Source: https://momentic.ai/docs/cli-reference/mo/commands/licenses Print third-party license notices bundled with the Mo CLI. The standalone `mo` binary embeds several open source executables. Use this command to review their license notices, for example when auditing what ships in a CI image. ```bash theme={null} mo licenses ``` ## Output The command prints the full third-party license text to stdout. Pipe it to a pager or a file: ```bash theme={null} mo licenses | less mo licenses > THIRD-PARTY-LICENSES.txt ``` ## Notes The notices are embedded only in the standalone binary from the installer. When `mo` runs from the npm package, this command reports that no license file is available; the npm package's dependencies carry their own license files in `node_modules`. # mo login Source: https://momentic.ai/docs/cli-reference/mo/commands/login Sign in with your Momentic account and save an API key. Authenticate the CLI once so every later command can reach the Momentic API. `mo login` opens a browser sign-in flow and writes the resulting API key to `~/.momentic/auth.json`, the same file used by `momentic` and `momentic-mobile`. ```bash theme={null} mo login ``` ## Options Do not open a browser automatically. The command prints the sign-in URL so you can open it yourself, for example on a headless machine. Momentic server URL to sign in to. Defaults to `https://api.momentic.ai`. Env: `MOMENTIC_SERVER`. ## `logout` Remove the saved API key. ```bash theme={null} mo logout ``` The command deletes `~/.momentic/auth.json`. Because the file is shared, this also signs out `momentic` and `momentic-mobile`. ## Notes * To skip the saved key for a single command, pass `--api-key ` or set `MOMENTIC_API_KEY`. Both take priority over the file. * In CI, set `MOMENTIC_API_KEY` instead of running `mo login`. Create keys in the dashboard; see [API keys and team](/docs/account/api-keys-and-team). # mo read Source: https://momentic.ai/docs/cli-reference/mo/commands/read Read new output from a Mo session. Read what Mo has said in a session. By default the command returns immediately with the transcript so far; pass `--timeout` to block until Mo finishes its current turn or asks a question, which is the usual way to follow a running session from a script or coding agent. ```bash theme={null} mo read --timeout 290s ``` ## Arguments The session to read, from the output of `mo start`. ## Options Maximum time to wait for new output. Accepts `0` (return immediately) or a value such as `30s`, `2m`, or `500ms`, up to `290s`. Loop the command to follow a long session. Where to read from. `start` returns the whole transcript plus anything Mo says while the command waits. `latest` skips the existing transcript and returns only output produced while the command waits, so a polling loop does not reprint earlier messages. Print the raw response as one JSON object instead of plain text. ## Output In plain-text mode, the command prints each message on stdout. Two status lines can appear on stderr: * `Mo is still working.` when the timeout ran out before Mo finished. * `Mo was stopped.` when the session state is `stopped`, for example after `mo stop` or a stop from the dashboard. With `--json`, the object has this shape: ```json theme={null} { "sessionId": "", "state": "waitingOnUser", "timedOut": false, "messages": [ { "role": "assistant", "text": "Which environment should I test?" } ], "pendingInput": { "id": "", "question": "Which environment should I test?", "options": ["staging", "production"] } } ``` `state` is one of `starting`, `working`, `waitingOnUser`, `waitingOnAgents`, `idle`, or `stopped`. `timedOut` is `true` when the command returned because the timeout ran out while Mo was still working. `pendingInput` is present only when Mo is waiting for an answer; reply with [`mo send`](/docs/cli-reference/mo/commands/send). ## Examples Follow a session until Mo stops working: ```bash theme={null} while true; do output=$(mo read "$session_id" --from latest --timeout 290s --json) jq -r '.messages[].text' <<<"$output" [[ $(jq -r .timedOut <<<"$output") == true ]] || break done ``` # mo send Source: https://momentic.ai/docs/cli-reference/mo/commands/send Send a message to a Mo session. Send Mo a follow-up instruction, answer a question it asked, or redirect a session that is going the wrong way. If Mo is working, `send` stops the active turn first: in-flight tool work is interrupted, and Mo resumes from saved history with your message. ```bash theme={null} mo send --session-id "Also check the account settings flow." ``` ## Arguments The message to deliver. ## Options The session to message. Wait for Mo's response for up to this long, then print the new output the same way [`mo read`](/docs/cli-reference/mo/commands/read) does. Accepts `0` or a value such as `30s`, `2m`, or `500ms`, up to `290s`. Without `--wait`, the command returns as soon as the message is delivered. ## Output Without `--wait`, the command prints the current session state as JSON. With `--wait`, it prints Mo's new messages as plain text on stdout and, when the wait runs out before Mo finishes, `Mo is still working.` on stderr. ## Examples Answer a question Mo asked, then wait for it to continue: ```bash theme={null} mo send --session-id "$session_id" --wait 120s "Use the second option: skip the payment step." ``` ## Notes * A message to an archived session fails. Unarchive the session in the dashboard first. * The delivery is retried once when the response is lost, so a message can be delivered even when the command reports a network error. Check with [`mo read`](/docs/cli-reference/mo/commands/read) before sending it again. # mo start Source: https://momentic.ai/docs/cli-reference/mo/commands/start Create a Mo session from a brief. Start a session by giving Mo a [brief](/docs/mo/brief) in plain language. The command returns as soon as the session exists; Mo keeps working in the cloud. Use [`mo read`](/docs/cli-reference/mo/commands/read) to follow its output. ```bash theme={null} mo start "Test the checkout flow on https://preview.example.com. Sign in with the staging QA buyer. Do not submit payment." ``` ## Arguments The brief. Include the target URL, credentials or how to get them, and any boundaries Mo must respect. ## Options Route Mo's traffic through a tunnel started with [`mo tunnel start`](/docs/cli-reference/mo/commands/tunnel). Required when the target runs on your machine or a private network. Give Mo read-only context from a GitHub repository connected to your organization. See [integrations](/docs/mo/integrations). Maximum number of sub-agents Mo runs at the same time. Must be an integer of `1` or more. The organization limit caps the value. How specific Mo's explore-agent test discovery should be: `low`, `medium`, or `high`. Defaults to `high`. ## Output The command prints one JSON object: ```json theme={null} { "sessionId": "", "webUrl": "https://app.momentic.ai/..." } ``` Keep `sessionId` for the other session commands. `webUrl` opens the session in the dashboard. ## Examples Start a session and follow it until Mo finishes or asks a question: ```bash theme={null} session_id=$(mo start "Bug bash the new billing page on https://preview.example.com" | jq -r .sessionId) mo read "$session_id" --timeout 290s ``` Test a local build through a tunnel: ```bash theme={null} tunnel_id=$(mo tunnel start localhost:3000 | jq -r .tunnelId) mo start "Smoke test http://localhost:3000 after the login refactor." --tunnel "$tunnel_id" ``` # mo status Source: https://momentic.ai/docs/cli-reference/mo/commands/status Get a snapshot of a Mo session, including its findings. Check where a session stands without reading its transcript. `status` returns the run state, the latest message, the dashboard URL, and everything Mo has reported so far: test cases, bugs, exercised controls, and bug bash verdicts. Use it to poll a session or to pull the [report](/docs/mo/reports) into a script. ```bash theme={null} mo status ``` ## Arguments The session to inspect. ## Output The command prints one pretty-printed JSON object: ```json theme={null} { "sessionId": "", "state": "active", "latestMessage": { "id": "", "role": "assistant", "text": "Finished the checkout flow. Filed 2 bugs.", "createdAt": "2026-09-02T04:12:33.000Z" }, "webUrl": "https://app.momentic.ai/...", "findings": { "testCases": [], "bugs": [], "controls": [], "verdicts": [] } } ``` * `state` is `active`, `completed`, `cancelled`, or `failed`, or `null` when no run state is available for the session. * `latestMessage` is `null` when the session has no visible messages. * `findings` arrays grow as Mo works. Each bug entry includes a name, summary, expected and actual behavior, and reproduction steps. ## Examples List the bugs Mo has filed so far: ```bash theme={null} mo status "$session_id" | jq -r '.findings.bugs[].name' ``` Wait until the session's run finishes: ```bash theme={null} until [[ $(mo status "$session_id" | jq -r .state) != active ]]; do sleep 30; done ``` ## Notes `status` is a point-in-time snapshot and never blocks. To wait for Mo's next output, use [`mo read --timeout`](/docs/cli-reference/mo/commands/read) instead. # mo stop Source: https://momentic.ai/docs/cli-reference/mo/commands/stop Stop the active turn of a Mo session. Interrupt what Mo is doing right now. Mo cancels its in-flight tool work and the session goes idle with its history intact, so you can resume it later with [`mo send`](/docs/cli-reference/mo/commands/send). Use it when Mo is testing the wrong thing or you want to pause the session. ```bash theme={null} mo stop ``` Add `--subagents` to stop the root turn and every active sub-agent turn: ```bash theme={null} mo stop --subagents ``` ## Arguments The session whose active turn to stop. ## Options Stop every active sub-agent turn after the root turn stops. You can send new instructions to those sub-agent conversations later. ## Output On success the command prints `Stopped Mo session .` Stopping a session that is already idle succeeds as well. ## Notes * `stop` does not archive the session. Use [`mo archive`](/docs/cli-reference/mo/commands/archive) when you are finished with it. * To stop and give new instructions in one step, use `mo send`, which stops the active turn before delivering your message. # mo tunnel Source: https://momentic.ai/docs/cli-reference/mo/commands/tunnel Let Mo reach localhost and private applications from your machine. Mo runs on its own machine, so it cannot see `localhost:3000` or an internal staging host. A tunnel exposes one or more `hostname:port` addresses from your machine to a single Mo session through a Momentic Connector. Start the tunnel, pass its ID to [`mo start --tunnel`](/docs/cli-reference/mo/commands/start), and stop it when the session is done. ```bash theme={null} mo tunnel start [--foreground] mo tunnel stop mo tunnel list ``` ## tunnel start Start a tunnel to one or more addresses. ```bash theme={null} mo tunnel start localhost:3000 mo tunnel start localhost:3000 api.internal:8080 ``` One or more `hostname:port` addresses reachable from this machine. Keep the tunnel attached to the terminal and run until you press `Ctrl+C`. By default the tunnel detaches and keeps running in the background. When the tunnel is ready, the command prints its ID as JSON: ```json theme={null} { "tunnelId": "tunnel-6f1c2a4e-..." } ``` In background mode the command returns immediately after printing. In foreground mode it prints the ID and then blocks; stopping the process also revokes the tunnel. ## tunnel stop Stop a tunnel and revoke Mo's access to it. ```bash theme={null} mo tunnel stop tunnel-6f1c2a4e-... ``` The command asks the local tunnel process to shut down, then revokes the Connector tunnel on the server. If the local process is already gone, the command still revokes the tunnel and prints a warning. On success it prints `{ "tunnelId": "..." }`. ## tunnel list List tunnels started from this machine. ```bash theme={null} mo tunnel list ``` ```json theme={null} { "tunnels": [ { "tunnelId": "tunnel-6f1c2a4e-...", "addresses": ["localhost:3000"], "mode": "detached", "pid": 48213, "startedAt": "2026-09-02T04:01:12.000Z", "status": "running" } ] } ``` `status` is `starting`, `running`, `unreachable` (the state file exists but the process does not respond), or `cleanup_failed` (the process exited without revoking the tunnel; run `mo tunnel stop` to finish cleanup). ## Example: test a local dev server ```bash theme={null} tunnel_id=$(mo tunnel start localhost:3000 | jq -r .tunnelId) session=$(mo start "Test the signup flow on http://localhost:3000" --tunnel "$tunnel_id") mo read "$(jq -r .sessionId <<<"$session")" --timeout 290s mo tunnel stop "$tunnel_id" ``` ## Notes * Tunnel state lives in `~/.momentic/mo-tunnels`. `mo tunnel list` only shows tunnels started from this machine. * One tunnel can serve several addresses; start it with every host Mo needs before you create the session. * A background tunnel outlives your shell. Stop it explicitly, or it stays open until you do. # mo upload Source: https://momentic.ai/docs/cli-reference/mo/commands/upload Copy a local file to a Mo session machine. Give Mo a file to work with: test data, a CSV of accounts, a spec, a build artifact. The command copies the file to the session machine and prints its path there. Pass that path to Mo in your next [`mo send`](/docs/cli-reference/mo/commands/send). ```bash theme={null} mo upload [destination] --session-id ``` ## Arguments Path of a local file. Directories are not supported. File name to use on the session machine. The CLI places the file in the session user's home directory and replaces characters other than letters, digits, `.`, `_`, and `-` with `_`, so a nested path becomes a single name. When omitted, the CLI stores the file as a session attachment under a generated path. ## Options The session machine to copy to. ## Output On success the command prints the absolute path of the file on the session machine and nothing else: ```text theme={null} /home/user/accounts.csv ``` ## Examples Upload test accounts and tell Mo to use them: ```bash theme={null} remote=$(mo upload ./fixtures/accounts.csv accounts.csv --session-id "$session_id") mo send --session-id "$session_id" "Use the accounts in $remote to test login for each role." ``` ## Notes * Always tell Mo the printed path. Uploading a file does not notify Mo by itself. * The session machine must exist. Uploads to an archived session fail. # mo version Source: https://momentic.ai/docs/cli-reference/mo/commands/version Print the installed Mo CLI version and check for updates. Confirm which build of `mo` you are running and whether a newer one is available. ```bash theme={null} mo version ``` ## Output The first line is always the installed version: ```text theme={null} 1.4.2 ``` The CLI then asks the Momentic server for the latest published version. If it differs from yours, a warning follows: ```text theme={null} New Mo functionality is available in 1.5.0. Please update Mo. ``` The check times out after five seconds and fails silently, so `mo version` works offline and always exits `0`. ## Options Momentic server to query for the latest version. Defaults to `MOMENTIC_SERVER`, then the server saved by [`mo login`](/docs/cli-reference/mo/commands/login), then `https://api.momentic.ai`. ## Update Re-run the installer to upgrade to the latest release: ```bash theme={null} curl -fsSL https://cli.momentic.ai/mo | sh ``` If you installed with npm, run `npm install -g @momentic/mo@latest` instead. ## Notes * `mo --version` prints the version number only, with no update check. * The check is informational. `mo version` does not install anything. # mo CLI Source: https://momentic.ai/docs/cli-reference/mo/overview Start, follow, and control Mo sessions from a terminal. Mo is in private beta. [Sign up](https://momentic.ai/mo) to get onboarded. The `mo` CLI drives [Mo](/docs/mo/index), Momentic's autonomous QA agent, from a terminal or a coding agent. Use it to start a session from a brief, read Mo's output, answer questions, move files in and out of the hosted sandbox, and open a tunnel so Mo can test an application on your machine. For a task-oriented walkthrough, read [Use the Mo CLI](/docs/mo/cli). ## Install ```bash theme={null} curl -fsSL https://cli.momentic.ai/mo | sh ``` The installer writes `mo` to `$HOME/.local/bin` on Linux and macOS (x86\_64 and arm64). Run it again to update. Set `MO_VERSION` to pin a version or `MO_INSTALL_DIR` to install somewhere else. The package is also published as `@momentic/mo` and requires Node `^22.12.0 || >=24.0.0`: ```bash theme={null} npx @momentic/mo --help ``` ## Commands Sign in and save an API key, or sign out. Create a session from a brief. Send a message to a session. Read new output from a session. Get a session snapshot with findings. Stop the active turn. Archive a session. Copy a file from the session sandbox. Copy a local file into the session sandbox. Let Mo reach applications available from this machine. Print the installed version and check for updates. Print licenses for bundled executables. ## Global flags Every command that talks to the Momentic API accepts these flags. Per-command pages document any other flags they accept. Momentic API key. Defaults to the value saved by `mo login` in `~/.momentic/auth.json`. Env: `MOMENTIC_API_KEY`. Momentic server URL. Defaults to the server saved by `mo login`, then to `https://api.momentic.ai`. Env: `MOMENTIC_SERVER`. One of `debug`, `info`, `warn`, or `error`. Defaults to `info`. Place it before the command name. ## Output Session commands print machine-readable output so a script or coding agent can chain them: `start`, `send`, `status`, and `tunnel` print JSON, and `upload` and `download` print a single path. `read` prints Mo's messages as plain text unless you pass `--json`. Status lines such as `Mo is still working.` go to stderr. ## Session IDs `mo start` prints a `sessionId`. Every later command takes that ID, either as a positional argument (`mo read `) or as `--session-id` (`mo send`, `mo upload`, `mo download`). You can also copy the ID from the session URL in the Momentic dashboard. ## Environment variables | Variable | Purpose | | ------------------------ | ------------------------------------------------------------------ | | `MOMENTIC_API_KEY` | Auth token. Overrides the key saved by `mo login`. | | `MOMENTIC_SERVER` | Override the API host. | | `MOMENTIC_ARTIFACTS_DIR` | Default directory for `mo download` when `--output` is not passed. | | `MO_VERSION` | Version for the installer script to install. | | `MO_INSTALL_DIR` | Directory for the installer script to write `mo` into. | ## Notes * The CLI shares `~/.momentic/auth.json` with `momentic` and `momentic-mobile`. Signing in with any one of them signs in all three. * `read --timeout` and `send --wait` accept `0` or a duration such as `500ms`, `30s`, or `2m`, up to a maximum of `290s`. * Every command exits `1` on an error and prints the reason to stderr. The waiting commands (`read`, `send --wait`, and `tunnel start`) exit `130` when you interrupt them with Ctrl+C. # momentic-mobile app Source: https://momentic.ai/docs/cli-reference/momentic-mobile/commands/app Open the local Momentic editor for authoring mobile tests. Launches the local Momentic editor against the project at `momentic.config.yaml`. Use it to author, edit, and debug mobile tests locally. ```bash theme={null} npx momentic-mobile app ``` ## Common flags Path to the Momentic configuration file. Defaults to `momentic.config.yaml` in the current directory. Port for the local editor server. Defaults to `58890`. Env: `PORT`. Region used for remote emulator sessions. Overrides any region configured at the project or environment level. Pass `closest` to autoselect the nearest region. ## Caching Disable step caches entirely for the session. Steps run without cached data and no caches are saved after runs. Always save updated step caches after successful runs, even on the main and other protected Git branches. See [cache saving eligibility](/docs/reliability/step-cache#cache-saving-eligibility) for the default behavior. Start from an empty cache state for the session. Step caches are still saved at the end of each run. Useful for refreshing caches after a config change. ## Local devices Force the editor to use a specific local Android Virtual Device (AVD) instead of a remote emulator. Override the APK installed on emulator initialization. Requires `--local-avd-id`. Force the editor to use a specific local iOS simulator device type. Accepts any option Xcode supports when creating a new simulator (e.g., `"iPhone 17"`). Override the iOS app installed on simulator initialization. Requires `--local-ios-device-type`. ## Examples Open the editor for the current project: ```bash theme={null} npx momentic-mobile app ``` Open the editor using a config in a sibling directory: ```bash theme={null} npx momentic-mobile app -c ../other-project/momentic.config.yaml ``` # momentic-mobile assets Source: https://momentic.ai/docs/cli-reference/momentic-mobile/commands/assets List, upload, download, and delete mobile assets on Momentic. Manage dashboard-hosted mobile assets (APKs and `.app` bundles). Each asset lives under a release channel (e.g. `staging`, `dev`) and is identified by a version tag. ```bash theme={null} npx momentic-mobile assets upload --channel --tag ``` ## `list` List available asset channels and tags for your organization, grouped by platform. Without any flags, prints a summary of every channel under each platform heading with its tag count and latest uploaded tag: ```text theme={null} ANDROID - momentic: 3 tags (latest 1.2.0) - other: 1 tag (latest v1) IOS - momentic: 1 tag (latest 2.0.0) ``` With `--channel `, prints the newest-first tags for that channel under each platform heading: ```text theme={null} ANDROID - momentic: - 1.2.0 - 1.1.0 - 1.0.0 IOS - momentic: - 2.0.0 ``` With `--platform `, only the requested platform is shown. ```bash theme={null} npx momentic-mobile assets list ``` ### Options Channel to show tags for. When omitted, the command prints the channel summary view instead of tags. Filter results to a specific mobile platform. One of `android` or `ios`. Case-insensitive substring filter applied to tag names when listing a channel. For example, `--tag-filter 1.2` matches any tag that contains the text `1.2`. Emit machine-readable JSON output instead of text. Summary mode (no `--channel`) returns a `platforms` array, each with its channels, tag counts, and the latest uploaded tag: ```json theme={null} { "platforms": [ { "platform": "ANDROID", "channels": [ { "channel": "momentic", "tagCount": 3, "latestTag": "1.2.0", "latestUploadedAt": "2026-04-20T17:53:07.049Z" } ] }, { "platform": "IOS", "channels": [ { "channel": "momentic", "tagCount": 1, "latestTag": "2.0.0", "latestUploadedAt": "2026-04-08T23:37:20.541Z" } ] } ] } ``` Tag list mode (with `--channel `) returns the `channel` name and a `platforms` array whose `tags` are ordered newest-first: ```json theme={null} { "channel": "momentic", "platforms": [ { "platform": "ANDROID", "tags": [ { "tag": "1.2.0", "md5": "qrNr9GyYYmx4P6+ZwLcooQ==", "uploadedAt": "2026-04-20T17:53:07.049Z" }, { "tag": "1.1.0", "md5": "oE9fZ8whKPWXbyaFWDM4BA==", "uploadedAt": "2026-04-01T12:00:00.000Z" } ] } ] } ``` ## `upload` Upload a mobile asset to the Momentic dashboard. After upload, the asset is available in both the interactive editor and in test runs. Supported formats: Android APK (`.apk`) and iOS `.app` directory (development build). See [iOS app setup](/docs/platforms/ios/app-setup) for building a testing-ready `.app`. ```bash theme={null} npx momentic-mobile assets upload --channel --tag ``` Uploaded assets are immutable: a `(channel, tag)` can only be re-uploaded with identical bytes. To publish a new build, upload it under a new tag (or delete the existing tag first). When `--tag` is omitted, a tag is generated for you and printed in the command output. A test that omits the tag, or uses the reserved tag `latest`, resolves to the most recently uploaded asset in the channel. ### Arguments Path to the asset to upload. Must be an `.apk` file or an `.app` directory. ### Options **Required.** Release channel for the asset, such as `staging` or `dev`. This name affects how the asset will be referenced by tests. Channels cannot be renamed after creation. Version label within the channel, such as a semantic version like `0.0.1`. When omitted, a tag is autogenerated and printed in the command output. `latest` is reserved and cannot be used as a tag; tests that reference `latest` (or omit the tag) resolve to the most recently uploaded asset in the channel. Floating alias to repoint at this build, such as `nightly` or `stable`. Aliases are per-platform and move on each upload, while the underlying tagged bytes stay immutable, so a test referencing the alias always resolves to the most recently aliased asset. `latest` is reserved and cannot be used as an alias. ## `download` Download an APK from the Momentic dashboard to the local machine. ```bash theme={null} npx momentic-mobile assets download --channel --tag ``` ### Arguments Optional path to download the asset to. Can be a directory or a file path. If omitted, defaults to the current working directory. If a directory is provided, the file will be named `-.apk`. ### Options **Required.** Release channel for the asset to download. **Required.** Version label within the channel to download. ## `delete` Delete a previously uploaded mobile asset. The command prompts for confirmation before deleting. ```bash theme={null} npx momentic-mobile assets delete --channel --tag --platform ``` ### Options Release channel of the asset to delete. Version label of the asset to delete within the channel. Platform of the asset to delete. One of `android` or `ios`. ## Examples List the most recent tags for the `staging` channel as JSON: ```bash theme={null} npx momentic-mobile assets list --channel staging --json ``` Upload a staging APK tagged `1.2.0`: ```bash theme={null} npx momentic-mobile assets upload ./app-staging.apk --channel staging --tag 1.2.0 ``` Upload a build and repoint the `nightly` alias at it so tests referencing `nightly` resolve to this build: ```bash theme={null} npx momentic-mobile assets upload ./app-staging.apk --channel staging --tag 1.2.0 --alias nightly ``` Download a specific tag into the current directory: ```bash theme={null} npx momentic-mobile assets download --channel staging --tag 1.2.0 ``` Delete a specific asset: ```bash theme={null} npx momentic-mobile assets delete --channel staging --tag 1.2.0 --platform android ``` # momentic-mobile doctor Source: https://momentic.ai/docs/cli-reference/momentic-mobile/commands/doctor Check the Momentic Mobile CLI installation and project for problems. Runs a read-only health check of your Momentic mobile setup and prints a section-by-section report: CLI version, authentication, connectivity to the Momentic API (including TLS interception, WebSocket support, clock skew, and proxy settings), environment, the mobile toolchain (adb and `ANDROID_HOME`, required even for remote emulators, plus the bundled Appium drivers and the local-emulator-only Java setup), reachability of the remote emulator provider, installed browsers (including missing OS libraries needed to launch them), and your project configuration (deprecated options, legacy file format, agent versions that have a newer release available, and tests that target a local emulator or simulator when the local toolchain for their platform is missing). Problems are listed at the end with a suggested fix for each, and the command exits non-zero when any are found. Warnings do not affect the exit code. ```bash theme={null} npx momentic-mobile doctor ``` ## Options Momentic API key. Defaults to `MOMENTIC_API_KEY` or the key saved by `momentic-mobile login`. Path to the Momentic configuration file. Defaults to `momentic.config.yaml` in the current directory. Remove deprecated options from the project configuration file. Output the report as JSON. Useful for attaching to support tickets. ## Examples Check the installation and project: ```bash theme={null} npx momentic-mobile doctor ``` Generate a machine-readable report for a support ticket: ```bash theme={null} npx momentic-mobile doctor --json ``` # momentic-mobile init Source: https://momentic.ai/docs/cli-reference/momentic-mobile/commands/init Scaffold a new Momentic mobile project in the current directory. Creates a [`momentic.config.yaml`](/docs/configuration/momentic-config) and the project layout used by the rest of the mobile CLI. The command prompts before overwriting any existing files. ```bash theme={null} npx momentic-mobile init ``` New mobile projects are scaffolded with `fileFormat: v2`. Sample tests and modules emitted by the [onboarding wizard](https://www.npmjs.com/package/@momentic/wizard) are written in the simplified format directly, so no follow-up migration is needed. Existing v1 mobile projects should run [`momentic-mobile migrate simplified-format`](/docs/get-started/migrate-to-simplified-format) instead of re-running `init`. ## Options Project name to write into the generated `momentic.config.yaml`. When omitted, the wizard prompts for one and defaults to `app`. Accepts the defaults for every prompt so the command runs in a non-TTY shell such as CI or a coding agent. The project name defaults to `app` unless `--name` is given. ## Examples Scaffold a project in the current directory: ```bash theme={null} npx momentic-mobile init ``` Scaffold a project without any prompts: ```bash theme={null} npx momentic-mobile init --yes ``` Scaffold a project non-interactively with a fixed name: ```bash theme={null} npx momentic-mobile init --name shopping-app ``` # momentic-mobile install-browsers Source: https://momentic.ai/docs/cli-reference/momentic-mobile/commands/install-browsers Deprecated. Mobile tests do not need a local browser. This command is deprecated. Mobile tests automate webviews on the device or emulator, so no local browser is needed. The command stays available for backward compatibility. Downloads Chromium-based browsers onto the local machine. ```bash theme={null} npx momentic-mobile install-browsers chromium ``` ## Arguments Browsers to install, separated by spaces. Available choices: `chromium`, `chrome`, and `chrome-for-testing`. ## Options Reinstall the specified browsers even if they already exist on disk. Install every supported browser (`chromium`, `chrome`, and `chrome-for-testing`). ## Examples Install the Chromium browser: ```bash theme={null} npx momentic-mobile install-browsers chromium ``` Install every supported browser at once: ```bash theme={null} npx momentic-mobile install-browsers --all ``` Reinstall Chromium: ```bash theme={null} npx momentic-mobile install-browsers chromium --force ``` # momentic-mobile install-skills Source: https://momentic.ai/docs/cli-reference/momentic-mobile/commands/install-skills Install Momentic mobile skill files for coding agents (deprecated). `momentic-mobile install-skills` is deprecated. Use the standalone `skills` CLI instead: ```bash theme={null} npx skills add momentic-ai/skills ``` Installs Momentic mobile skill markdown so coding assistants get explicit instructions for the Momentic MCP. See the [MCP integration guide](/docs/coding-agents/mcp-server) for the full setup flow. ```bash theme={null} npx momentic-mobile install-skills --editor ``` ## Legacy command Only use this command if you are pinned to an older version of Momentic and need an older version of the skills. Skills give coding agents explicit instructions for using the Momentic MCP. Without them, agents are more likely to make malformed tool calls. Run this after configuring the MCP server. ### Options Editor whose skill directory to write into. One of `cursor`, `claude-code`, `codex`, `opencode`, or `copilot`. ### Install location Inside a git repository, the skill installs at `/`. Outside git, it installs at `/`. | Editor | Path | | ------------- | ------------------------------------------------ | | `cursor` | `.cursor/skills/momentic-mobile-test/SKILL.md` | | `claude-code` | `.claude/skills/momentic-mobile-test/SKILL.md` | | `codex` | `.agents/skills/momentic-mobile-test/SKILL.md` | | `opencode` | `.opencode/skills/momentic-mobile-test/SKILL.md` | | `copilot` | `.github/skills/momentic-mobile-test/SKILL.md` | ## Examples Install skills for Cursor: ```bash theme={null} npx momentic-mobile install-skills --editor cursor ``` Install skills for Claude Code: ```bash theme={null} npx momentic-mobile install-skills --editor claude-code ``` # momentic-mobile lint Source: https://momentic.ai/docs/cli-reference/momentic-mobile/commands/lint Validate Momentic simplified format mobile test and module YAML files. Validate simplified format mobile test and module YAML files: schema, local file references (modules, JS steps, JSON files), and entity ID conflicts. Applies only to files with `fileType: momentic/mobile-test/v2` or `fileType: momentic/mobile-module/v2`. Lint runs automatically before starting the local mobile app and before executing tests, so normal app and test workflows already block invalid YAML. Use this command for fast standalone validation in pre-commit hooks, in CI, or after agent-authored edits. ```bash theme={null} npx momentic-mobile lint ``` ## Arguments Path to a single `.test.yaml` or `.module.yaml` file to lint. Defaults to the entire project, which can take several seconds in large workspaces. ## Options Path to the Momentic configuration file. Defaults to `momentic.config.yaml` in the current directory. ## Examples Lint the entire project: ```bash theme={null} npx momentic-mobile lint ``` Lint a single test file: ```bash theme={null} npx momentic-mobile lint mobile-tests/login.test.yaml ``` # momentic-mobile list Source: https://momentic.ai/docs/cli-reference/momentic-mobile/commands/list List local Momentic mobile tests matching a pattern. Prints one test file path per line for every test in the current project that matches the provided filters. Intended to be piped into other commands. Requires tests to exist locally as YAML files. ```bash theme={null} npx momentic-mobile list ``` ## Arguments Tests to list, given as test file paths, directories, or test-name substrings. Defaults to every test in the current project. ## Common flags Path to the Momentic configuration file. Defaults to `momentic.config.yaml` in the current directory. When using [workspaces](/docs/configuration/workspace), load the project whose name matches the filter. ## Filtering Only include tests with one of the specified labels. Only include tests whose file path matches any of the provided regex patterns. The pattern only needs to match part of the path. Exclude tests whose file path matches any of the provided regex patterns. ## Examples List every test in the project: ```bash theme={null} npx momentic-mobile list ``` List tests under a specific folder: ```bash theme={null} npx momentic-mobile list tests/login ``` List tests then pipe into `run`: ```bash theme={null} npx momentic-mobile list tests/login | xargs npx momentic-mobile run ``` # momentic-mobile mcp Source: https://momentic.ai/docs/cli-reference/momentic-mobile/commands/mcp Run the Momentic mobile MCP server for coding agents. Starts the Momentic mobile MCP server over stdio so coding agents can author, run, and triage iOS and Android tests. See the [MCP integration guide](/docs/coding-agents/mcp-server) for editor-specific setup. By default, sessions open a `localhost` page with a remote control UI for viewing and interacting with the emulator. ```bash theme={null} npx momentic-mobile mcp ``` CLI flags override environment variables. ## Common flags Authenticates the MCP server with Momentic APIs. Env: `MOMENTIC_API_KEY`. Path to the `momentic.config.yaml` file used to load project tests, modules, and environments. ## Toolchain Set `ANDROID_HOME` for the current MCP process. Env: `ANDROID_HOME`. Set `JAVA_HOME` for the current MCP process. Env: `JAVA_HOME`. ## Session Whether the remote control browser opens with a visible UI by default. Defaults to `true`. Allow MCP tool responses to include file output references. Defaults to `true`. Disable for clients that cannot resolve file references. Idle timeout for MCP sessions in minutes. Defaults to `5`. Sessions inactive for this duration are terminated automatically. Env: `MOMENTIC_SESSION_IDLE_TIMEOUT_MINUTES`. ## Caching Always save updated step caches after successful runs, even on the main and other protected Git branches. Disable step caches entirely for the MCP session. Steps run without cached data and no caches are saved. Create a persistent local daemon so mobile sessions can be shared across multiple MCP server invocations. The daemon's working directory is set to the parent of the config file, so MCP servers launched from different directories share device sessions and other state. Daemon mode is not yet available on Windows. Use the standard stdio mode on Windows for now. ## Examples Start the MCP server using the project's `momentic.config.yaml`: ```bash theme={null} npx momentic-mobile mcp ``` Run with custom Android and Java toolchain paths: ```bash theme={null} npx momentic-mobile mcp --android-home ~/Library/Android/sdk --java-home /opt/homebrew/opt/openjdk@17 ``` # momentic-mobile migrate simplified-format Source: https://momentic.ai/docs/cli-reference/momentic-mobile/commands/migrate Rewrite local mobile tests and modules from legacy YAML to the simplified format. `momentic-mobile migrate simplified-format` is the narrow file-only migration. It rewrites every legacy mobile `*.test.yaml` / `*.module.yaml` in the project through the simplified format serializer and flips `fileFormat: v2` on `momentic.config.yaml`. It does not touch the rest of the project config (agent versions, `ai.useMemory`, `ai.failureRecovery`) and does not upgrade your installed CLI version. If you want the overarching upgrade (file rewrite plus CLI version bump plus recommended config defaults), use [`momentic-mobile upgrade`](/docs/cli-reference/momentic-mobile/commands/upgrade) instead. ```bash theme={null} npx momentic-mobile migrate simplified-format ``` The command runs against the CLI version installed in your project. If that version is older than `momentic-mobile@latest`, the command warns you and points at `npx momentic-mobile@latest upgrade` so you can install the newest serializers before rewriting your files. The first file that fails to migrate aborts the run. Resolve the surfaced error and rerun the command; the migration is not designed to be resumable. ## Options Path to the Momentic configuration file. Defaults to `momentic.config.yaml` in the current directory. ## Examples Migrate every legacy mobile test and module in the project: ```bash theme={null} npx momentic-mobile migrate simplified-format ``` # momentic-mobile results Source: https://momentic.ai/docs/cli-reference/momentic-mobile/commands/results Upload, merge, and view local Momentic mobile test results. Manage the results directory produced by [`momentic-mobile run`](/docs/cli-reference/momentic-mobile/commands/run). Use `upload` after running with `--upload-results` disabled, `merge` to combine sharded runs, and `view` to inspect runs locally without uploading. ```bash theme={null} npx momentic-mobile results upload ``` ## `upload` Upload local test results to the Momentic dashboard. ```bash theme={null} npx momentic-mobile results upload [folder] ``` ### Arguments Folder containing results from `momentic-mobile run` or `momentic-mobile results merge`. Defaults to `test-results`, which matches the default `--output-dir`, so you can usually omit this argument. ## `merge` Merge results from multiple sharded mobile runs into a single folder before uploading. ```bash theme={null} npx momentic-mobile results merge ``` ### Arguments Parent folder of the results to merge. For example, if shards wrote into `test-results/shard-1` and `test-results/shard-2`, pass `test-results`. ### Options Directory to write the merged results to. The folder is overwritten if it exists. Required. ## `view` Launch the local run viewer to inspect results without uploading. ```bash theme={null} npx momentic-mobile results view [runId] ``` ### Arguments Path to a folder containing a `runs/` subfolder. Defaults to `test-results`. Run ID to open, matching a zip file in the `runs/` subfolder. For example, for `runs/eed92602-7355-43dc-8d79-1c43029bec26.zip`, pass `eed92602-7355-43dc-8d79-1c43029bec26`. When omitted, the viewer opens to the run group table. ### Options Port for the local run viewer server. Defaults to `58889`. ## Examples Upload the default results folder: ```bash theme={null} npx momentic-mobile results upload ``` Merge sharded results before uploading: ```bash theme={null} npx momentic-mobile results merge test-results --output-dir test-results/merged npx momentic-mobile results upload test-results/merged ``` View a specific run locally on a custom port: ```bash theme={null} npx momentic-mobile results view --port 59999 my-results eed92602-7355-43dc-8d79-1c43029bec26 ``` # momentic-mobile run Source: https://momentic.ai/docs/cli-reference/momentic-mobile/commands/run Run Momentic mobile tests locally and optionally upload results. Runs Momentic mobile tests in the current project. By default, results are written to a local directory; pass `--upload-results` to send them to the dashboard after the run completes. Requires tests to exist locally as YAML files. ```bash theme={null} npx momentic-mobile run --upload-results ``` ## Arguments Tests to run, given as test file paths, directories, or test-name substrings. Defaults to every test in the current project. ## Common flags Path to the Momentic configuration file. Defaults to `momentic.config.yaml` in the current directory. Name to associate with this run, used in the dashboard and as the base filename for generated reports. Number of tests to run in parallel. Defaults to `1`. Pass `AUTO` to saturate the current shard. Remote runs give each test an independent emulator session, so parallelism is safe and any org quota is enforced server-side. Local Android runs require a distinct AVD per parallel test; running multiple tests against the same `--local-avd-id` conflicts. Local iOS runs prefer `parallel=1` because concurrent Appium instances share a driver manifest. Skip all confirmation prompts. Enabled by default when `CI` is set. ## Environment Environment to run tests in. Must exist in the project configuration and takes precedence over the default environment configured on the test. Region used for remote emulator sessions. Overrides any region configured at the project or environment level. Pass `closest` to autoselect the nearest region. Override the default release channel for APK selection (e.g., `staging`, `dev`). When omitted, falls back to the test's default channel, otherwise no APK is installed on emulator initialization. Override the version tag within the selected channel. Accepts an exact tag, the reserved `latest`, or a floating alias (e.g. `nightly`). When omitted, uses the test's default tag, otherwise the latest uploaded APK in the channel. ## Filtering Only run tests with one of the specified labels. Only include tests whose file path matches any of the provided regex patterns. The pattern only needs to match part of the path. Exclude tests whose file path matches any of the provided regex patterns. ## Video Record videos of mobile test runs. Accepts `true`, `false`, or `on-fail`. Defaults to `on-fail` (videos are recorded but kept only for failing tests). ```bash theme={null} npx momentic-mobile run --video true # record every test npx momentic-mobile run --video on-fail # keep videos only for failures npx momentic-mobile run --video false # disable video ``` ## Quarantine Skip quarantined tests entirely. By default, quarantined tests still run but their statuses do not affect pipeline status or the process exit code. Run only quarantined tests, applying their statuses to pipeline status and the exit code. Run every test even if it is quarantined. Useful for validating that quarantined tests are fixed before moving them out of quarantine. ## Caching Disable step caches entirely. Steps run without cached data and no caches are saved. Always save updated step caches after successful runs, even on the main and other protected Git branches. See [cache saving eligibility](/docs/reliability/step-cache#cache-saving-eligibility). Run without using any existing caches. Step caches are still saved at the end of the run. Useful for refreshing caches after a config change. ## Visual diff Update locally stored golden files for [`visualDiff`](/docs/reference/mobile-commands/visual-diff) steps. Without this flag a `visualDiff` step fails when the screenshot differs from its golden; missing goldens are always created on first run regardless of this flag. ## Sharding 1-indexed shard to run. Defaults to `1`. Must be less than or equal to `--shard-count`. Total number of shards. Defaults to `1` (no sharding). ## Output Directory to store run artifacts (screenshots, logs, results). Defaults to the project's `outputDir` or `./test-results`. The directory is cleared at the start of a run. Upload test results to the Momentic dashboard after the run. Equivalent to running `momentic-mobile results upload ` once the run finishes. Output reporter. Pass multiple times to combine reporters (e.g. `--reporter=list --reporter=junit`). Live reporters render progress to the terminal as the run unfolds: * `list`: per-test rows. Default. On a TTY the running rows redraw in place with their current step; on non-TTY each test commits a single row when it finishes. * `steps`: append-only lines logging each step as it starts and finishes, with per-step durations, sections (setup/main/teardown), and nesting via indentation (modules, AI actions, loops). Suited to CI logs, which don't render the `list` reporter's in-place redraws. File reporters write post-run output to `--reporter-dir`. The following are supported for mobile runs: * `json` * `junit` * `allure` * `allure-json` * `buildkite-json` Directory where reporter output is saved. Defaults to `./reports`. Filenames derive from `--name` (or the project name). Logging verbosity. One of `error`, `warn`, `info`, or `debug`. ## Local devices Force tests to use a specific local Android Virtual Device (AVD). Overrides all configuration at the test and environment level. Override the APK installed on emulator initialization. Requires `--local-avd-id`. Force tests to use a specific local iOS simulator device type. Accepts any option Xcode supports when creating a new simulator (e.g., `"iPhone 17"`). Override the iOS app installed on simulator initialization. Requires `--local-ios-device-type`. ## CI Maximum total run time, in minutes. When reached, running tests stop and the current results are printed. ## Examples Run every test and upload to the dashboard: ```bash theme={null} npx momentic-mobile run --upload-results ``` Run a sharded Android pipeline against a staging APK: ```bash theme={null} npx momentic-mobile run --channel staging --shard-index 1 --shard-count 4 --reporter junit ``` Run against a local iOS simulator with a freshly built app: ```bash theme={null} npx momentic-mobile run --local-ios-device-type "iPhone 17" --local-app-path ./build/App.app ``` # momentic-mobile upgrade Source: https://momentic.ai/docs/cli-reference/momentic-mobile/commands/upgrade Bring an existing Momentic mobile project current with the latest recommended settings and file format. `momentic-mobile upgrade` is the overarching one-shot command for keeping a Momentic mobile project current. It installs the latest matching CLI release, flips the project to the simplified format, refreshes the recommended `ai` settings while preserving any pinned agent sub-versions, and rewrites every legacy `*.test.yaml` / `*.module.yaml` through the simplified format serializer. Files already using the simplified format are skipped. For just the YAML rewrite without any other config changes, use [`momentic-mobile migrate simplified-format`](/docs/cli-reference/momentic-mobile/commands/migrate) instead. ```bash theme={null} npx momentic-mobile@latest upgrade ``` Always invoke `momentic-mobile@latest` on first run; the CLI version bump writes your new version to `package.json`, but the rest of the upgrade still runs in the currently-installed process, so an old pinned CLI would migrate files with its old serializer until the next invocation. ## Options Path to the Momentic configuration file. Defaults to `momentic.config.yaml` in the current directory. Preview the upgrade without writing any files or pushing snapshots. Prints the same diff-style summary you would see during a real run so you can review changes before applying them. ## Examples Run the full upgrade in place: ```bash theme={null} npx momentic-mobile@latest upgrade ``` Preview what would change: ```bash theme={null} npx momentic-mobile@latest upgrade --dry-run ``` # momentic-mobile CLI Source: https://momentic.ai/docs/cli-reference/momentic-mobile/overview Drive Momentic iOS and Android tests locally and in CI. The `momentic-mobile` CLI is the entry point for mobile testing. Install it as a dev dependency, then invoke commands via `npx momentic-mobile `. ## Install ```bash theme={null} npm install --save-dev momentic-mobile ``` `momentic-mobile` supports Node.js 22.12.0+ in the 22.x line, Node.js 24.x, and Node.js 26.x. Node.js 23 and 25 are not supported. See the [Node.js release list](https://nodejs.org/en/about/previous-releases/) for active and end-of-life release lines. Every command assumes your project has a `momentic.config.yaml` at the root. Run [`init`](/docs/cli-reference/momentic-mobile/commands/init) to create one. ## Commands Scaffold a new mobile project. Open the local mobile editor. Run mobile tests on local or remote emulators. Upload, merge, and view local test results. List mobile tests matching a pattern. Validate simplified format mobile test and module YAML files. Check the installation and project for problems. Upload and manage APK and `.app` builds. Start the mobile MCP server for coding agents. Install Chromium-based browsers locally (deprecated). Install Momentic mobile skills for editors (deprecated). ## Global flags These flags are accepted by every command that talks to the Momentic API or loads a project. Per-command pages document any other flags they accept. Momentic API key. Defaults to the value in `~/.momentic/auth.json`. Env: `MOMENTIC_API_KEY`. Momentic server URL. Defaults to `https://api.momentic.ai`. Env: `MOMENTIC_SERVER`. Absolute or relative path to a Momentic configuration file. Defaults to `momentic.config.yaml` in the current directory. When using [workspaces](/docs/configuration/workspace), load the project whose name matches the filter. Substring matches are allowed. Skip all confirmation prompts. Enabled by default when `CI` is set. Set logging verbosity for Momentic and dependent services. One of `error`, `warn`, `info`, or `debug`. Enable verbose logging to stderr. ## Environment variables | Variable | Purpose | | ------------------ | ----------------------------------------------------------------- | | `MOMENTIC_API_KEY` | Auth token. Required for any command that talks to the dashboard. | | `MOMENTIC_SERVER` | Override the API host. | | `ANDROID_HOME` | Android SDK root. Required for all Android runs, remote included. | | `JAVA_HOME` | Java home directory used by local Android runs. | # momentic ai Source: https://momentic.ai/docs/cli-reference/momentic/commands/ai AI-assisted test selection, classification, and repair. AI-powered subcommands for test selection, classification, and repair. Use these to choose tests for a code change, triage failures, or attach AI-generated metadata to runs in CI. ```bash theme={null} npx momentic ai select --base origin/main ``` ## `select` Analyze the current git diff and return the tests most likely to catch a regression. This command prints the selection without executing tests. To select and run tests in one command, use [`momentic run --ai-select`](/docs/ai/select#run-selected-tests). ```bash theme={null} npx momentic ai select npx momentic ai select --base origin/main --json ``` Base branch, tag, or commit to diff against `HEAD`. Momentic detects the pull request base in supported CI providers and otherwise falls back to `origin/HEAD`. Soft cap on the number of tests selected. AI test selection can exceed it to cover distinct changed behavior. Additional selection guidance appended to the built-in AI test selection instructions. Repeatable; values are appended in command-line order. Omitting the flag leaves the standard selection prompt unchanged. Print the structured selection result to stdout without the streaming UI. Skip the local import index and select using the diff and app graph. Skip app graph search and select using local code evidence only. Maximum selection time in seconds. If the deadline expires, discard any partial selection and return a run-all fallback. See [AI test selection](/docs/ai/select) for GitHub Actions setup, code-index caching, fail-open behavior, and benchmark results. ## `classify` Classify the result of a test run. The agent inspects step results, screenshots, and error details and returns a category with reasoning. For CI, prefer enabling classification in `momentic.config.yaml` so `momentic run` classifies failures in-flow and saves the verdict automatically, with no separate `ai classify` step. See [Turn on in-flow classification](/docs/guides/auto-heal/in-flow-classification). Use this command to re-classify past runs, batch-classify a run group or commit, or ask follow-up questions with `--interactive`. Only failed runs are classified; passing runs are skipped. Provide exactly one selector: `--run-id` (one or more run IDs or URLs), `--run-group-id` (a run group ID or URL), or `--git-commit`. Multiple failed runs are classified in parallel with an aggregated summary. ```bash theme={null} npx momentic ai classify --run-id npx momentic ai classify --run-group-id npx momentic ai classify --git-commit ``` ### Options Classify one or more runs by ID or full run URL (e.g. `https://app.momentic.ai/runs/`). Pass multiple space-separated values to classify several runs in one invocation. Passing more than one run cannot be combined with `--interactive`. Classify every failed run in an uploaded run group, by run group ID or full run group URL (e.g. `https://app.momentic.ai/run-groups/`). Classify every failed run recorded at the given git commit SHA, across all run groups. When targeting a run group or commit, skip runs that already have a saved classification. Useful for resuming a partially-completed batch. Number of runs to classify in parallel when targeting a run group or commit. Defaults to `4`. The effective value is shown in the run banner. Output format for the classification. Defaults to `text`. Use `json` to print only the structured payload to stdout. Suppress the agent's streamed reasoning. Redundant when `--output-format json` is set. Persist the classification into the run's metadata. For local runs, this updates the local run zip; for uploaded runs, it updates the dashboard run. When targeting a run group or commit, each run is saved as it finishes. New result-classification cache entries are only written when `--save` is set. Ignore prior result-classification cache entries and do not write new cache entries. By default, classification can reuse prior classifications from the result-classification cache. If `--save` is also set, successful classifications can write new cache entries for future runs. After classifying, stay in an interactive terminal chat with the classification agent. Useful for asking follow-up questions about the run (why a step failed, what the screenshots show, related runs, etc.) without re-running classification. Single-run only and requires a TTY; cannot be combined with `--run-group-id`, `--git-commit`, or `--output-format json`. Type `exit` (or Ctrl-C) to leave; Ctrl-C during a response cancels just that turn. ### Output By default, the classification is printed as plain text: ``` Classification: BUG Reasoning: The checkout button was disabled due to a validation error that appeared after the address step... Confidence: high Recoverable: RECOVERABLE ``` Pass `--output-format json` to emit a machine-readable payload instead: ```json theme={null} { "category": "BUG", "reasoning": "The checkout button was disabled due to a validation error...", "recoverable": "RECOVERABLE", "confidence": "high" } ``` When targeting a run group or commit, the text output shows one row per run plus an aggregated summary of category counts and any failures. The `json` payload is an array, one entry per run; entries that failed to classify carry an `error` field instead of a `classification`: ```json theme={null} [ { "runId": "", "testName": "Checkout", "classification": { "category": "BUG", "recoverable": "RECOVERABLE", "confidence": "high" } }, { "runId": "", "testName": "Login", "error": "Run archive not found" } ] ``` Failures do not stop the batch; remaining runs are still classified and the errors are reported in the summary. Re-run with `--skip-classified` to retry only the runs that did not complete. ### Categories No failures, all attempts passed. The test is out of date because the application's flow or UI has changed. Updating the test to match the new behavior would permanently fix the failure. Something clearly went wrong in the application that shouldn't have, such as an unexpected error message appearing or expected content failing to render. The test can be permanently updated to prevent the failure while still validating its original intent, and a specific authorship change can be recommended. Timeouts, slow page loads, and any failure whose recommended fix is to wait longer or increase a timeout do not belong here. Those are `INFRA`, even when the test could technically be edited to wait longer. Missing test data or files necessary to run the test, where the fix requires user action outside of the test itself (e.g. a missing file for a file upload step, or missing/incorrect credentials). A failure unrelated to the application or application code that was caused by an infrastructure outage, long load times, or some other outside factor. An issue with Momentic's own execution (e.g. incorrect cache entries, unexpected locator redirects, obvious AI hallucinations). The failure doesn't fit any of the other categories. ## `triage` Runs the triage agent over a local results archive from [`momentic run`](/docs/cli-reference/momentic/commands/run) or an uploaded run group. The agent investigates failures, groups them by shared fixes when possible, attempts to update tests in place, and writes the outcome back to the run group. `momentic ai heal` is an alias with the same behavior and flags. When processing a local results archive, the command automatically uploads the updated archive after processing so the dashboard and connected reporting receive the final results and validation signal. Pass `--no-upload` to keep the archive local. This automatic upload also runs after `--dry-run` triage. For a copy-paste CI setup and the different integration paths, see [Auto-heal failing tests in CI](/docs/reliability/auto-maintenance#permanent-healing). Triage can take a while. When you only need to know which runs failed (not to repair them), use [`momentic results check`](/docs/cli-reference/momentic/commands/results#check) over the same results folder. It reports the failed, canceled, and quarantined runs so you can decide what to do. ```bash theme={null} npx momentic ai triage [results] npx momentic ai triage --run-group-id npx momentic ai triage --run-id npx momentic ai triage --git-commit npx momentic ai triage --from-quarantine --from-quarantine-budget 5 ``` Provide exactly one selector: a local `[results]` archive, `--run-group-id`, `--run-id`, `--git-commit`, or `--from-quarantine`. When multiple runs are passed via `--run-id`, they are triaged together in a single bucketing pass. ### Arguments Path to a local results archive directory written by `momentic run`. The directory must contain a run group metadata file. Omit when using `--run-group-id`, `--run-id`, or `--git-commit`. ### Target and output Triage an already uploaded run group by ID or full run group URL (e.g. `https://app.momentic.ai/run-groups/`) instead of a local results archive. Automatic upload does not apply because there is no local archive. Triage one or more uploaded runs by ID or full run URL. Pass multiple space-separated values to triage several runs together in one bucketing pass. The run-group risk-summary write-back is skipped for this scope. Triage every failed run recorded at the given git commit SHA, flat across all run groups. The run-group risk-summary write-back is skipped for this scope. Heal the active quarantine backlog instead of a specific results set. Walks quarantined tests earliest-quarantined first, replaying each one's most recent failed run. Tests whose stored heal status is **Unhealable** are skipped with their diagnostics printed; clear the heal status from the [Quarantine board](https://app.momentic.ai/quarantine) to retry one. Honors `--exclude`. Cannot be combined with `--only-quarantined` or `--skip-quarantined`. Maximum number of quarantined tests to attempt in one `--from-quarantine` invocation. Scanning stops as soon as the budget is filled and the summary reports how many tests were not attempted. Must be a positive integer. Group failed tests and generate a validation signal without attempting or applying repairs. A local results archive is still uploaded by default. Add `--no-upload` to skip the archive upload. How an accepted repair is delivered. Accepts `pull-request`, `draft-pull-request`, `direct-commit-except-main`, `patch` (print a git patch to stdout), or `nothing` (leave the changes on disk). Overrides the **On successful heal** [Triage setting](https://app.momentic.ai/settings/triage) for this run. What happens to tests the agent cannot fix. Accepts `warn`, `fail`, or `quarantine`. Overrides the **On failed heal** [Triage setting](https://app.momentic.ai/settings/triage) for this run. Suppress progress output and print the triage result as JSON. After triaging, stay in an interactive terminal chat with the triage agent so you can ask follow-up questions. This cannot be combined with `--json`. Do not automatically upload the local results archive after processing. The generated validation signal may still update connected pull request reporting. This flag has no effect when using `--run-group-id`. ### Common flags Path to the Momentic configuration file. Defaults to `momentic.config.yaml` in the current directory. When using [workspaces](/docs/configuration/workspace), load the project whose name matches the filter. Number of healing attempts to run in parallel. Each attempt opens its own browser session. Defaults to `1`. Abort when the number of healable failed runs exceeds this threshold. Must be a positive integer. Exclude tests whose name or project-relative file path matches any of the provided regex patterns from the triage queue. Provide multiple patterns separated by spaces. A pattern only needs to match part of the name or path for that test to be skipped. Emits high fidelity diagnostics for the triage agent to enable Momentic to help you debug your agent's failure. Do not default to turning this on. ### Environment Environment to run replays in. Overrides any environment configured on the test itself. Override the base URL of the test or environment during the replay. Custom headers to include in the replay. Specify multiple headers separated by spaces. CSV file containing input data for the replay. Each row is used as input for a separate run. ### Browser Override the browser used for replays. Accepts `chromium`, `chrome`, or `chrome-for-testing`. Launch healing browser sessions headfully by default. Useful for visually watching the agent work. Env: `MOMENTIC_HEADFUL_BROWSER`. Device pixel ratio for the healing browser. Set to `2` on macOS Retina or other HiDPI displays. ### Caching Always save updated step caches after a successful heal, even on the main and other protected Git branches. Disable step caches entirely. Steps run without cached data and no caches are saved. Ignore previously cached heal solutions during triage so failures are healed from scratch. Newly successful heals are still saved; step caches are unaffected. ### Quarantine Skip quarantined tests during triage. Disabled by default, so quarantined failures are included in healing. Only attempt to heal quarantined tests. Failed runs outside quarantine are ignored. ### Recovery Skip tests that passed through in-run failure recovery instead of assessing whether they need a permanent repair. Failed tests are still triaged. ### Setup Command to run before the replay begins. Useful for booting a local dev server. Resource to wait for before the replay begins. Accepts anything supported by [`wait-on`](https://www.npmjs.com/package/wait-on). HTTP proxy used when polling `--wait-on`. Provide the full URL including protocol, optional credentials, host, and port. Timeout (in seconds) for `--wait-on`. Defaults to `60`. Triage fails if the resource is not reachable in time. ### CI Maximum total triage time, in minutes. When reached, in-flight healing attempts stop and the current results are flushed. Suppress the agent's streamed reasoning. Skip all confirmation prompts. Enabled by default when `CI` is set. ### Exit codes `triage` is the final status for a run group: a non-zero exit code means something still needs your attention. * **`0`** - every failure was either successfully healed or, when **On failed heal** is `warn`, logged as a warning. A successful heal does not fail the run on its own; the delivered fix (e.g. a pull request) is yours to review and merge. * **`1`** - a test could not be healed and **On failed heal** is `fail` or `quarantine`, or delivering an accepted repair failed (e.g. opening the pull request errored), or the triage run itself errored out. Configure **On failed heal** in [Settings > Triage](https://app.momentic.ai/settings/triage). ## Examples Classify a local run by ID and print JSON for downstream tooling: ```bash theme={null} npx momentic ai classify eed92602-7355-43dc-8d79-1c43029bec26 --output-format json ``` Classify an uploaded run by URL and persist the result: ```bash theme={null} npx momentic ai classify https://app.momentic.ai/runs/eed92602 --save ``` Classify a run, then keep the chat open for follow-up questions: ```bash theme={null} npx momentic ai classify https://app.momentic.ai/runs/eed92602 -i ``` Triage failed runs from the latest local results directory: ```bash theme={null} npx momentic ai triage ./test-results ``` Triage only quarantined failures with two parallel sessions: ```bash theme={null} npx momentic ai triage ./test-results --only-quarantined --parallel 2 ``` Triage everything except a couple of known-flaky tests: ```bash theme={null} npx momentic ai triage ./test-results --exclude "checkout flow" "^Legacy " ``` Preview the triage plan without changing tests or uploading the local archive: ```bash theme={null} npx momentic ai triage ./test-results --dry-run --no-upload ``` # momentic app Source: https://momentic.ai/docs/cli-reference/momentic/commands/app Open the local Momentic web editor for authoring tests. Launches the local Momentic web editor against the project at `momentic.config.yaml`. Use it to author, edit, and debug tests locally. ```bash theme={null} npx momentic app ``` ## Common flags Path to the Momentic configuration file. Defaults to `momentic.config.yaml` in the current directory. Port for the local editor server. Defaults to `58888`. Env: `PORT`. Device pixel ratio for the editor's browser. Set to `2` on macOS Retina or other HiDPI displays. Defaults to the detected screen DPR. ## Caching Disable step caches entirely for the session. Steps run without cached data and no caches are saved after runs. Always save updated step caches after successful runs, even on the main and other protected Git branches. See [cache saving eligibility](/docs/reliability/step-cache#cache-saving-eligibility) for the default behavior. Start from an empty cache state for the session. Step caches are still saved at the end of each run. Useful for refreshing caches after a config change. ## Examples Open the editor for the current project: ```bash theme={null} npx momentic app ``` Open the editor using a config in a sibling directory: ```bash theme={null} npx momentic app -c ../other-project/momentic.config.yaml ``` # momentic apply Source: https://momentic.ai/docs/cli-reference/momentic/commands/apply Apply patch changes to local Momentic tests. Deprecated and retained only for legacy test fragment patches. It is hidden from `momentic --help` and may be removed in a future release. Applies a generated patch to the local copy of a test. Use it to roll changes suggested by the Momentic dashboard back into version control. ```bash theme={null} npx momentic apply patch --from --to ``` ## `patch` Apply a saved patch to a test. ### Common flags Path to the Momentic configuration file. Defaults to `momentic.config.yaml` in the current directory. When using [workspaces](/docs/configuration/workspace), load the project whose name matches the filter. ### Patch selection Patch identifier, formatted as three dash-separated words like `potato-apple-cherry`. Name of the test the patch should be applied to. ## Examples Apply a patch named `potato-apple-cherry` to `checkout-happy-path`: ```bash theme={null} npx momentic apply patch --from potato-apple-cherry --to checkout-happy-path ``` # momentic check Source: https://momentic.ai/docs/cli-reference/momentic/commands/check Validate Momentic tests, modules, and config files. Static checks over the local project. Use these in pre-commit hooks or CI to catch duplicate IDs and config drift before runs. For schema, file-reference, and entity ID validation of simplified format YAML, see [`momentic lint`](/docs/cli-reference/momentic/commands/lint). ## `duplicate-ids` Detect duplicate step and command IDs across tests and modules. For simplified format projects, this delegates to [`momentic lint`](/docs/cli-reference/momentic/commands/lint). ```bash theme={null} npx momentic check duplicate-ids ``` ### Options Rename duplicate IDs in place to make them unique. ## `duplicate-names` Detect duplicate test and module names so every entity is uniquely identifiable. ```bash theme={null} npx momentic check duplicate-names ``` ## `unused` Report modules that are not referenced by any test, directly or transitively through other modules. Useful for finding `.module.yaml` files left orphaned after tests are deleted or refactored. Exits non-zero when unused modules are found. ```bash theme={null} npx momentic check unused ``` ## `config` Validate `momentic.config.yaml` against the configuration schema. ```bash theme={null} npx momentic check config ``` ### Common flags Path to the Momentic configuration file. Defaults to `momentic.config.yaml` in the current directory. ## Examples Detect and auto-fix duplicate IDs: ```bash theme={null} npx momentic check duplicate-ids --fix ``` # momentic doctor Source: https://momentic.ai/docs/cli-reference/momentic/commands/doctor Check the Momentic CLI installation and project for problems. Runs a read-only health check of your Momentic setup and prints a section-by-section report: CLI version, authentication, connectivity to the Momentic API (including TLS interception, WebSocket support, clock skew, and proxy settings), environment, installed browsers (including missing OS libraries needed to launch them), and your project configuration (deprecated options, legacy file format, agent versions that have a newer release available, tests that have neither a base URL nor an environment, and browsers referenced by tests that are not installed). Problems are listed at the end with a suggested fix for each, and the command exits non-zero when any are found. Warnings do not affect the exit code. ```bash theme={null} npx momentic doctor ``` ## Options Momentic API key. Defaults to `MOMENTIC_API_KEY` or the key saved by [`momentic login`](/docs/cli-reference/momentic/overview). Path to the Momentic configuration file. Defaults to `momentic.config.yaml` in the current directory. Remove deprecated options from the project configuration file. Output the report as JSON. Useful for attaching to support tickets. ## Examples Check the installation and project: ```bash theme={null} npx momentic doctor ``` Remove deprecated options from the project configuration: ```bash theme={null} npx momentic doctor --fix ``` Generate a machine-readable report for a support ticket: ```bash theme={null} npx momentic doctor --json ``` # momentic import Source: https://momentic.ai/docs/cli-reference/momentic/commands/import Import tests, modules, and environments from the Momentic dashboard. Pulls dashboard-managed tests, modules, and environments down into the current project. You can import individual tests by their dashboard path, an entire cloud folder (which brings every test and module inside it plus any nested subfolders), or omit arguments to import the entire workspace. When the imported entities live inside dashboard folders, the folder hierarchy is recreated on disk so your local layout mirrors the dashboard. ```bash theme={null} npx momentic import ``` ## Arguments One or more dashboard paths to import. A path can be either a test path (e.g. `tests/checkout/happy-path`) or a folder path using the slash-separated cloud folder hierarchy (e.g. `auth/onboarding`). When omitted, every test, module, and environment in the project is imported. ## How folder import works * Folder paths are resolved against the dashboard's folder tree case-insensitively. `auth/onboarding` matches the cloud folder named `Onboarding` nested under `Auth`. * All tests and modules inside the folder are imported, including those in any nested subfolders. * The cloud folder hierarchy is recreated on disk. A test in cloud folder `Auth/Onboarding` lands at `auth/onboarding/.test.yaml` relative to the project root. Folder names are slugified the same way test names are. * If a test or module already exists locally with the same id, it keeps its current on-disk location; existing flat layouts are not reshuffled. ## Examples Import every dashboard-managed resource into the local project: ```bash theme={null} npx momentic import ``` Import a single test by its dashboard path: ```bash theme={null} npx momentic import tests/checkout/happy-path ``` Import every test and module inside a cloud folder, recreating the folder hierarchy on disk: ```bash theme={null} npx momentic import auth/onboarding ``` Import multiple folders and a specific test in one command: ```bash theme={null} npx momentic import auth/onboarding checkout tests/smoke/login ``` # momentic init Source: https://momentic.ai/docs/cli-reference/momentic/commands/init Scaffold a new Momentic project in the current directory. Creates a [`momentic.config.yaml`](/docs/configuration/momentic-config) and the project layout used by the rest of the CLI. The command prompts before overwriting any existing files. ```bash theme={null} npx momentic init ``` New projects are scaffolded with `fileFormat: v2`. Sample tests and modules emitted by the [onboarding wizard](https://www.npmjs.com/package/@momentic/wizard) are written in the simplified format directly, so no follow-up migration is needed. Existing v1 projects should run [`momentic migrate simplified-format`](/docs/get-started/migrate-to-simplified-format) instead of re-running `init`. ## Options Project name to write into the generated `momentic.config.yaml`. When omitted, the wizard prompts for one and defaults to `app`. Accepts the defaults for every prompt so the command runs in a non-TTY shell such as CI or a coding agent. The project name defaults to `app` unless `--name` is given. ## Examples Scaffold a project in the current directory: ```bash theme={null} npx momentic init ``` Scaffold a project without any prompts: ```bash theme={null} npx momentic init --yes ``` Scaffold a project non-interactively with a fixed name: ```bash theme={null} npx momentic init --name checkout-app ``` # momentic install-browsers Source: https://momentic.ai/docs/cli-reference/momentic/commands/install-browsers Install browser executables for Momentic web tests. Downloads and installs Momentic-managed browser binaries. See [supported browsers](/docs/platforms/web/browsers) for the differences between each variant. ```bash theme={null} npx momentic install-browsers chromium ``` The command also installs Playwright's managed `ffmpeg` binary for video recording. ## Arguments Browsers to install, separated by spaces. Available choices: `chromium`, `chrome`, and `chrome-for-testing`. See [supported browsers](/docs/platforms/web/browsers) for details. ## Options Reinstall the specified browsers even if they already exist on disk. Install every supported browser (`chromium`, `chrome`, and `chrome-for-testing`). ## Examples Install Chromium only: ```bash theme={null} npx momentic install-browsers chromium ``` Install every supported browser: ```bash theme={null} npx momentic install-browsers --all ``` Reinstall Chrome after a broken upgrade: ```bash theme={null} npx momentic install-browsers chrome --force ``` # momentic install-skills Source: https://momentic.ai/docs/cli-reference/momentic/commands/install-skills Install Momentic skill files for coding agents (deprecated). `momentic install-skills` is deprecated. Use the standalone `skills` CLI instead: ```bash theme={null} npx skills add momentic-ai/skills ``` Installs Momentic skill markdown so coding assistants get explicit instructions for the Momentic MCP. See the [MCP integration guide](/docs/coding-agents/mcp-server) for the full setup flow. ```bash theme={null} npx momentic install-skills --editor ``` ## Legacy command Only use this command if you are pinned to an older version of Momentic and need an older version of the skills. Skills give coding agents explicit instructions for using the Momentic MCP. Without them, agents are more likely to make malformed tool calls. Run this after configuring the MCP server. ### Options Editor whose skill directory to write into. One of `cursor`, `claude-code`, `codex`, `opencode`, or `copilot`. ### Install location Inside a git repository, the skill installs at `/`. Outside git, it installs at `/`. | Editor | Path | | ------------- | ----------------------------------- | | `cursor` | `.cursor/skills//SKILL.md` | | `claude-code` | `.claude/skills//SKILL.md` | | `codex` | `.agents/skills//SKILL.md` | | `opencode` | `.opencode/skills//SKILL.md` | | `copilot` | `.github/skills//SKILL.md` | ## Examples Install skills for Cursor: ```bash theme={null} npx momentic install-skills --editor cursor ``` Install skills for Claude Code: ```bash theme={null} npx momentic install-skills --editor claude-code ``` # momentic lint Source: https://momentic.ai/docs/cli-reference/momentic/commands/lint Validate Momentic simplified format test and module YAML files. Validate simplified format test and module YAML files: schema, local file references (modules, JS steps, JSON files), and entity ID conflicts. Applies only to files with `fileType: momentic/test/v2` or `fileType: momentic/module/v2`. Lint runs automatically before starting the local app and before executing tests, so normal app and test workflows already block invalid YAML. Use this command for fast standalone validation in pre-commit hooks, in CI, or after agent-authored edits. ```bash theme={null} npx momentic lint ``` ## Arguments Path to a single file to lint. Defaults to the entire project, which can take several seconds in large workspaces. ## Options Path to the Momentic configuration file. Defaults to `momentic.config.yaml` in the current directory. ## Examples Lint the entire project: ```bash theme={null} npx momentic lint ``` Lint a single test file: ```bash theme={null} npx momentic lint tests/checkout/happy-path.yaml ``` # momentic list Source: https://momentic.ai/docs/cli-reference/momentic/commands/list List local Momentic tests matching a pattern or label. Prints one test file path per line for every test in the current project that matches the provided filters. Intended to be piped into other commands. Requires tests to exist locally as YAML files. ```bash theme={null} npx momentic list ``` ## Arguments Tests to list, given as test file paths, directories, or test-name substrings. Defaults to every test in the current project. ## Common flags Path to the Momentic configuration file. Defaults to `momentic.config.yaml` in the current directory. When using [workspaces](/docs/configuration/workspace), load the project whose name matches the filter. ## Filtering Only list tests with one of the specified labels. Only include tests whose file path matches any of the provided regex patterns. The pattern only needs to match part of the path. Exclude tests whose file path matches any of the provided regex patterns. Only list tests changed against the base branch: changed test files plus tests that use a changed module (it lists those affected tests, not the module files). The base branch is auto-detected from the CI pull request, or `origin/HEAD`. Requires the checkout to have full git history. Pipe into `run` to re-run only what a [Momentic auto-heal](/docs/reliability/auto-maintenance#permanent-healing) PR touched. ## Examples List every test in the project: ```bash theme={null} npx momentic list ``` List tests under a specific folder: ```bash theme={null} npx momentic list tests/checkout ``` List tests with the `smoke` label, then pipe into `run`: ```bash theme={null} npx momentic list --labels smoke | xargs npx momentic run ``` Validate an auto-heal PR by running only the tests it changed: ```bash theme={null} npx momentic list --changed | xargs -r npx momentic run --upload-results ``` # momentic mcp Source: https://momentic.ai/docs/cli-reference/momentic/commands/mcp Run the Momentic MCP server for coding agents. Starts the Momentic MCP server over stdio so coding agents can author, run, and triage web tests. See the [MCP integration guide](/docs/coding-agents/mcp-server) for editor-specific setup. ```bash theme={null} npx momentic mcp ``` CLI flags override environment variables. ## Common flags Authenticates the MCP server with Momentic APIs. Env: `MOMENTIC_API_KEY`. Path to the `momentic.config.yaml` file used to load project tests, modules, and environments. ## Browser Whether browser sessions launch with a visible UI (`true`) or headless (`false`). Defaults to `true`. Env: `MOMENTIC_HEADFUL_BROWSER`. Override the viewport device pixel ratio used for browser rendering. Defaults to `2` on macOS Retina and `1` elsewhere. Record video of browser sessions by default. Defaults to `false`. The output directory path is returned when a session ends. Env: `MOMENTIC_VIDEO`. ## Caching Always save updated step caches after successful sessions, even on protected Git branches. Disable step caches entirely. Sessions run without cached data and no caches are saved. ## Session Idle timeout for MCP sessions in minutes. Defaults to `5`. Sessions inactive for this duration are terminated automatically. Env: `MOMENTIC_SESSION_IDLE_TIMEOUT_MINUTES`. Create a persistent local daemon so browser sessions can be shared across multiple MCP server invocations. The daemon's working directory is set to the parent of the config file, so MCP servers launched from different directories share the same project home. ## Examples Start the MCP server using the project's `momentic.config.yaml`: ```bash theme={null} npx momentic mcp ``` Run headless with a five-minute idle timeout: ```bash theme={null} npx momentic mcp --headful-browser false --session-idle-timeout-minutes 5 ``` # momentic migrate simplified-format Source: https://momentic.ai/docs/cli-reference/momentic/commands/migrate Rewrite local web tests and modules from legacy YAML to the simplified format. `momentic migrate simplified-format` is the narrow file-only migration. It rewrites every legacy `*.test.yaml` / `*.module.yaml` in the project through the simplified format serializer and flips `fileFormat: v2` on `momentic.config.yaml`. It does not touch the rest of the project config (agent versions, `ai.useMemory`, `ai.failureRecovery`) and does not upgrade your installed CLI version. If you want the overarching upgrade (file rewrite plus CLI version bump plus recommended config defaults), use [`momentic upgrade`](/docs/cli-reference/momentic/commands/upgrade) instead. ```bash theme={null} npx momentic migrate simplified-format ``` The command runs against the CLI version installed in your project. If that version is older than `momentic@latest`, the command warns you and points at `npx momentic@latest upgrade` so you can install the newest serializers before rewriting your files. The first file that fails to migrate aborts the run. Resolve the surfaced error and rerun the command; the migration is not designed to be resumable. ## Options Path to the Momentic configuration file. Defaults to `momentic.config.yaml` in the current directory. ## Examples Migrate every legacy web test and module in the project: ```bash theme={null} npx momentic migrate simplified-format ``` # momentic quarantine Source: https://momentic.ai/docs/cli-reference/momentic/commands/quarantine Quarantine or unquarantine tests from the CLI. Manage quarantined tests for the current project. Quarantined tests still run by default but their results do not affect pipeline success; see [`run --skip-quarantined`](/docs/cli-reference/momentic/commands/run) for opt-out behavior. ```bash theme={null} npx momentic quarantine add ``` ## `add` Quarantine a test so it stops impacting pipeline status. ```bash theme={null} npx momentic quarantine add ``` ### Arguments Name or path of the test to quarantine. Omit to pick interactively. ### Options Free-form reason shown alongside the test in the Momentic dashboard. ## `list` List every currently quarantined test in the project. ```bash theme={null} npx momentic quarantine list ``` ## `remove` Unquarantine a test so its result counts again. ```bash theme={null} npx momentic quarantine remove ``` ### Arguments Name or path of the test to unquarantine. Omit to pick interactively. ### Options Optional reason recorded alongside the change. ## Examples Quarantine a flaky test with a reason: ```bash theme={null} npx momentic quarantine add tests/checkout/flaky.yaml --reason "investigating CHK-123" ``` List quarantined tests: ```bash theme={null} npx momentic quarantine list ``` # momentic queue Source: https://momentic.ai/docs/cli-reference/momentic/commands/queue Queue dashboard-hosted tests and suites on Momentic infrastructure (deprecated). **Deprecated.** Cloud-hosted tests are being phased out as part of the broader [cloud deprecation](/docs/get-started/cloud-deprecation). Both `queue tests` and `queue suites` remain for backwards compatibility and will be removed in a future release. Run tests locally or in CI with [`momentic run`](/docs/cli-reference/momentic/commands/run) instead. Queues dashboard-hosted tests or suites for cloud execution. Requires the tests to exist on Momentic dashboard. ```bash theme={null} npx momentic queue tests ``` ## `tests` Queue one or more individual tests. ```bash theme={null} npx momentic queue tests ``` ### Arguments Names of the dashboard tests to queue. Pass multiple values separated by spaces. ### Common flags Queue every test in the project instead of the paths passed as arguments. Mutually exclusive with the `` argument. Environment to run the tests in. Overrides any environment configured on the test itself. The base URL set on the test still takes precedence; use `--url-override` to override it. Override the base URL of the test or environment. Useful for running against a preview deployment. ### Inputs Custom headers to include in the test run. Specify multiple headers separated by spaces. CSV file containing input data for the tests. Each row is used as input for a separate test run. ### Waiting Wait for the run to complete before exiting. Maximum time to wait for the run to complete, in seconds. Defaults to `1800`. Requires `--wait`. ## `suites` Queue one or more dashboard suites. ```bash theme={null} npx momentic queue suites ``` ### Arguments Names of the suites to queue. Pass multiple values separated by spaces. ### Options Custom headers to include in the run. Environment to run the suite in. The base URL on the suite still takes precedence; use `--url-override` to override. Override the base URL of the suite or environment. Wait for the run to complete before exiting. Maximum time to wait for the run to complete, in seconds. Defaults to `1800`. Requires `--wait`. ## Examples Queue a single dashboard test and wait for completion: ```bash theme={null} npx momentic queue tests checkout-happy-path --wait ``` Queue a suite against a preview deployment: ```bash theme={null} npx momentic queue suites smoke --url-override https://preview-123.example.com ``` # momentic results Source: https://momentic.ai/docs/cli-reference/momentic/commands/results Upload, merge, view, and check local Momentic test results. Manage the results directory produced by [`momentic run`](/docs/cli-reference/momentic/commands/run). Use `upload` after running with `--upload-results` disabled, `merge` to combine sharded runs, `view` to inspect runs locally without uploading, and `check` to gate CI on truly clean results. ```bash theme={null} npx momentic results upload ``` ## `upload` Upload local test results to the Momentic dashboard. ```bash theme={null} npx momentic results upload [folder] ``` ### Arguments Folder containing results from `momentic run` or `momentic results merge`. Defaults to `test-results`, which matches the default `--output-dir` of `momentic run`, so you can usually omit this argument. ## `merge` Merge results from multiple sharded runs into a single folder before uploading. ```bash theme={null} npx momentic results merge ``` ### Arguments Parent folder of the results to merge. For example, if shards wrote into `test-results/shard-1` and `test-results/shard-2`, pass `test-results`. ### Options Directory to write the merged results to. The folder is overwritten if it exists. Include run groups that produced no runs, such as shards where [AI test selection](/docs/ai/select) chose zero tests. Their metadata, including the selection plans, is merged instead of skipped, so the uploaded run group can explain why nothing ran. A results path that is missing or contains no run groups becomes a graceful no-op instead of an error. Recommended whenever AI selection is enabled; `upload` and `check` accept the same flag so the whole chain can run unconditionally in CI. ## `view` Launch the local run viewer to inspect results without uploading. ```bash theme={null} npx momentic results view [runId] ``` ### Arguments Path to a folder containing a `runs/` subfolder. Defaults to `test-results`. Run ID to open, matching a zip file in the `runs/` subfolder. For example, for `runs/eed92602-7355-43dc-8d79-1c43029bec26.zip`, pass `eed92602-7355-43dc-8d79-1c43029bec26`. When omitted, the viewer opens to the run group table. ### Options Port for the local run viewer server. Defaults to `58889`. ## `check` Exit non-zero if any non-quarantined run in a results archive did not pass cleanly. Use it as a CI gate after `merge` to require truly green results. ```bash theme={null} npx momentic results check ``` A run is considered **not clean** (and the command exits `1`) when it is not quarantined and any of the following is true: * its final status is `FAILED` or `CANCELLED`, * it only passed after an in-run [failure recovery](/docs/reliability/auto-maintenance#failure-recovery), or * it carries a failure [classification](/docs/reliability/auto-maintenance#permanent-healing) (any category, including ones routed to `heal`/`warn`). Quarantined runs are always ignored. The command exits `0` only when every non-quarantined run passed outright with no recovery and no classification. Pass `--allow-recovered` to treat runs that passed via in-run failure recovery as clean: they no longer fail the check, while `FAILED`/`CANCELLED` runs and failure classifications still exit `1`. ### Arguments Path to a folder containing a `runs/` subfolder, typically the `--output-dir` of a preceding `momentic results merge`. ### Options Treat runs that passed via in-run failure recovery as clean (exit `0`). Suppress progress output and print the check report as JSON. The report includes per-run detail for each not-clean run (`uncleanRuns`) and a `summary` with descriptive per-category counts: `total`, `clean`, `quarantined`, `failed`, `cancelled`, `recovered`, and `classified`. These counts overlap (a run can be both recovered and classified), so they do not sum to `total`. ## Examples Upload the default results folder: ```bash theme={null} npx momentic results upload ``` Merge sharded results before uploading: ```bash theme={null} npx momentic results merge test-results --output-dir test-results/merged npx momentic results upload test-results/merged ``` View a specific run locally on a custom port: ```bash theme={null} npx momentic results view --port 59999 my-results eed92602-7355-43dc-8d79-1c43029bec26 ``` Gate CI on clean results after merging shards: ```bash theme={null} npx momentic results merge test-results --output-dir test-results/merged npx momentic results check test-results/merged ``` # momentic run Source: https://momentic.ai/docs/cli-reference/momentic/commands/run Run Momentic web tests locally and optionally upload results. Runs Momentic tests in the current project. By default, results are written to a local directory; pass `--upload-results` to send them to the dashboard after the run completes. Requires tests to exist locally as YAML files. ```bash theme={null} npx momentic run --upload-results ``` ## Arguments Tests to run, given as test file paths, directories, or test-name substrings. Defaults to every test in the current project. ## Common flags Path to the Momentic configuration file. Defaults to `momentic.config.yaml` in the current directory. When using [workspaces](/docs/configuration/workspace), load the project whose name matches the filter. Name to associate with this run, used in the dashboard and as the base filename for generated reports. Number of tests to run in parallel. Each test starts its own browser instance. Defaults to `1`. Pass `auto` to size workers from the host's CPU count. Number of times to retry a test if it fails. Overrides each test's own retry configuration. Override the browser used for every test. Accepts `chromium`, `chrome`, or `chrome-for-testing`. Takes precedence over the per-test and config defaults. ## Environment Environment to run tests in. Overrides any environment configured on the test itself. The base URL set on the test still takes precedence; use `--url-override` to override it. Override the base URL of the test or environment. Useful for running against a preview deployment. Custom headers to include in the run. Specify multiple headers separated by spaces. CSV file containing input data for the tests. Each row is used as input for a separate test run. See [Data-driven tests](/docs/guides/data-driven-tests/parametrized-runs). ## Filtering Only run tests with one of the specified labels. Only include tests whose file path matches any of the provided regex patterns. The pattern only needs to match part of the path. Exclude tests whose file path matches any of the provided regex patterns. ## AI test selection Use [AI test selection](/docs/ai/select) to choose which in-scope tests to run from the current git diff. If selection is unavailable, Momentic runs every in-scope test. Base branch, tag, or commit to diff against `HEAD`. Momentic detects the pull request base in supported CI providers. Soft cap on the number of tests selected. AI test selection can exceed it when needed to cover distinct changed behavior. Additional selection guidance appended to the built-in AI test selection instructions when `--ai-select` or `--ai-select-dry-run` is enabled. Repeatable; values are appended in command-line order. Omitting the flag leaves the standard selection prompt unchanged. Run every in-scope test, while recording which tests AI test selection would have selected. Use this to evaluate selection on your own CI history. ## Quarantine Skip quarantined tests entirely. By default, quarantined tests still run but their statuses do not affect pipeline status or the process exit code. Run only quarantined tests, applying their statuses to pipeline status and the exit code. Run every test and apply all statuses to pipeline status and exit code. ## Classification Opt in to letting the classification verdict override this run's exit code, overriding `ai.classification.overrideExitCode` in `momentic.config.yaml`. When present, failures that classification routes to **heal** or **warn** exit `0`. Takes precedence over both the config file and the cloud setting. Has no effect unless [classification](/docs/reliability/auto-maintenance#permanent-healing) is enabled. Skip AI classification for this run, even if classification is enabled in `momentic.config.yaml` or workspace settings. Use this for one-off local runs where you only need the raw failure and want the CLI to exit as soon as test execution finishes. ## Caching Disable step caches entirely. Steps run without cached data and no caches are saved. Always save updated step caches after successful runs, even on the main and other protected Git branches. See [cache saving eligibility](/docs/reliability/step-cache#cache-saving-eligibility). Run without using any existing caches. Step caches are still saved at the end of the run. Useful for refreshing caches after a config change. Steps run without cached data, which significantly increases run time. Not recommended for ongoing use. Bust the oldest `n%` of step caches before the run. Useful for incrementally regenerating caches after a config change. At least one cache is always busted, even if `n%` rounds to zero. Only applies on non-protected branches. Replay one or more `.snapshot.zip` files created with [`momentic snapshot`](/docs/cli-reference/momentic/commands/snapshot). Each snapshot replays in complete isolation: modules, environment, and step caches are read straight from the zip, and the cache backend is never read from or written to. Because the run is fully self-contained, this option cannot be combined with test paths or any test-selection option (`--include`, `--exclude`, `--labels`, `--ai-select`). ## Video Record videos of test runs. Accepts `true`, `false`, or `on-fail`. Defaults to `on-fail` (videos are recorded but kept only for failing tests). The required `ffmpeg` binary is installed by `momentic install-browsers`. ```bash theme={null} npx momentic run --video true # record every test npx momentic run --video on-fail # keep videos only for failures npx momentic run --video false # disable video ``` ## Sharding 1-indexed shard to run. Combine with `--shard-count` to split tests across machines. Total number of shards. ## Output Directory to store run artifacts (screenshots, logs, results). The directory is cleared at the start of a run. Defaults to `./test-results`. A live `progress.json` is written to the top of this directory and updated as steps complete, so you can poll step progress while a run is still going. See [Live run progress](/docs/running-tests/results#live-run-progress). Upload test results to the Momentic dashboard after the run. Equivalent to running `momentic results upload ` once the run finishes. Attach this invocation's results to a caller-chosen run group. The value must be a UUID. When omitted, Momentic creates a new run group for the invocation. Output reporter. Pass multiple times to combine reporters (e.g. `--reporter=list --reporter=junit`). Live reporters render progress to the terminal as the run unfolds: * `list`: per-test rows. Default. On a TTY the running rows redraw in place with their current step; on non-TTY each test commits a single row when it finishes. * `steps`: append-only lines logging each step as it starts and finishes, with per-step durations, sections (setup/main/teardown), and nesting via indentation (modules, AI actions, loops). Suited to CI logs, which don't render the `list` reporter's in-place redraws. File reporters write post-run output to `--reporter-dir`: * `json` * `junit` * `allure` * `allure-json` * `playwright-json` * `buildkite-json` Network reporters push results to an external service configured under [`reporting`](/docs/configuration/momentic-config#reporting) in `momentic.config.yaml`: * `newrelic`: see [Push run results to New Relic](/docs/guides/reporting/new-relic) Directory where reporter output is saved. Defaults to `./reports`. Filenames derive from `--name` (or the project name). Update locally stored golden files for **Visual diff** steps. See [Visual testing](/docs/guides/visual-testing/golden-files). ## Setup Device pixel ratio of the local screen. Set to `2` on macOS Retina or other HiDPI displays. Defaults to the detected screen DPR. Command to run before tests begin. Useful for booting a local dev server. ```bash theme={null} npx momentic run --start "pnpm dev" ``` Resource to wait for before tests begin. Accepts anything supported by [`wait-on`](https://www.npmjs.com/package/wait-on). HTTP proxy used when polling `--wait-on`. Provide the full URL including protocol, optional credentials, host, and port. Timeout (in seconds) for `--wait-on`. Defaults to `60`. The run fails if the resource is not reachable in time. ## CI Maximum total run time, in minutes. When reached, running tests stop, results are flushed to disk, and the process exits with code `1`. Emit run diagnostics using standard OpenTelemetry exporter environment variables. Configure exporter endpoints via the usual `OTEL_*` env vars. Env: `MOMENTIC_SHARE_DIAGNOSTICS`. Skip all confirmation prompts. Enabled by default when `CI` is set. ## Examples Run every test and upload to the dashboard: ```bash theme={null} npx momentic run --upload-results ``` Run a single test suite across four shards in CI: ```bash theme={null} npx momentic run tests/checkout --shard-index 1 --shard-count 4 --reporter junit ``` Run against a preview deployment with a startup hook: ```bash theme={null} npx momentic run --url-override https://preview-123.example.com --start "pnpm dev" --wait-on http-get://localhost:3000 ``` Replay snapshots created with [`momentic snapshot`](/docs/cli-reference/momentic/commands/snapshot) in full isolation: ```bash theme={null} npx momentic run --from-snapshot checkout.snapshot.zip login.snapshot.zip ``` Validate an [auto-heal PR](/docs/reliability/auto-maintenance#permanent-healing) by re-running only the tests it changed: ```bash theme={null} npx momentic list --changed | xargs -r npx momentic run --upload-results ``` # momentic snapshot Source: https://momentic.ai/docs/cli-reference/momentic/commands/snapshot Freeze tests into self-contained zips for fully isolated replay. Creates a **test snapshot**: a self-contained `.snapshot.zip` that captures a test exactly as it would run right now, with modules expanded, step caches included, environment variables baked in, and the relevant project config frozen. A snapshot can later be replayed in complete isolation with [`momentic run --from-snapshot`](/docs/cli-reference/momentic/commands/run#snapshots) (no local test files, modules, environment, or cache backend required). ```bash theme={null} npx momentic snapshot checkout.test.yaml login.test.yaml ``` One zip is written per resolved test, named `.snapshot.zip`. Folders are expanded into the tests they contain, exactly like [`momentic run`](/docs/cli-reference/momentic/commands/run). ## What a snapshot contains Each zip holds two entries: * `test.yaml`: the resolved test, metadata plus the fully expanded before, main, and after steps with every step cache inlined. * `metadata.json`: readable fields (`momenticVersion`, `schemaVersion`, `createdAt`, `relativeFilePath`, environment name, base URL, and the frozen project config: `browser`, `ai`, `advanced`, `retries`). Snapshots can only be replayed by the organization that created them, to prevent accidental leakage of environment secrets. ## Arguments One or more test file paths or folders on the local machine to snapshot. Pass multiple values separated by spaces. Folders are expanded into every test they contain. ## Common flags Path to the Momentic configuration file. Defaults to `momentic.config.yaml` in the current directory. When using [workspaces](/docs/configuration/workspace), load the project whose name matches the filter. Directory to write the `.snapshot.zip` files to. Defaults to the current directory. Skip all confirmation prompts. Enabled by default when `CI` is set. ## Environment Environment to resolve when capturing the snapshot. Overrides any environment configured on the test itself. The resolved variables are frozen into the snapshot. Override the base URL resolved into the snapshot. Useful for capturing a snapshot pointed at a specific deployment. ## Examples Snapshot a single test into the current directory: ```bash theme={null} npx momentic snapshot checkout.test.yaml ``` Snapshot every test in a folder, writing the zips elsewhere: ```bash theme={null} npx momentic snapshot tests/smoke --output-dir ./snapshots ``` Snapshot a test resolved against a specific environment and deployment: ```bash theme={null} npx momentic snapshot checkout.test.yaml --env staging --url-override https://preview-123.example.com ``` Then replay one or more of the produced zips in isolation: ```bash theme={null} npx momentic run --from-snapshot ./snapshots/checkout.snapshot.zip ./snapshots/login.snapshot.zip ``` # momentic upgrade Source: https://momentic.ai/docs/cli-reference/momentic/commands/upgrade Bring an existing Momentic project current with the latest recommended settings and file format. `momentic upgrade` is the overarching one-shot command for keeping a Momentic project current. It installs the latest matching CLI release, flips the project to the simplified format, refreshes the recommended `ai` settings while preserving any pinned agent sub-versions, and rewrites every legacy `*.test.yaml` / `*.module.yaml` through the simplified format serializer. Files already using the simplified format are skipped. For just the YAML rewrite without any other config changes, use [`momentic migrate simplified-format`](/docs/cli-reference/momentic/commands/migrate) instead. ```bash theme={null} npx momentic@latest upgrade ``` Always invoke `momentic@latest` on first run; the CLI version bump writes your new version to `package.json`, but the rest of the upgrade still runs in the currently-installed process, so an old pinned CLI would migrate files with its old serializer until the next invocation. ## Options Path to the Momentic configuration file. Defaults to `momentic.config.yaml` in the current directory. Preview the upgrade without writing any files or pushing snapshots. Prints the same diff-style summary you would see during a real run so you can review changes before applying them. ## Examples Run the full upgrade in place: ```bash theme={null} npx momentic@latest upgrade ``` Preview what would change: ```bash theme={null} npx momentic@latest upgrade --dry-run ``` # momentic CLI Source: https://momentic.ai/docs/cli-reference/momentic/overview Drive Momentic web tests locally and in CI. The `momentic` CLI is the entry point for web testing. Install it as a dev dependency, then invoke commands via `npx momentic `. ## Install ```bash theme={null} npm install --save-dev momentic ``` Every command assumes your project has a `momentic.config.yaml` at the root. Run [`init`](/docs/cli-reference/momentic/commands/init) to create one. ## Commands Scaffold a new Momentic project. Open the local editor. Run tests locally and optionally upload results. Freeze tests into self-contained zips for isolated replay. Upload, merge, and view local test results. List tests matching a pattern. Queue a run on Momentic infrastructure (deprecated). Validate simplified format test and module YAML files. Detect duplicate IDs and validate `momentic.config.yaml`. Check the installation and project for problems. Import tests from the Momentic dashboard. Apply patch changes to local tests (deprecated). Quarantine or unquarantine tests. AI-assisted classification and authoring. Start the MCP server for coding agents. Install or update headless browsers. Install Momentic skills for editors (deprecated). ## Global flags These flags are accepted by every command that talks to the Momentic API or loads a project. Per-command pages document any other flags they accept. Momentic API key. Defaults to the value in `~/.momentic/auth.json`. Env: `MOMENTIC_API_KEY`. Momentic server URL. Defaults to `https://api.momentic.ai`. Env: `MOMENTIC_SERVER`. Absolute or relative path to a Momentic configuration file. Defaults to `momentic.config.yaml` in the current directory. When using [workspaces](/docs/configuration/workspace), load the project whose name matches the filter. Substring matches are allowed. Skip all confirmation prompts. Enabled by default when `CI` is set. Enable verbose logging to stderr. ## Environment variables | Variable | Purpose | | ------------------ | ----------------------------------------------------------------- | | `MOMENTIC_API_KEY` | Auth token. Required for any command that talks to the dashboard. | | `MOMENTIC_SERVER` | Override the API host. | See [Environment variables](/docs/configuration/environment-variables) for the full list. # MCP Source: https://momentic.ai/docs/coding-agents/mcp-server Run Momentic's MCP server so coding agents can author, run, and triage tests directly from your editor. The explore agent (`momentic ai explore`) is deprecated. [Mo](/docs/mo) now does the autonomous bug finding. Mo is in private beta, so [sign up](https://momentic.ai/mo) to get onboarded. To write tests from a code diff, use the MCP server with the `momentic-spec` skill on this page. Momentic's MCP server exposes tools that let agents browse, edit, create, and run tests with a live browser directly from your editor. Requires Momentic CLI 2.54.0 or later. ## Common workflows * **Implement from executable specs.** Use `momentic-spec` before changing user-visible behavior so the affected Momentic tests capture the intended product behavior and validate the finished implementation. * **Author and extend coverage.** Use `momentic-test` to create tests, steps, and modules against a live browser. Use `momentic-mobile-test` for Android and iOS. * **Understand a branch failure.** Use `momentic-maintain` to find runs for the branch, inspect the saved classifications and run evidence, and identify the earliest point where behavior diverged. * **Investigate failures on main.** DevX and on-call engineers can group recent failures by status or classification, inspect representative runs, and distinguish application regressions from test, environment, and Momentic issues. * **Deflake tests and reduce latency.** Find quarantined, recovered, and retry-heavy runs, then repair unstable tests and reduce time spent in failure recovery. Branch, classification, and minimum-attempt filters help prioritize repeated failure patterns. ## Prerequisites * [Momentic CLI](/docs/quickstart/web) installed locally (MCP runs on your machine) * A project with a valid `momentic.config.yaml` * A `MOMENTIC_API_KEY` available to the MCP process (most editors do **not** inherit your shell environment) ## Setup instructions ### General Momentic's MCP is a **local stdio server**. Every editor ultimately runs: ``` npx momentic mcp --config /absolute/path/to/momentic.config.yaml ``` For mobile testing, substitute `momentic-mobile mcp`. See [`momentic mcp`](/docs/cli-reference/momentic/commands/mcp) and [`momentic-mobile mcp`](/docs/cli-reference/momentic-mobile/commands/mcp) for every supported flag (headful browser, pixel ratio, daemon mode, etc.). Along with the server, install the **Momentic skills** for your editor. Skills give agents explicit operating guidance so they don't make malformed tool calls: * **`momentic-test`**: how to build reliable tests, steps, and modules * **`momentic-spec`**: how to write affected tests before product changes * **`momentic-maintain`**: how to investigate branch and main failures, audit classifications, deflake quarantined or recovered tests, reduce retries, and repair durable test issues
After registering the server with one of the clients below, restart the client and start a new chat. Ask the agent which MCP tools are available. You should see `momentic_*` tools such as `momentic_get_artifacts`. If they do not appear, fully restart the client. ### Claude Code Register the server: ```bash theme={null} claude mcp add --transport stdio momentic -- npx momentic mcp --config /absolute/path/to/momentic.config.yaml ``` Verify with `claude mcp list`. On native Windows, wrap with `cmd /c`: ```bash theme={null} claude mcp add --transport stdio momentic -- cmd /c npx momentic mcp --config C:\path\to\momentic.config.yaml ``` Pass `MOMENTIC_API_KEY` via the CLI's `--env` flag or by running the command from a shell that already has it exported. See [Claude Code MCP docs](https://code.claude.com/docs/en/mcp#option-3-add-a-local-stdio-server) for scoping and auth options. Restart Claude Code and run `/mcp` to confirm the server is active. ### Codex Register the server: ```bash theme={null} codex mcp add momentic -- npx momentic mcp --config /absolute/path/to/momentic.config.yaml ``` The command saves the entry to `~/.codex/config.toml`. For project-scoped configs, edit `.codex/config.toml` in a trusted project. See [Codex MCP docs](https://developers.openai.com/codex/mcp/) for env vars and timeouts. Restart Codex, then run `/mcp` in the TUI to verify. ### Cursor Open the command palette, select **View: Open MCP Settings**, click **Add a new Custom MCP server**, then paste and restart Cursor: ```json theme={null} { "mcpServers": { "momentic": { "type": "stdio", "command": "npx", "args": [ "momentic", "mcp", "--config", "/absolute/path/to/momentic.config.yaml" ], "env": { "MOMENTIC_API_KEY": "your-api-key" } } } } ``` ### Devin Follow the dedicated [Devin integration page](/docs/integrations/devin). Devin requires additional machine-configuration steps so it can install browsers, set `ANDROID_HOME` / `JAVA_HOME`, and pre-install skills before MCP starts. ### OpenCode Edit `opencode.json` in your project root or `~/.config/opencode/`: ```json theme={null} { "mcp": { "momentic": { "type": "local", "command": [ "npx", "momentic", "mcp", "--config", "/absolute/path/to/momentic.config.yaml" ], "environment": { "MOMENTIC_API_KEY": "your-api-key" }, "enabled": true } } } ``` ### VS Code (Copilot) Open the command palette, select **MCP: Add Server**, pick **Command (stdio)**, then paste: ``` npx momentic mcp --config /absolute/path/to/momentic.config.yaml ``` Name the server `momentic` when prompted. Then add `MOMENTIC_API_KEY` to the generated entry in `mcp.json`: ```json theme={null} "momentic": { "env": { "MOMENTIC_API_KEY": "your-api-key" } } ``` Your org may need to allow MCP. Copilot only exposes MCP in agent mode. ### Other clients Any MCP-compatible client can launch the server with: * Command: `npx` * Arguments: `momentic mcp --config /absolute/path/to/momentic.config.yaml` * Env: `MOMENTIC_API_KEY=your-api-key` ## Install skills After registering the MCP server with your editor, install the Momentic skill files from your project root: ```bash theme={null} npx skills add momentic-ai/skills ``` ## Invoke the skill Some agents load installed skills on their own, but many skip them unless you name the skill in the prompt. Invoke skills with a slash prefix, as the examples below show. For agents without slash commands, ask for the skill by name. ### Authorship Use `momentic-test` to create or extend Momentic tests: ```text theme={null} /momentic-test write a test for the checkout flow ``` Use `momentic-mobile-test` for Android and iOS. Naming the skill keeps the agent on Momentic's test format and MCP workflow instead of hand-rolling browser automation. ### Maintenance Use `momentic-maintain` to understand failures on a branch or main, review and challenge saved classifications, deflake quarantined or recovered tests, reduce retries, and repair stale test steps while preserving the intended behavior: ```text theme={null} /momentic-maintain investigate and repair run ``` ### Request visual evidence Web and mobile MCP tools return screenshots from live sessions and saved step results. Ask the agent to display them in the conversation when you want to see the evidence it used: ```text theme={null} /momentic-maintain show the before and after screenshots for the first failing step in run , then explain where behavior diverged ``` The web MCP can also record a live browser session. Ask the agent to enable video when it starts the reproduction and return the video output path after it terminates the session: ```text theme={null} /momentic-maintain reproduce run in a web session with video enabled, then return the screenshots and video output path ``` Mobile MCP sessions return screenshots but do not currently expose a live session video option. The agent can still inspect video attached to a completed mobile run when that artifact is available. ### Spec-driven development Once your repo is on the simplified format, Momentic tests are readable enough to double as product specs. Invoke `momentic-spec` when implementing a feature so the agent creates or updates the smallest set of affected Momentic tests before changing product code: ```text theme={null} /momentic-spec add a confirmation message after a file is attached ``` To make this the default behavior for your repository, also add a spec-driven section to your `AGENTS.md` (or `.cursor/rules`, etc.): ```md theme={null} ## Momentic spec-driven development Use the `momentic-spec` skill before implementing user-visible product changes. It captures the intended behavior in the smallest affected set of Momentic tests, then validates the implementation at durable UI checkpoints. Follow the skill's workflow for test data, disabled specifications, and verification. ``` See [Agentic testing](/docs/core-concepts/agentic-testing) for more on `act` and AI action V3. ## Usage tips * **Model**: use the newest model your editor offers. `High` reasoning gives the best results; `Medium` is about 20% faster with some quality loss. * **Invoke the relevant skill** explicitly when authoring, maintaining, or changing product behavior. * **Be specific** in prompts. For exploratory runs, include a step limit. * **Let sessions terminate**: the agent calls `momentic_session_terminate` to close the browser. Hard-stopping your editor leaks browser processes. * **Gitignore** `.momentic-mcp/`. MCP stores screenshots, videos, and traces there. * **Long-running steps**: `momentic_preview_step`, `momentic_preview_steps`, and `momentic_run_step` wait 30 seconds by default, which you can change with `timeoutSeconds`. Work that takes longer continues in the background and the tool returns a `stepRunnerId`. Collect the result with `momentic_poll_runner`, and pass its own `timeoutSeconds` (0-30, default 0) to hold the poll open instead of busy-polling. Only one preview or run executes per session at a time. ## Related * [What is AI-native testing?](/docs/get-started/ai-native-testing#author-with-product-context) # Momentic vs Appium Source: https://momentic.ai/docs/comparisons/appium Compare Momentic vs Appium for mobile testing: managed step cache, AI primitives, and YAML authoring for faster, stable runs. Momentic is a managed testing platform for iOS and Android. Tests are YAML, executed on managed remote emulators and simulators. A multi-modal step cache stores locator metadata per step and auto-heals in place when the UI changes. AI primitives cover action, assertion, visual diff, and typed extraction. AI providers route with cross-provider failover. A dashboard captures run videos, view hierarchies, heal events, and AI reasoning. [Appium](https://appium.io) is an open-source mobile automation framework that exposes the WebDriver / W3C protocol across iOS, Android, and other platforms via swappable drivers (UiAutomator2, XCUITest, Espresso, Flutter, Mac, Windows). Tests are written in TypeScript / Python / Java / Ruby / .NET against the Appium client of choice. It's a fit for teams that want OSS, multi-language flexibility, physical-hardware support, and deep customization at the driver level, plus the bandwidth to maintain a verbose, locator-heavy codebase. ## Speed and caching | | Momentic | Appium | | ------------------- | -------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- | | What's cached | Multi-modal locator data per step ([docs](/docs/reliability/step-cache)). | Nothing. Every locator strategy re-queries the device. | | Heal on miss | Re-resolves and **updates the entry in place**. Heal event on the run. | Not supported. A miss is a test failure after the WebDriverWait timeout. | | Waiting | Built-in: navigation, `load`, screenshots, DOM / view-hierarchy mutations, same-origin requests. 3s default, configurable. | `implicitlyWait` (per-driver) or explicit `WebDriverWait` + `ExpectedConditions` per query. Boilerplate per step. | | Storage | Managed, git-aware. | N/A. | | Cost of a UI change | Auto-heal absorbs renamed IDs, localized strings, reordered hierarchies. | One client-code edit per broken selector. XPath edits often require full re-derivation. | ## How the multi-modal cache works A cached step stores more than one way to find the target: where it sits on screen, what it looks like, what text it contains, and the accessibility and structural attributes around it. Which of those signals matters for a given step is inferred from the natural-language description. "The red Cancel button below the Order Summary header" leans on visual and positional signals; "the Sign in button" leans on accessibility and text. When a step replays, the runner checks the stored signals against the live UI and runs the action without invoking the LLM when there's a match. ## What happens on a UI change A practical sequence that shows the difference. Take a sign-in screen whose Email field has `accessibilityIdentifier = "email_input"`, after a passing baseline run where the cache is warm. **Refactor:** the app team renames `email_input` to `email_field`. The XPath position of the field shifts because a container was added above it. **Appium replay:** 1. `driver.$("~email_input")` issues a `findElement` request against the device. The WebDriver waits up to `implicitlyWait` (or the configured `WebDriverWait` timeout) for the element to appear. 2. The timeout elapses with no match. The client throws `NoSuchElementError`. 3. The test stops; the CI job fails. Someone edits the client code to use the new accessibility ID (or rewrites the XPath against the new hierarchy), opens a PR, gets it merged, and re-runs CI. If the XPath path was deep, the edit can cascade across multiple steps. **Momentic replay:** 1. The cached locator for the `Email` step misses on the live device. 2. The locator agent re-resolves the original natural-language description `Email`. 3. The new locator binds, the step runs, the test passes. 4. The cache entry is updated in place. A heal event is attached to the run for review. Subsequent runs hit the cache normally. Across a test suite, a renamed ID requires a code edit and another CI run. Momentic can update the cache entry and continue running the test. **Smart waiting** Momentic's default smart wait is 3000ms and configurable per test. The runner waits on a combination of navigation, `load`, screenshots, DOM / view-hierarchy mutations, and same-origin requests until the UI is quiet or the timeout elapses. **Appium waiting** * `implicitlyWait` is per-driver. Too low -> flakes; too high -> padded runs. * Explicit waits (`WebDriverWait` + `ExpectedConditions.visibilityOfElementLocated`, `presenceOf`, `elementToBeClickable`) are per query. Common to layer 3-5 explicit waits per logical step. * No notion of network quiescence; teams instrument their own request interceptors or poll the UI. ## Locators and AI primitives | | Momentic | Appium | | ------------- | --------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Locator model | Natural-language descriptions resolved by an AI agent against a11y tree + view hierarchy + screenshot. Cached, auto-healed. | `accessibility id`, `id`, `xpath`, `class name`, `-android uiautomator` (UiSelector), `-ios predicate string`, `-ios class chain`, `-image` (template match). | | Visual cues | Color, icon, relative size, position part of the locator. | `-image` strategy is template matching only (no semantic context). | | Agentic step | `act` accepts a multi-step goal; the agent plans and executes. | Not supported. | | AI assert | `assert` is a first-class step type, fails by default. | Not built-in. Teams build with `getText` + manual checks. | | Visual diff | `assertVisually`, agent-scored against a golden. | Not built-in. Third-party plugins (e.g. Applitools) bolt on. | | AI provider | Managed; cross-provider failover handled by the platform. | None. Teams integrate LLMs themselves. | **Momentic mobile step types** * Action: `act`, `tap`, `doubleTap`, `longPress`, `type`, `swipe`, `scroll`, `back`, `dismissKeyboard`, `launchApp`, `terminateApp` * Assert: `assert`, `assertVisually`, `checkElement<...>` * Extract: `extract` (typed via JSON schema) * Control flow: `if/then`, modules, parameter inputs **Appium locator trade-offs** * `accessibility id` is the most stable strategy but only exists when developers explicitly set `contentDescription` (Android) / `accessibilityIdentifier` (iOS). Production apps frequently miss them on dynamic content. * `id` (resource-id on Android) breaks under refactors and A/B testing. * `xpath` is the catch-all but is slow on large hierarchies and breaks on any structural change. * `-image` does template matching; works for static images, fails on themed UIs. * No locator strategy carries semantic intent. A failing step has no description to recover from. ## Recovery, quarantine, and CI | | Momentic | Appium | | ---------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- | | Failure recovery | Post-run triage agent (`momentic ai triage`) rewrites failing tests and opens a PR or patch in CI; `momentic ai classify` triages the failure. | Not supported. | | Quarantine | First-class: tests run, results report, exit code unaffected unless `--only-quarantined`. | Not supported. | | Sharding | `--shard-index ` / `--shard-count `, 1-indexed. Deterministic alphabetical partition. | Owned by the host runner (pytest, Mocha, JUnit). | | Reporters | `junit`, `allure`, `playwright-json`, `buildkite-json`. | Whatever the host runner emits (Allure, ExtentReports). | | Device fleet | Remote Android 15 emulators and iOS 26 simulators with sub-1s provisioning, multi-region. Local AVDs / simulators supported. | Bring-your-own: local devices, Appium server cluster, or device cloud (BrowserStack, Sauce, LambdaTest, AWS Device Farm). | | Dashboard | Run videos, traces, heal events, AI reasoning, screenshots, network. | Third-party (Allure, vendor dashboards). | **Sharding**: `--shard-index ` / `--shard-count `. Deterministic, contiguous partition of the test suite. **Device provisioning**: each test gets its own device session, so parallel runs don't share device state. No per-test execution cap. **Appium grid**: Appium servers run locally or in a Selenium Grid. Device farms layer their own provisioning on top. Common issues: stale UI hierarchies between sessions, dangling driver processes, capability drift across drivers and OS versions. ## Authoring side-by-side ```ts theme={null} // Appium with WebdriverIO import { remote } from "webdriverio"; const driver = await remote({ hostname: "localhost", port: 4723, capabilities: { platformName: "Android", "appium:deviceName": "emulator-5554", "appium:automationName": "UiAutomator2", "appium:app": "/path/to/app.apk", }, }); const email = await driver.$("~email_input"); // accessibility id await email.waitForDisplayed({ timeout: 10_000 }); await email.setValue("ada@example.com"); const password = await driver.$("~password_input"); await password.setValue("secret"); const signIn = await driver.$('//*[@text="Sign in"]'); // XPath await signIn.click(); await driver.waitUntil( async () => (await driver.$('//*[contains(@text, "Welcome")]')).isDisplayed(), { timeout: 10_000 }, ); // "Chart visible and not cut off" requires custom logic. await driver.deleteSession(); ``` Agentic simplified format: ```yaml theme={null} fileType: momentic/test/v2 id: quiet-maple-window steps: - act: Sign in with ada@example.com / secret - assert: The dashboard chart is visible and not cut off ``` Explicit simplified format (same flow, step-by-step): ```yaml theme={null} fileType: momentic/test/v2 id: quiet-maple-window steps: - type: text: ada@example.com into: Email - type: text: secret into: Password - tap: Sign in - assert: The dashboard chart is visible and not cut off ``` ## A more realistic test The hello-world above doesn't show the full simplified format surface. A representative onboarding regression with module reuse, parameter inputs, typed extraction, and a conditional looks like this: ```yaml onboarding.test.yaml theme={null} fileType: momentic/test/v2 id: velvet-river-comet steps: - launchApp - module: path: ../modules/sign-in.module.yaml inputs: EMAIL: env.QA_EMAIL PASSWORD: env.QA_PASSWORD - act: Skip the onboarding tour and land on Home - tap: Account - type: text: "{{ env.PROMO_CODE }}" into: Promo code field - tap: Apply - if: assert: A success banner saying the promo was applied is visible then: - extract: goal: The discounted monthly total shown on the plan card schema: type: object properties: amount: type: number required: [amount] - if: assert: An invalid-promo error is visible then: - assert: The plan price is unchanged - assertVisually: The plan card is fully visible and not cut off ``` The matching module: ```yaml ../modules/sign-in.module.yaml theme={null} fileType: momentic/module/v2 id: copper-forest-key name: Sign in parameters: - name: EMAIL - name: PASSWORD steps: - type: text: "{{ env.EMAIL }}" into: Email - type: text: "{{ env.PASSWORD }}" into: Password - tap: Sign in - assert: The Home tab is visible ``` There is no equivalent first-class surface in Appium. Reuse is by extracting host-language helpers; extraction is whatever the client codes; conditionals are `if` in the host language; visual assertions need a third-party plugin. ## When to pick which **Appium is the right call if** you have an existing Appium test suite the team wants to keep, you have a hard requirement for an OSS WebDriver-protocol layer, you need multi-language clients, or you do deep customization at the driver level (custom plugins, native command extensions). **Momentic is the right call if** wall-clock run time matters at scale, selector maintenance is a real recurring cost, you want AI assertions that fail the test by default, you'd rather author in YAML than maintain a multi-language WebDriver codebase, and you expect healing, recovery, quarantine, sub-second emulator boots, and run videos built in. For the build-it-yourself version of this decision, see [Build vs. buy](/docs/comparisons/build-vs-buy). # Build vs. buy Source: https://momentic.ai/docs/comparisons/build-vs-buy What the testing platform you build in-house has to own as your app changes, and which parts Momentic provides built in. Writing a first E2E test is cheap. The expensive part is the testing platform you build and run around those tests to keep them reliable as the product changes. It becomes a system your team maintains for the life of the product. This page lays out what that platform has to do, so you can scope it against adopting Momentic. With current models, you can build it. The tradeoff is whether your team wants to build, run, and maintain an internal testing product instead of shipping its own. A test can pass once and still require ongoing maintenance to gate releases reliably. That maintenance accounts for most of the cost. ## What you actually own Authoring tests is the part most people picture. The platform you build around them, the one you gate releases on, also has to: * **Replay cached steps and heal misses.** Calling an LLM on every step is slow, non-deterministic, and costs money per action. Cache the resolved locator and it is fast again, until the UI moves and the cached locator breaks. You own the logic that decides when to replay, when to re-resolve, and how to confirm the result was right. * **Survive UI changes.** A redesign, a renamed ID, a moved button: each one breaks locators, and someone has to fix them. That work grows with the app, not the team. * **Separate real bugs from flakes.** If a failing build might be noise, people stop trusting it, and a platform no one trusts cannot gate releases. * **Keep up with the product.** New behavior needs new tests. Skip it and coverage falls behind. * **Run as a service.** Runner, assertions, sharding, retries, reporting, browser and driver upgrades, mobile. Operating all of it is a job on its own. AI makes authoring tests cheaper. It does little for maintenance, triage, or operation, which are the recurring costs. ## The runtime-AI tradeoff Running an LLM inside the test is useful: it adapts when the page changes. It is also expensive, since you pay for a model call on every action. This leaves one tradeoff: | | Adapts to change | Speed and cost | Determinism | | ---------- | ---------------- | ---------------------------- | ----------------------------------------- | | **AI** | Yes | Slow, per-action \$ | Non-deterministic | | **Cached** | No | Fast; no model call per step | Deterministic; breaks when the UI changes | The recurring work is tuning that tradeoff (replay when safe, re-resolve only when needed) and confirming that passing runs are correct. For the tool-specific version of this tradeoff, see the [Stagehand](/docs/comparisons/stagehand) and [Playwright MCP](/docs/comparisons/playwright-mcp) comparisons. ## Estimating the cost Most of this cost is engineer time, so you can estimate it directly. The build is a one-time number. Maintenance, triage, and operation repeat every year and grow with the app. | Cost | How to size it | | -------------------- | ----------------------------------------------------------------------------------------------- | | Build (v1) | Engineers x months to reach a platform you trust, amortized over its life. | | Maintenance + triage | Engineer-hours per week fixing broken tests and sorting real failures from flakes, times 52. | | Operation | Engineer-hours per week on the framework itself (runner, sharding, upgrades, mobile), times 52. | Say fixing broken tests and triaging failures takes one engineer-day per week, and operating the framework another half-day. That is 12 hours per week, or about 620 hours per year. At a fully-loaded \$150 per hour, that is roughly \$95k per year, before the build, and it grows as you add tests. These numbers are illustrative. Use the bake-off below to replace them with measured ones from your own app. ## What Momentic provides built in Each row below is its own long-lived project if you build it in-house. | Capability | What it does | | --------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | | [Step cache](/docs/reliability/step-cache) | Replays a step's resolved locator with no LLM call until something changes, so steady-state runs cost about the same as plain Playwright. | | [In-run auto-heal](/docs/reliability/auto-maintenance#locator-auto-healing) | Re-resolves a locator from its natural-language description on a cache miss and waits for the page to settle before acting, so the run recovers on its own. | | [Post-run heal agent](/docs/reliability/auto-maintenance#permanent-healing) | After a failed run, rewrites the failing tests and opens a pull request or patch, so test fixes come to you as a code review. | | [Failure classification](/docs/cli-reference/momentic/commands/ai) | Sorts a failed run into a category (bug, application change, test issue, infra) with reasoning, so you can tell a real failure from a flaky or broken test. | | [MCP server](/docs/coding-agents/mcp-server) | Gives your coding agent the product, the tests, and a live browser session, so tests for new behavior are authored alongside the change itself. | | [App graph](/docs/ai/app-graph) (alpha) | A coverage model of your user journeys built from run traces, so you can see what is covered, partial, or missing instead of guessing from a test list. | | [Knowledge base](/docs/ai/knowledge-base) | Org-level memory of your terminology, rules, and flows, retrieved per AI step so steps resolve more accurately as it learns your product. | ## When building in-house makes sense Building in-house fits a few cases: A handful of flows that rarely change and that you can maintain by hand. OSS with no SaaS dependency, or compliance and isolation rules that rule out external tooling. You want to own testing as a core competency and have the platform capacity to staff it. If none of these hold, the recurring maintenance and reliability cost usually outweighs what you save by building. Those savings are in authoring, which is exactly where AI already helps, not in running and maintaining the platform. ## Decide with a bake-off The way to settle this is to run both approaches on the same work. A recent UI redesign and a flow with a history of breaking. These are where maintenance cost actually shows up. Cover the same journeys in-house and in Momentic. Let both run for a few weeks of normal merges, not a one-time trial run. Momentic's triage agent also edits tests, but those edits arrive as pull requests you review, so count the work a person actually had to do: * Commits whose only purpose was fixing tests. * Tests that broke and needed editing per UI change. * Failures fixed automatically vs. by hand. * Flake rate against an unchanged app. * Time to triage each failure, and whether it is automatic. * Engineer-hours per week spent operating the framework itself. Run the bake-off long enough to see the trend, not a single week. A short window usually favors building; what matters is whether maintenance per test rises or falls as the app grows. # Momentic vs a coding agent driving a browser Source: https://momentic.ai/docs/comparisons/coding-agents When to let your coding agent verify a change with computer use, and when to run a Momentic test and hand the result back to the agent. Cursor, Claude Code, Codex, and Devin can open a browser and check the change they just made. That works for one diff in one session, and the check disappears with the session. Momentic keeps the check as a YAML test in your repo, runs it on managed browsers, emulators, and simulators, and returns the evidence from a failing step to the agent over its [MCP server](/docs/coding-agents/mcp-server). For a running app with no test suite, see [Mo](/docs/mo). ## What each one is for | | Coding agent with computer use | Momentic | | ----------------- | --------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- | | Starting point | The diff in the current session. | A test file, or a goal for an [agentic step](/docs/core-concepts/agentic-testing). | | After the session | A message in the chat. | YAML in your repo, reviewed in a pull request and run by CI. | | Repeat runs | The agent reasons about the page again. | Steps replay from the [step cache](/docs/reliability/step-cache) with no AI call on a cache hit. | | A moved element | The run fails, or the agent guesses a new selector. | [Auto-heal](/docs/reliability/auto-maintenance#locator-auto-healing) re-resolves it mid-run. | | Concurrency | One browser per session. | [Hosted browsers, emulators, and simulators](/docs/running-tests/hosted-test-environments), sharded across CI jobs. | | Platforms | A browser. | Web, iOS simulators, and Android emulators from the same YAML format. | | Product context | What the agent reads in this session. | The [knowledge base](/docs/ai/knowledge-base) and [memory](/docs/ai/memory), retrieved on every AI-assisted step. | Agentic steps are non-deterministic. Keep critical paths step-based and wrap each agentic step in an assertion. See [agentic testing](/docs/core-concepts/agentic-testing). ## Read a failing run When a coding agent maintains the suite, it also debugs the runner. It re-runs a flaky spec, reads a stack trace, and guesses which selector moved. Each of those turns costs wall time before the agent reaches the product bug. The test adapts as it runs, so that work does not reach your agent. [Auto-heal](/docs/reliability/auto-maintenance#locator-auto-healing) re-resolves a moved locator mid-run, [failure recovery](/docs/reliability/auto-maintenance#failure-recovery) clears a transient obstruction and retries the step, and [classification](/docs/guides/auto-heal/in-flow-classification) triages what broke. When a run does fail, it produces artifacts per step, and the agent reads them through the MCP server: * Screenshots before and after each step. * A trace with the DOM, the network requests, and the console output. * The step execution order with each step's status and duration. * Video, when [`recordVideo`](/docs/configuration/momentic-config#recordvideo) is on. See [run artifacts](/docs/running-tests/results#artifacts) for where each one is stored, and [request visual evidence](/docs/coding-agents/mcp-server#inspect-visual-artifacts) for the prompts that make an agent display them. A typical loop: `npx momentic run` fails on a step and uploads the run. With the `momentic-maintain` skill, the agent finds the run for the branch, reads the saved classification, and opens the artifacts for the first step that changed behavior. A product bug goes back into the code. A stale locator or an intended behavior change goes into the test file, in the same pull request as the code. Devin can drive this loop with no extra setup beyond the MCP entry. See [Devin](/docs/integrations/devin). ## What a repeat run costs A coding agent that maintains a Playwright suite calls a model on every failure, and again on every rerun of a flaky spec. Because the run adapts itself, your agent is called for a product change and not for a test change, so the loop runs less often and each cycle is shorter. * Each run reports its duration and cost in the dashboard. See [run results](/docs/running-tests/results). * [Hosted browsers](/docs/running-tests/hosted-test-environments) run the suite off your CI machines, so the runners can be lower-spec. ## Product context between runs An agent session starts with no memory of your product. The [knowledge base](/docs/ai/knowledge-base) holds your terminology, per-agent rules, and known flows, and Momentic retrieves the relevant entries on every AI-assisted step. A decision you record, such as marking a finding expected behavior, becomes an entry that later runs retrieve. ## When the coding agent is the better tool * The check only covers the diff you are writing right now. Use `momentic-spec` so the affected tests land with the change; see [spec-driven development](/docs/coding-agents/mcp-server#spec-driven-development). * The task is a one-off inspection you do not want to keep, such as reading a staging page to confirm a deploy. * The work is a code change. Momentic does not read or write your product code. **Momentic is the right call if** the check must outlive the session, run on every merge, and cover flows nobody touched in this diff, and if you want the failing step handed back to your agent with its evidence instead of a stack trace. ## Related * [MCP server](/docs/coding-agents/mcp-server) * [Devin](/docs/integrations/devin) * [Momentic vs Playwright MCP](/docs/comparisons/playwright-mcp) * [Momentic vs Stagehand](/docs/comparisons/stagehand) # Momentic vs Maestro Source: https://momentic.ai/docs/comparisons/maestro Compare Momentic vs Maestro for mobile testing: managed step cache, AI assertions, recovery, and quarantine for stable runs. Momentic is a managed testing platform for iOS and Android. Tests are YAML, executed on managed remote emulators and simulators. A multi-modal step cache stores locator metadata per step and auto-heals in place when the UI changes. AI primitives cover action, assertion, visual diff, and typed extraction. AI providers route with cross-provider failover. A dashboard captures run videos, view hierarchies, heal events, and AI reasoning. [Maestro](https://docs.maestro.dev) is an open-source mobile UI automation framework from mobile.dev. Tests are YAML flows that drive the device through its accessibility layer. It's well-suited to fully-scripted test suites where the app team owns stable resource IDs and there's a hard requirement for an OSS CLI with no SaaS dependency. AI features (`assertWithAI`, `assertNoDefectsWithAI`, `extractTextWithAI`) are experimental commands that wrap a customer-supplied LLM. ## Speed and caching | | Momentic | Maestro | | ---------------------- | -------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------- | | What's cached | Multi-modal locator data per step ([docs](/docs/reliability/step-cache)). | Nothing. Selectors re-resolve every run. | | Heal on miss | Re-resolves and **updates the entry in place**. Heal event on the run. | Not supported. A miss is a test failure. | | Storage | Managed, git-aware. | N/A. | | Cost of a UI change | Auto-heal absorbs renamed IDs, localized strings, reordered hierarchies. | One YAML edit per broken selector. | | Smart waiting | Built-in: navigation, `load`, screenshots, DOM / view-hierarchy mutations, same-origin requests. 3s default, configurable. | Animation tolerance + `extendedWaitUntil`. No XHR tracking on WebViews. | | Per-test execution cap | None. | 15-minute soft limit on Maestro Cloud. | ## How the multi-modal cache works A cached step stores more than one way to find the target: where it sits on screen, what it looks like, what text it contains, and the accessibility and structural attributes around it. Which of those signals matters for a given step is inferred from the natural-language description. "The red Cancel button below the Order Summary header" leans on visual and positional signals; "the Sign in button" leans on accessibility and text. When a step replays, the runner checks the stored signals against the live UI and runs the action without invoking the LLM when there's a match. ## What happens on a UI change A practical sequence that shows the difference. Take a mobile sign-in screen with an `email_input` resource ID, after a passing baseline run where the cache is warm. **Refactor:** the app team renames `email_input` to `email_field` and changes the surrounding container hierarchy. **Maestro replay:** 1. `tapOn: { id: "email_input" }` retries against the device for \~5s. 2. The retry window elapses with no match. The step fails. 3. The test stops; the CI job fails. Someone edits the YAML to use the new ID or switches the selector to a `text` match, opens a PR, gets it merged, and re-runs CI. **Momentic replay:** 1. The cached locator for the `Email` step misses on the live UI. 2. The locator agent re-resolves the original natural-language description `Email`. 3. The new locator binds, the step runs, the test passes. 4. The cache entry is updated in place. A heal event is attached to the run for review. Subsequent runs hit the cache normally. Across a test suite, a renamed ID or a localized string requires no test edits in Momentic but a manual PR in Maestro. Selector commands have a default \~5s retry window with animation tolerance. WebViews require app-side debug enablement; XHR is not tracked. Long flows reach for `extendedWaitUntil { visible: ..., timeout: ... }`. ## Locators and AI primitives | | Momentic | Maestro | | ----------------- | --------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | Locator model | Natural-language descriptions resolved by an AI agent against a11y tree + view hierarchy + screenshot. Cached, auto-healed. | Static selectors: `text`, `id`, `index`, `point`, relational. | | Visual cues | Color, icon, relative size, position part of the locator. | Not supported. | | Agentic step | `act` accepts a multi-step goal; the agent plans and executes. | Not supported. | | WebView | Bundled Chromium; works inside hybrid apps without setup. | Debugging must be enabled by the app team. | | AI assert default | First-class step type, fails the test by default. | Experimental. Defaults to `optional: true`, so a failed AI assertion silently passes unless every call site sets `optional: false` ([Maestro docs](https://docs.maestro.dev/reference/commands-available/assertwithai)). | | Visual diff | `assertVisually`, agent-scored against a golden. | `assertScreenshot` (pixel / hash diff). | | AI provider | Managed; cross-provider failover handled by the platform. | Bring-your-own LLM, credentials, fallback. | **Momentic mobile step types** * Action: `act`, `tap`, `doubleTap`, `longPress`, `type`, `swipe`, `scroll`, `back`, `dismissKeyboard`, `launchApp`, `terminateApp` * Assert: `assert`, `assertVisually`, `checkElement<...>` * Extract: `extract` (typed via JSON schema) * Control flow: `if/then`, modules, parameter inputs **Maestro `assertWithAI` default** ([source](https://docs.maestro.dev/reference/commands-available/assertwithai)) > Since `assertWithAI` is an experimental feature, `optional` is set to `true` > by default to prevent unstable AI responses from breaking your CI/CD > pipelines. If you want a failed AI assertion to stop the test, you must > explicitly set `optional: false`. A team that wants AI assertions to fail the test must set `optional: false` on every call site because Maestro has no project-level default. ## Recovery, quarantine, and CI | | Momentic | Maestro | | ---------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------- | | Failure recovery | Post-run triage agent (`momentic ai triage`) rewrites failing tests and opens a PR or patch in CI; `momentic ai classify` triages the failure. | Not supported. | | Quarantine | First-class: tests run, results report, exit code unaffected unless `--only-quarantined`. | Not supported. | | Sharding | `--shard-index ` / `--shard-count `, 1-indexed. Deterministic alphabetical partition. | Parallel on Cloud; shard via CI config. | | Reporters | `junit`, `allure`, `playwright-json`, `buildkite-json`. | `junit`, HTML, HTML-detailed; Cloud dashboard. | | Device fleet | Remote Android 15 emulators and iOS 26 simulators with sub-1s provisioning, multi-region. Local AVDs / simulators supported. | Hosted virtual devices on Cloud. Physical hardware via CLI. | * Default: quarantined tests run, results report, exit code unaffected. * `--skip-quarantined`: skipped entirely. * `--only-quarantined`: only quarantined tests run; statuses affect exit code. ## Authoring side-by-side ```yaml theme={null} # Maestro - launchApp - tapOn: { id: "email_input" } - inputText: "ada@example.com" - tapOn: { id: "password_input" } - inputText: "secret" - tapOn: "Sign in" - assertVisible: "Welcome back" - assertWithAI: assertion: "The dashboard chart is visible and not cut off." optional: false # required, or a failed assertion silently passes ``` If `email_input` is renamed or `"Sign in"` is localized, the YAML breaks until someone edits it. Agentic simplified format: ```yaml theme={null} fileType: momentic/test/v2 id: misty-harbor-lantern steps: - act: Sign in with ada@example.com / secret - assert: The dashboard chart is visible and not cut off ``` Explicit simplified format (same flow, step-by-step): ```yaml theme={null} fileType: momentic/test/v2 id: misty-harbor-lantern steps: - type: text: ada@example.com into: Email - type: text: secret into: Password - click: Sign in - assert: The dashboard chart is visible and not cut off ``` ## A more realistic test The hello-world above doesn't show the full simplified format surface. A representative onboarding regression with module reuse, parameter inputs, typed extraction, and a conditional looks like this: ```yaml onboarding.test.yaml theme={null} fileType: momentic/test/v2 id: bright-cedar-orbit steps: - launchApp - module: path: ../modules/sign-in.module.yaml inputs: EMAIL: env.QA_EMAIL PASSWORD: env.QA_PASSWORD - act: Skip the onboarding tour and land on Home - tap: Account - type: text: "{{ env.PROMO_CODE }}" into: Promo code field - tap: Apply - if: assert: A success banner saying the promo was applied is visible then: - extract: goal: The discounted monthly total shown on the plan card schema: type: object properties: amount: type: number required: [amount] - if: assert: An invalid-promo error is visible then: - assert: The plan price is unchanged - assertVisually: The plan card is fully visible and not cut off ``` The matching module: ```yaml ../modules/sign-in.module.yaml theme={null} fileType: momentic/module/v2 id: coral-meadow-key name: Sign in parameters: - name: EMAIL - name: PASSWORD steps: - type: text: "{{ env.EMAIL }}" into: Email - type: text: "{{ env.PASSWORD }}" into: Password - tap: Sign in - assert: The Home tab is visible ``` ## When to pick which **Maestro is the right call if** you have a small fully-scripted test suite, your app team maintains stable resource IDs the test relies on, you have a hard requirement for physical hardware in the CLI, or you need an OSS framework with no SaaS dependency. **Momentic is the right call if** wall-clock run time matters at scale, your test suite is large enough that selector maintenance is a real recurring cost, you want AI assertions that fail the test by default, and you expect healing, recovery, quarantine, sub-second emulator boots, and run videos built in. For the build-it-yourself version of this decision, see [Build vs. buy](/docs/comparisons/build-vs-buy). # Momentic vs Playwright MCP Source: https://momentic.ai/docs/comparisons/playwright-mcp Compare Momentic vs Playwright MCP: preview-then-commit loop and step cache vs interact-then-generate for reliable automation. Momentic is a managed testing platform for the web with its own MCP server. A coding agent (Cursor, Claude Code, Codex, any MCP client) previews each candidate step against the live page, gets a screenshot back, and only commits the step on success. Saved tests are YAML, executed on a managed runner with a multi-modal step cache and auto-heal so generated tests replay deterministically. [Playwright MCP](https://github.com/microsoft/playwright-mcp) is Microsoft's open-source MCP server. It lets a coding agent (Cursor, Claude Code, VSCode Copilot) drive a browser, capture snapshots, and synthesize Playwright tests. It's a fit for teams already on Playwright who want to assist authoring with a coding agent and end up with standard Playwright code. ## Speed and caching | | Momentic | Playwright MCP | | ---------------------- | --------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------ | | What's cached | Multi-modal locator data per step ([docs](/docs/reliability/step-cache)). | Nothing. PW MCP is an authoring tool; generated Playwright tests don't cache either. | | Waiting | Built-in: navigation, `load`, screenshots, DOM mutations, same-origin requests. 3s default, configurable. | Generated tests use hard-coded `waitForTimeout`; manual `waitForResponse` per request. | | Agent context per step | Screenshot + short status. Locator resolution / assertion evaluation happens server-side, outside the agent's prompt. | Full browser snapshot per `browser_*` tool call (DOM + a11y tree + console). Accumulates across the session. | | Runtime hit cost | Milliseconds, no LLM call. | N/A. Speed is whatever Playwright config + hard-coded waits allow. | | Heal on miss | Re-resolves and **updates the entry in place** mid-run. | N/A. A broken selector is a test failure. | ## How the multi-modal cache works A cached step stores more than one way to find the target: where it sits on screen, what it looks like, what text it contains, and the structural and accessibility attributes around it. Which of those signals matters for a given step is inferred from the natural-language description. "The red Cancel button below the Order Summary header" leans on visual and positional signals; "the Submit button in the form" leans on structure and role. When a step replays, the runner checks the stored signals against the live page and runs the action without invoking the LLM when there's a match. ## What happens on replay The authoring loop only matters if the generated artifact survives the next day. Take this generated Playwright spec the day after authoring, against the same app with one change: the team replaced the static welcome string with a personalized one (`"Welcome, Ada"` -> `"Hi Ada, welcome back"`). **Playwright MCP, replay:** 1. `page.locator('input[type="email"]').fill(...)` and the subsequent interactions resolve normally. 2. `page.waitForTimeout(2000)` blocks for 2s regardless of whether the page is ready. 3. `expect(page.getByText("Welcome, Ada")).toBeVisible()` fails. The text was guessed from the snapshot the agent saw during authoring; it no longer matches. 4. The CI job fails. The maintainer either re-runs the MCP authoring loop from scratch or hand-edits the spec to use a different selector. Either way it's a code review. **Momentic, replay:** 1. `type` / `click` steps hit the cache and run in milliseconds. 2. `assert: The dashboard chart is visible and not cut off` is evaluated by the assertion agent against the current page state. The agent reasons over the intent of the assertion, not a literal string match, so the rephrased welcome banner doesn't trip it. 3. The test passes without a code change to review. Playwright MCP materializes locators and string literals at authoring time, so a change to either is a test failure. Momentic resolves user-intent descriptions at runtime, caches them for speed, and re-resolves them when the UI changes, so the same change heals instead of failing. Each MCP tool call (`browser_click`, `browser_snapshot`, `browser_navigate`, ...) returns a structured snapshot of the page: rendered DOM, a11y tree, and console messages. The agent's prompt history accumulates every snapshot from every tool call in the session. Momentic's MCP server returns a compressed screenshot plus a short status from each preview / run call. Snapshot expansion happens server-side during locator resolution; the full DOM is only returned when the agent explicitly asks for the session state. Locator resolution runs against the cache first; cache hits return without invoking the LLM at all. ## Authoring loop | | Momentic | Playwright MCP | | --------------------- | ------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | | Loop | Preview each step against the live page -> commit on success. | Interact through the browser from memory -> generate Playwright code at the end. | | Generated artifact | `act` / `assert` / `extract` step targeting user intent. | `locator` / `getByRole` / `expect` / `waitForTimeout` materialized at generation time. | | Editing a test | Splice individual steps; browser session persists across edits. | Full browser and session reset; agent replays from memory. | | Hidden / transient UI | Interacts with `aria-disabled`, 0-opacity, 0-bbox elements when user-reachable. | Often fails on Chakra-style hidden / transient elements. | | Supported clients | Cursor, Claude Code, Codex, any MCP client. | VSCode, Claude Code. | Add a spec-driven section to `AGENTS.md` so the coding agent keeps Momentic tests in sync with feature work. See [the integration docs](/docs/coding-agents/mcp-server#spec-driven-development). ```md theme={null} ## Momentic spec-driven development - Before starting any UI implementation, sketch the desired user flows as Momentic tests. Prefer `act` steps (AI action V3). - After any UI change, update the relevant Momentic tests so they describe the new behavior. ``` ## Generated artifact side-by-side Playwright MCP (after running the flow once from memory): ```ts theme={null} import { expect, test } from "@playwright/test"; test("sign in and verify", async ({ page }) => { await page.goto("https://app.example.com"); await page.locator('input[type="email"]').fill("ada@example.com"); await page.locator('input[type="password"]').fill("secret"); await page.getByRole("button", { name: "Sign in" }).click(); await page.waitForTimeout(2000); // hard-coded await expect(page.getByText("Welcome, Ada")).toBeVisible(); // text guessed from snapshot }); ``` The text was guessed from a stale snapshot; the `2000ms` wait was inserted because the agent saw a transient loading state. Replay often fails on one or both. Agentic simplified format (each step previewed live before commit): ```yaml theme={null} fileType: momentic/test/v2 id: golden-sparrow-window url: https://app.example.com steps: - act: Sign in with ada@example.com / secret - assert: The dashboard chart is visible and not cut off ``` Explicit simplified format (same flow, step-by-step): ```yaml theme={null} fileType: momentic/test/v2 id: golden-sparrow-window url: https://app.example.com steps: - type: text: ada@example.com into: Email - type: text: secret into: Password - click: Sign in - assert: The dashboard chart is visible and not cut off ``` The test contains no hard-coded waits, guessed text, or brittle selectors materialized at generation time. ## A more realistic test The hello-world above doesn't show the full simplified format surface. A representative checkout regression with module reuse, parameter inputs, typed extraction, and a conditional looks like this: ```yaml checkout.test.yaml theme={null} fileType: momentic/test/v2 id: calm-river-compass url: https://shop.example.com steps: - module: path: ../modules/sign-in.module.yaml inputs: EMAIL: env.QA_EMAIL PASSWORD: env.QA_PASSWORD - act: Add the Tetris Eye Sweatshirt (size M) to the cart - navigate: https://shop.example.com/checkout - type: text: "{{ env.PROMO_CODE }}" into: Promo code field - click: Apply - if: assert: A success banner saying the promo was applied is visible then: - extract: goal: The discounted subtotal in the order summary schema: type: object properties: amount: type: number required: [amount] - if: assert: An invalid-promo error is visible then: - assert: The subtotal is unchanged - assertVisually: The order summary section is fully visible and not cut off ``` The matching module: ```yaml ../modules/sign-in.module.yaml theme={null} fileType: momentic/module/v2 id: violet-maple-bridge name: Sign in parameters: - name: EMAIL - name: PASSWORD steps: - type: text: "{{ env.EMAIL }}" into: Email - type: text: "{{ env.PASSWORD }}" into: Password - click: Sign in - assert: The dashboard chart is visible and not cut off ``` ## When to pick which **Playwright MCP is the right call if** you have an existing Playwright codebase you want to keep, your test suite is small and stable, you have a hard requirement for OSS with no SaaS, and your agent surface is VSCode or Claude Code only. **Momentic is the right call if** coding agents are part of your authoring flow at scale, you need generated tests to replay deterministically without re-prompting, your product churns frequently enough that hard-coded waits and text assertions break on a weekly basis, and you expect AI-native primitives + auto-heal + recovery + a managed dashboard built in. For the build-it-yourself version of this decision, see [Build vs. buy](/docs/comparisons/build-vs-buy). # Momentic vs Stagehand Source: https://momentic.ai/docs/comparisons/stagehand Compare Momentic vs Stagehand: multimodal step cache, AI primitives, and managed runners for faster, reliable browser automation. Momentic is a managed testing platform for the web. Tests are YAML, executed on a managed runner. A multi-modal step cache stores locator metadata per step and auto-heals in place when the UI changes. AI primitives cover action, assertion, visual diff, and typed extraction. AI providers route with cross-provider failover behind a single managed surface. A dashboard captures run videos, traces, network, heal events, and AI reasoning. [Stagehand](https://docs.stagehand.dev/get_started/introduction) is an open-source TypeScript library from Browserbase. It adds four AI primitives (`act`, `observe`, `extract`, `agent`) on top of Playwright. With `env: "BROWSERBASE"` it adds **Browserbase Cache** (server-side, on by default) and **Browserbase Model Gateway** (one Browserbase key routes to OpenAI, Anthropic, Google). It's a fit for teams that want programmatic TypeScript control with a thin AI layer over Playwright. ## Speed and caching | | Momentic | Stagehand | | --------------------- | --------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | What's cached | Multi-modal locator data per step ([docs](/docs/reliability/step-cache)). | Resolved action per `act` call. | | DOM-change resilience | Unrelated DOM changes don't invalidate the entry. | Any structural change in the a11y tree (banner mount, modal open, streaming content) flips the hash. Docs recommend `waitForLoadState("networkidle")` before every action. | | Heal on miss | Re-resolves and **updates the entry in place**. Heal event on the run. | Re-resolves and writes a **new entry** under the new key. | | Storage | Managed, git-aware. | Browserbase Cache (server-side, requires `env: "BROWSERBASE"`) or Local Cache (JSON in repo). | | Smart waiting | Built-in: navigation, `load`, screenshots, DOM mutations, same-origin requests. 3s default, configurable. | Playwright actionability + manual `waitForLoadState` / `waitForResponse`. | ## How the multi-modal cache works A cached step stores more than one way to find the target: where it sits on screen, what it looks like, what text it contains, and the structural and accessibility attributes around it. Which of those signals matters for a given step is inferred from the natural-language description. "The red Cancel button below the Order Summary header" leans on visual and positional signals; "the Submit button in the form" leans on structure and role. When a step replays, the runner checks the stored signals against the live page and runs the action without invoking the LLM when there's a match. On a miss, the locator agent ([auto-heal](/docs/reliability/auto-maintenance#locator-auto-healing)) re-resolves the original description against the live page, updates the cache entry in place, and the run continues. A heal event is recorded against the run. Stagehand's Browserbase Cache keys on the page's accessibility tree, so any background change (a transient banner, a streaming widget, an A/B variant) flips the key even when the target itself hasn't changed. The [Stagehand caching docs](https://docs.stagehand.dev/best-practices/caching) recommend `page.waitForLoadState("networkidle")` before every action to keep the tree stable enough to hit. On miss, Stagehand re-runs the LLM and writes a **new** entry under the new key; the old entry isn't reused. Local Cache writes a JSON file under `cacheDir`; the team owns expiry, ignore rules, and lock contention. ## AI primitives and assertions | | Momentic | Stagehand | | ----------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Primitives | 40+ step types: `act`, `assert`, `extract`, `assertVisually`, drag-and-drop, file upload, hover, `` elements (useful for UI frameworks that style hidden inputs). ```yaml momentic.config.yaml theme={null} browser: showZeroOpacityElements: inputs-only ``` ## Locator and cache tuning Default: `always`. Use Momentic's algorithm to find the top-most interactable element when a target is covered by another element. Other frameworks [throw](https://playwright.dev/docs/actionability#receives-events) or require [`force`](https://playwright.dev/docs/actionability#forcing-actions); this redirects to the covering element instead. * `false`: disabled. * `true`: only redirects on `CLICK` steps (backwards-compat). * `always`: redirects on all interactive steps. See [Global locator redirect](/docs/reliability/global-locator-redirect) for the full algorithm. ```yaml momentic.config.yaml theme={null} browser: globalLocatorRedirect: always ``` When `globalLocatorRedirect` can't find a valid redirect target, force-click the original element anyway instead of failing actionability checks. Default: `false`. ```yaml momentic.config.yaml theme={null} browser: forceClickForMissingRedirectElement: true ``` Resolve element coordinates with a visual heuristic and use those coordinates for clicks, hovers, and typing. Default: `false`. ```yaml momentic.config.yaml theme={null} browser: visualActions: true ``` Ignore the `href` attribute when matching cached anchors. Useful on sites with auto-generated or rotating links. Only applies when the anchor has text content. Default: `false`. ```yaml momentic.config.yaml theme={null} browser: ignoreHrefForCaching: true ``` Disable Levenshtein distance validation when resolving cached elements. When enabled, the cache accepts any element that passes CSS/hybrid selector matching and requirements checks without comparing its serialized HTML to the cached version. Default: `false`. ```yaml momentic.config.yaml theme={null} browser: disableLdistCacheValidation: true ``` Disable HTML l-dist and template-matching cache fallbacks. Faster but less accurate. Cache entries can occasionally resolve to the wrong element. Default: `false`. ```yaml momentic.config.yaml theme={null} browser: disableSecondaryCacheResolution: false ``` Hybrid selectors are in beta and may change. Default: `prefer`. Hybrid selectors combine text content, classes, attributes, parent hierarchy, and shadow-DOM-piercing to identify elements more resiliently than CSS selectors. * `off`: disabled. * `test`: save and resolve hybrid selectors, but report mismatches to Momentic without using them. * `prefer`: resolve with hybrid selectors first, fall back to CSS. * `always`: only use hybrid selectors; fall back to AI on miss. Hybrid selectors weight text content heavily. If you need a specific child in a hierarchy, use nth keywords with **Disable cache**. ```yaml momentic.config.yaml theme={null} browser: hybridSelectorMode: prefer ``` ## AI context filtering Extra HTML attributes that should never be pruned from AI context. Common testing attributes (`data-test-id`, `aria-label`, etc.) are always important. Suffix with `*` for a prefix match. ```yaml momentic.config.yaml theme={null} browser: importantAttributes: - data-topic-id - data-test-* ``` CSS class names that mark an element as important. Matching elements are never pruned from AI context. Suffix with `*` for a prefix match. ```yaml momentic.config.yaml theme={null} browser: importantClasses: - list-controls - home-page-* ``` HTML attributes to strip from AI context AND ignore when matching cached elements. Use this for attributes whose values change between renders (e.g. framework-generated `for` IDs) that otherwise bust the cache every run. Suffix with `*` for prefix matches. ```yaml momentic.config.yaml theme={null} browser: bannedAttributes: - for - aria-controls - data-dynamic-* ``` If the attribute is genuinely useful for identifying elements, list it under [`browser.importantAttributes`](#browser-importantattributes) instead. # Environment variables Source: https://momentic.ai/docs/configuration/environment-variables How Momentic reads environment variables and secrets at runtime, in order of precedence. Momentic resolves environment variables from three places, in order of precedence: 1. **CLI flags** (e.g. `--env`) 2. **The enclosing shell** when `inheritFromShell: true` is set on an environment 3. **`momentic.config.yaml`**, either inline under [`envVariables`](/docs/configuration/environments#environments-envvariables) or loaded from an [`envFile`](/docs/configuration/environments#environments-envfile) / JSON file See [`environments`](/docs/configuration/environments) for the full schema. ## Secrets For passwords, API tokens, and other secrets, prefer a `.env` file or shell / CI environment variables over inlining values in `momentic.config.yaml`. See [Secrets](/docs/configuration/environments#secrets) for the recommended patterns. ## Reserved variables These are set automatically at runtime and accessible in any step via `{{ env.NAME }}`: | Variable | Description | | ------------- | ----------------------------------- | | `BASE_URL` | Base URL of the current environment | | `CURRENT_URL` | URL of the page being tested | | `ENV_NAME` | Name of the current environment | | `TEST_NAME` | Name of the test being executed | ## Accessing in tests Use the templating syntax anywhere a step accepts a string: ```yaml theme={null} - type: text: "{{ env.USERNAME }}" into: Email field ``` Or access `env.VARIABLE` directly inside a **JavaScript** step. ## Setting at runtime Use `setVariable` inside a **JavaScript** step to write a variable: ```javascript theme={null} setVariable("OTP_CODE", "123456"); ``` Or use the **Save to environment variable** option on any step with a return value (e.g. **AI extract**, **JavaScript**). # Environments Source: https://momentic.ai/docs/configuration/environments Reference for the `environments` array in `momentic.config.yaml`. Each environment defines a base URL and a set of variables (including secrets) available to tests. Define one or more environments to run tests against. Each provides a `baseUrl` and a set of [variables](/docs/core-concepts/variables) available to tests as `env.*`. ```yaml momentic.config.yaml theme={null} environments: - name: dev baseUrl: https://dev.example.com envVariables: USERNAME: devUser PASSWORD: devPassword - name: staging baseUrl: https://staging.example.com envVariables: USERNAME: stagingUser PASSWORD: stagingPassword - name: production baseUrl: https://www.example.com envVariables: USERNAME: prodUser PASSWORD: prodPassword ``` For details on how Momentic resolves variables at runtime, see [Environment variables](/docs/configuration/environment-variables). ## Select an environment Momentic reads the environment name from `--env ` first, then from `defaultEnv` in the test file. There is no fallback. A test does not use the only environment in the config automatically. If neither value is set, no environment resolves. Pair the environment name in your config with `defaultEnv` in the test: ```yaml momentic.config.yaml theme={null} environments: - name: dev baseUrl: https://dev.example.com ``` ```yaml checkout.test.yaml theme={null} fileType: momentic/test/v2 id: silver-river-lantern name: Checkout defaultEnv: dev steps: - assert: The checkout page is visible ``` The base URL comes from `--url-override` first, then the test's own `url`, then `env.BASE_URL` from the selected environment. A test that sets `url` therefore keeps that URL in every environment. If no value is available, the run fails with: ```text theme={null} Cannot run test with no base URL and no BASE_URL variable defined in its environment ``` ### Mobile tests A mobile test selects its environment the same way, through `defaultEnv` and `--env`. Mobile has no base URL. The app comes from a [channel and a tag](/docs/running-tests/hosted-test-environments#app-assets-channels-and-tags) instead: ```yaml checkout.test.yaml theme={null} fileType: momentic/mobile-test/v2 id: emerald-forest-signal description: Checkout platform: android defaultEnv: dev defaultChannel: staging defaultTag: nightly steps: - tap: Checkout button ``` `defaultChannel` names the channel to install from, and `--channel` overrides it. `defaultTag` accepts a tag or an alias such as `nightly`, and `--tag` overrides it. `defaultTag` is optional: without it, Momentic installs the latest tag in the channel. In the `local` region, the test installs `defaultApkFilePath` or `defaultAppFilePath` from your machine, and the channel and the tag are unused. ## Environment isolation By default, Momentic shares cache entries across environments in the same project. This keeps repeat runs fast when `dev`, `staging`, and `production` render the same UI. If environments have different DOM structures, mobile screens, feature flags, or environment-specific IDs, enable [`advanced.isolateCachesByEnvironment`](/docs/configuration/advanced#advanced-isolatecachesbyenvironment). When enabled, Momentic stores separate [step cache](/docs/reliability/step-cache) entries for each selected environment, so a cache learned in `staging` will not replay in `production`. ```yaml momentic.config.yaml theme={null} environments: - name: staging baseUrl: https://staging.example.com - name: production baseUrl: https://www.example.com advanced: isolateCachesByEnvironment: true ``` ## Per-environment options Name of the environment. Selected at runtime via `--env ` or `defaultEnv` in the test file, and exposed to tests as `env.ENV_NAME`. ```yaml momentic.config.yaml theme={null} environments: - name: dev ``` Starting URL for tests in this environment. Exposed as `env.BASE_URL`. ```yaml momentic.config.yaml theme={null} environments: - name: dev baseUrl: https://dev.example.com ``` Key-value pairs available to tests as `env.VARIABLE_NAME`. Values may reference shell variables via [dotenvx interpolation](https://dotenvx.com/docs/env-file#interpolation), but cannot reference other variables defined in the same `envVariables` block. ```yaml momentic.config.yaml theme={null} environments: - name: dev envVariables: USERNAME: devUser API_KEY: ${VAR_FROM_SHELL:-default_value} ``` Use the `fromFile` form to load values from a JSON file: ```yaml momentic.config.yaml theme={null} environments: - name: dev envVariables: VAR_FROM_FILE: fromFile: package.json json: true ``` Include every variable from the enclosing shell at runtime. Default: `false`. ```yaml momentic.config.yaml theme={null} environments: - name: dev inheritFromShell: true ``` Path to a `.env`-format file to load. Each line is a `KEY=VALUE` pair; values become `env.VARIABLE_NAME`. ```yaml momentic.config.yaml theme={null} environments: - name: dev envFile: .dev.env ``` HTTP proxy configuration scoped to this environment. `server` must include the protocol (`http://` or `https://`), host, and port. ```yaml momentic.config.yaml theme={null} environments: - name: dev browser: proxy: server: http://proxy.internal.example.com:3128 username: my-proxy-user password: my-proxy-password ``` ## Secrets Keep passwords, API tokens, and other secrets out of `momentic.config.yaml` and out of version control. Provide them at runtime through one of these; the resolved values are still read in tests as `env.*`: Point an environment at a `.env`-format file with [`envFile`](#environments-envfile) and keep that file out of git (`.gitignore`). Each `KEY=VALUE` line becomes `env.KEY`. ```yaml momentic.config.yaml theme={null} environments: - name: dev envFile: .secrets.env ``` ```bash .secrets.env theme={null} PASSWORD=super-secret API_TOKEN=sk_live_... ``` Set the secret as an environment variable in your shell or CI secrets manager, then either inherit the whole shell with [`inheritFromShell`](#environments-inheritfromshell) or reference individual variables with [dotenvx interpolation](https://dotenvx.com/docs/env-file#interpolation) (`${SHELL_VAR}`). ```yaml momentic.config.yaml theme={null} environments: - name: ci inheritFromShell: true # pull every variable from the enclosing shell - name: dev envVariables: API_TOKEN: ${API_TOKEN} # read one variable from the shell ``` This is the standard pattern in CI: store the value as a masked secret and expose it to the `momentic run` step. See the [CI/CD guides](/docs/running-tests/ci/github-actions) for per-provider setup. Your Momentic API key is a secret too. Export it as `MOMENTIC_API_KEY` rather than committing it; see [API keys](/docs/account/api-keys-and-team#setting-a-key). For 2FA/TOTP secrets specifically, see [Log in with OTPAuth](/docs/guides/auth/otpauth). # Mobile configuration Source: https://momentic.ai/docs/configuration/mobile Reference for the `emulator` block in `momentic.config.yaml`. Controls mobile emulators used by the local editor and `momentic-mobile`. The `emulator` block configures remote mobile emulators used by the local editor and `momentic-mobile` CLI. Only applies to mobile test runs. ```yaml momentic.config.yaml theme={null} emulator: region: us autoGrantPermissions: true ``` Region where the emulator runs. Continent values (`us`, `eu`, `as`) are recommended because they let Momentic schedule across every data center in the continent, which improves allocation reliability compared to pinning a specific data-center region. Specific regions (`us-east1`, `us-east2`, `us-west1`, `us-west2`, `eu-north1`, `as-south1`) are still accepted when you need deterministic latency to a particular location. `as` is Android-only. When unset, Momentic picks the region closest to the user's source IP. ```yaml momentic.config.yaml theme={null} emulator: region: us ``` Pin emulators to a single jurisdiction. Within that jurisdiction, the emulator may be scheduled in any of its data centers, but never outside it: unlike `emulator.region`, which is a scheduling preference that can fall back to other regions when capacity runs out, `jurisdiction` is a hard constraint, and creation fails if no capacity is available inside it. Set this when your app has data residency requirements, e.g. it must never run outside the US. Setting a `region` outside the jurisdiction is rejected as a configuration error before any emulator is created. `as` is Android-only; combining `platform: ios` with `jurisdiction: as` is also rejected. When unset, emulators may fall back to any region worldwide. ```yaml momentic.config.yaml theme={null} emulator: jurisdiction: us ``` `region` is not required alongside `jurisdiction`. On its own, `jurisdiction` schedules the emulator in whichever of the jurisdiction's data centers is closest. Combine the two only to express a latency preference within the jurisdiction, e.g. `region: us-west1` with `jurisdiction: us`. **Android only.** Auto-grant permissions to the app under test at install and launch time, so permission confirmation dialogs (camera, location, notifications, etc.) never appear. Has no effect on iOS; use `emulator.autoAcceptAlerts` there instead. Default: `false`. ```yaml momentic.config.yaml theme={null} emulator: autoGrantPermissions: true ``` **iOS only.** Automatically accept native alert dialogs as they appear during the run, including permission prompts ("Allow ... to access ...") and other system alerts. Should not be combined with `emulator.autoDismissAlerts`. Has no effect on Android; use `emulator.autoGrantPermissions` there instead. Default: `false`. ```yaml momentic.config.yaml theme={null} emulator: autoAcceptAlerts: true ``` **iOS only.** Automatically dismiss native alert dialogs as they appear during the run, declining permission prompts and closing other system alerts. Should not be combined with `emulator.autoAcceptAlerts`. Default: `false`. ```yaml momentic.config.yaml theme={null} emulator: autoDismissAlerts: true ``` **Android only.** Stream emulator logcat entries into the local editor and CLI run output. Capture is disabled by default as a performance optimization that reduces continuous log streaming and can reduce emulator lag, especially during local editor sessions. Enable it when retaining logcat entries for debugging is more important than emulator responsiveness. Individual tests can override the project default from the test options dialog. Default: `false`. ```yaml momentic.config.yaml theme={null} emulator: enableLogcatCapture: true ``` **iOS only.** Stream simulator syslog entries into the local editor and CLI run output. Capture is disabled by default as a performance optimization that reduces continuous log streaming and can reduce simulator lag, especially during local editor sessions. Enable it when retaining syslog entries for debugging is more important than simulator responsiveness. Individual tests can override the project default from the test options dialog. Default: `false`. ```yaml momentic.config.yaml theme={null} emulator: enableSyslogCapture: true ``` How long to wait for a local emulator or simulator to finish starting, in milliseconds. Raise it on slow machines such as hosted CI runners, where a fresh simulator or emulator can take several minutes to boot. Has no effect on remote emulators. Default: `300000`. ```yaml momentic.config.yaml theme={null} emulator: localEmulatorStartTimeout: 420000 ``` Use the native Android accessibility tree inside webviews instead of Momentic's custom implementation. The custom implementation includes more elements by default. Disabling it can speed webview interactions by 1-2 seconds but may break interactions with elements outside the viewport. Default: `false`. ```yaml momentic.config.yaml theme={null} emulator: disableMomenticAccessibilityTree: true ``` Budget for every wait and retry on a single interaction, in milliseconds: settling the screen, the readiness check before Momentic locates an element with AI, and retrying a cached element. Raise it for apps that take a long time to render; lower it to fail faster. Default: `5000`. ```yaml momentic.config.yaml theme={null} emulator: smartWaitingTimeoutMs: 10000 ``` Wait for the screen to settle after every step that can change it, so one step's effects land before the next step runs. Assertions, extracts, and waits do not change the screen and are unaffected. Turn this on for apps that load incrementally or animate between screens. Default: `false`. This does not control the waits that happen *before* Momentic targets an element. Locating an element with AI always waits for the screen to be ready first, and a cached element is retried until `smartWaitingTimeoutMs` either way, so leaving this off does not make targeting less reliable. This setting only means that step's effects are not waited on before the next step begins. ```yaml momentic.config.yaml theme={null} emulator: waitForStability: true ``` Default maximum wait time for element check assertions to become true, in seconds. Element check steps with an explicit timeout are unaffected. Default: `5`. ```yaml momentic.config.yaml theme={null} emulator: elementCheckTimeoutSeconds: 10 ``` Default delay between key presses for type steps, in milliseconds. Steps with an explicit key press delay are unaffected. Increase this if your app needs more time to react to each keystroke. Default: `25`. ```yaml momentic.config.yaml theme={null} emulator: keyPressDelayMs: 60 ``` # momentic.config.yaml Source: https://momentic.ai/docs/configuration/momentic-config Index for `momentic.config.yaml`. Project-level options live here; large blocks like `browser`, `ai`, and `emulator` have their own reference pages. `momentic.config.yaml` lives in your project root and defines a **project**. One file covers both web and mobile. Paths and globs are relative to the file's location, or absolute. ## Configuration sources Momentic resolves configuration from these sources, highest precedence first: 1. **CLI flags** (e.g. `--local-avd-id`, `--local-apk-path`) 2. **Environment variables**, including `MOMENTIC_API_KEY` and any variable interpolated into `momentic.config.yaml` 3. **`momentic.config.yaml`** (this file). Includes the [`ai.classification`](/docs/configuration/ai#ai-classification) toggle for failure classification. 4. **Organization AI settings**. Failure categories and auto-heal behavior are configured in the [Momentic dashboard](https://app.momentic.ai/settings/triage) and applied when the CLI is authenticated. These remain dashboard-managed and cannot be set in this file. 5. **CLI defaults** ## Example ```yaml momentic.config.yaml theme={null} # Project identity and test discovery name: my-project include: - "**/*.test.yaml" - "**/*.module.yaml" exclude: - "out/**/*" # Run behavior retries: 2 parallel: 4 recordVideo: on-fail # One entry per environment, each with its own baseUrl and variables environments: - name: dev baseUrl: https://dev.example.com envVariables: USERNAME: devUser PASSWORD: ${DEV_PASSWORD} - name: production baseUrl: https://www.example.com envVariables: USERNAME: prodUser PASSWORD: ${PROD_PASSWORD} # Browser defaults applied to every browser-based test browser: smartWaitingTimeoutMs: 5000 pageLoadTimeoutMs: 8000 # AI agent versions and per-agent behavior ai: classification: true useMemory: true failureRecovery: true agentConfig: locator: v4 assertion: v4 visual-assertion: v4 text-extraction: v3 # Mobile emulator settings (remote-hosted) emulator: region: us-west1 ``` ## Reference Project name, file globs, retries, parallelism, video recording, Git branch settings. `environments[]`: name, base URL, env variables, per-env proxy. How Momentic resolves variables at runtime and the reserved variables available in every test. `browser.*`: defaults for browser type, timezone, timeouts, locator behavior, AI context filtering. `ai.*`: per-agent versions, memory, and failure recovery. `emulator.*`: region and runtime options for remote-hosted mobile emulators. `advanced.*`: Faker seed, per-environment cache isolation. Group multiple projects under one repo. Glob syntax for `include` / `exclude`. ## Global options Project name, displayed in reports and the dashboard. ```yaml momentic.config.yaml theme={null} name: my-project-name ``` Globs for test and module files to include. Matching files are picked up automatically when starting the Momentic Local App or running tests. ```yaml momentic.config.yaml theme={null} include: - "**/*.test.yaml" - "**/*.module.yaml" ``` Globs for files to exclude. `node_modules`, `.git`, and `.venv` are always excluded. ```yaml momentic.config.yaml theme={null} exclude: - "out/**/*" ``` Default number of retries per test on failure. Overrides per-test `retries`. ```yaml momentic.config.yaml theme={null} retries: 2 ``` Default for `momentic run`: `1`. Tests to run in parallel. For `momentic run`, `"auto"` sizes workers from the host's CPU cores. When the project's `browser.remoteBrowser` flag is enabled, workers scale to `cores * 4 - 2` (remote browsers are IO-bound); otherwise workers cap at `cores` (local browsers are CPU-bound). For mobile projects (`momentic-mobile`), pass `AUTO` (CLI flag only, not in `momentic.config.yaml`) to run as many tests in parallel as the current shard contains. Combine with `--shard-index` / `--shard-count` so each shard saturates its capacity. In `momentic.config.yaml`, only the lowercase form `auto` is valid. ```yaml momentic.config.yaml theme={null} parallel: 4 ``` Record video for test runs. Default: `on-fail`. * `true`: record every run. * `false`: never record. * `on-fail`: record every run but keep video only for failures. Browser recording requires `ffmpeg`, which is installed automatically by `momentic install-browsers`; mobile recording does not. ```yaml momentic.config.yaml theme={null} recordVideo: on-fail ``` Directory Momentic writes golden files to for **Visual diff**. ```yaml momentic.config.yaml theme={null} goldenFileDir: golden/visual-diff ``` Default directory for reporter output. ```yaml momentic.config.yaml theme={null} reporterDir: reports ``` Configuration for network reporters. Currently supports `newrelic`; see [Push run results to New Relic](/docs/guides/reporting/new-relic). ```yaml momentic.config.yaml theme={null} reporting: newrelic: region: US accountId: "1234567" licenseKey: ${NEW_RELIC_LICENSE_KEY} attributes: service: checkout team: payments ``` Main branch of the repo. When running tests on a new branch, Momentic seeds cache entries from the nearest commit on this branch. In non-CI environments, the main branch is also excluded from cache saving. See [cache saving eligibility](/docs/reliability/step-cache#cache-saving-eligibility). ```yaml momentic.config.yaml theme={null} gitMainBranch: main ``` Branches considered ineligible for cache saving in non-CI environments. Prevents accidental cache overwriting on shared branches. See [cache saving eligibility](/docs/reliability/step-cache#cache-saving-eligibility). ```yaml momentic.config.yaml theme={null} gitProtectedBranches: - staging ``` Relative path from the project root to use as the Repository root in the Momentic Local App. Display-only. Does not affect test execution or file resolution. ```yaml momentic.config.yaml theme={null} displayRoot: src/tests ``` # Test file globs Source: https://momentic.ai/docs/configuration/test-globs Glob syntax used by `include` and `exclude` in momentic.config.yaml. Globs are used throughout `momentic.config.yaml` (e.g. `include`, `exclude`) to choose which `.test.yaml` and `.module.yaml` files Momentic discovers. ## Patterns | Pattern | Matches | | ----------- | ---------------------------------------------------- | | `*` | All files in the current directory | | `**` | All files and subdirectories recursively | | `some-dir/` | The `some-dir` directory and its contents | | `some-dir` | A file named `some-dir`, or the `some-dir` directory | | `some-dir*` | Files and directories starting with `some-dir` | | `*.js` | All `.js` files in the current directory | | `!pattern` | Negates a glob (automatically appends `/**`) | ## Examples | Pattern | Matches | | ------------------ | ----------------------------------------------- | | `dist/**` | Everything under `dist/` | | `dist/` | `dist/` and its contents | | `dist` | A file named `dist`, or the `dist` directory | | `dist/some-dir/**` | Everything under `dist/some-dir/` | | `!dist` | Ignores `dist/` and its contents | | `dist*` | Files and directories starting with `dist` | | `dist/*.js` | `.js` files directly in `dist/` | | `!dist/*.js` | Ignores `.js` files directly in `dist/` | | `dist/**/*.js` | All `.js` files under `dist/` recursively | | `../scripts/**` | Everything under a sibling `scripts/` directory | # Workspaces Source: https://momentic.ai/docs/configuration/workspace Group multiple Momentic projects under one repository with a workspace file. A **workspace** groups multiple Momentic projects under a single repository. Use one when different teams maintain separate test suites but share a repo. Most organizations don't need a workspace; a single [`momentic.config.yaml`](/docs/configuration/momentic-config) at the repo root is enough. ## Creating a workspace Add a `momentic.workspace.yaml` at the root of your repository: ```yaml momentic.workspace.yaml theme={null} projects: - project-a - folder/* - apps/**/* ``` Each entry is a glob pointing to a directory that contains its own `momentic.config.yaml`. # Agentic testing Source: https://momentic.ai/docs/core-concepts/agentic-testing Use **AI action** steps to test dynamic scenarios and high-level goals without hard-coding every interaction. Most Momentic tests are **step-based**: each step names a specific action (click the Sign in button, assert the dashboard loads). Step-based tests are fast, deterministic, and cacheable. **Agentic testing** is the opposite end of the spectrum. You give Momentic a goal, and an AI agent determines the steps at runtime. Agentic steps are slower than step-based ones, but they fit situations where the exact flow isn't predictable ahead of time. ## When to reach for agentic testing * **Dynamic flows** where the UI changes based on feature flags, A/B tests, or user state * **High-level acceptance checks**, "confirm a new user can sign up and reach the welcome screen", without prescribing each click * **Exploratory coverage**: let the agent probe areas of your app that aren't worth a dedicated deterministic test * **End-to-end smoke tests** after deploys, "complete an order", with the agent handling whatever the current UX looks like Prefer step-based tests for core critical paths where you want speed, repeatability, and tight assertions. ## AI action **AI action** is the step behind agentic testing. It accepts a natural language goal and lets the agent drive the browser or app until the goal is complete. ```yaml signup.test.yaml theme={null} fileType: momentic/test/v2 id: gentle-river-lantern steps: - act: goal: Complete the new-user signup flow using a fresh email. postcondition: The welcome screen is visible. ``` The agent picks elements, types values, scrolls, waits for network, and handles modal dialogs on its own. When the goal is reached, the step passes; when the agent gives up or times out, the step fails with a trace of what it tried. ## Version: V2 vs V3 AI action ships in two versions, selectable per step from the **Version** dropdown in the editor. * **V3 (beta, recommended)**: a planner-style agent that drafts the full flow up front, caches the resolved steps after the first successful run, and self-heals when a cached step misses. Reruns are faster and more deterministic than V2. V3 also supports optional **Pre-condition** and **Post-condition** checks that run as protected guards around the generated flow and cannot be modified by the agent. * **V2**: the previous generation. A fully dynamic agent that decides each step at runtime and does not cache the generated trajectory. Kept available as a fallback for flows where V3 does not yet work well. V3 is in beta for web and mobile. New AI action steps default to V3; you can switch any individual step to V2 at any time. ## Pairing with assertions Wrap agentic steps with explicit assertions (**AI check**, **Page check**, **Element check**) so you verify the outcome, not only that the agent "finished". Agentic steps are flexible but non-deterministic; assertions check the result. ## Reliability tips * Keep goals short and specific. "Sign up a new user with a fresh email" is better than "Test the onboarding flow thoroughly." * Provide context the agent can't infer. If there's an invite code, pass it in via [variables](/docs/core-concepts/variables). * Add a fallback assertion right after the agentic step so failures surface with a meaningful message. * Combine this with [Auto-heal](/docs/reliability/auto-maintenance#locator-auto-healing) and [Step cache](/docs/reliability/step-cache). The agent's successful traces are cached and replayed deterministically on subsequent runs. ## Related * [AI action guide](/docs/guides/ai-actions/guide) * [Finding elements](/docs/core-concepts/finding-elements) * [Writing assertions](/docs/core-concepts/writing-assertions) * [Auto-heal](/docs/reliability/auto-maintenance#locator-auto-healing) * [Step cache](/docs/reliability/step-cache) # Authentication Source: https://momentic.ai/docs/core-concepts/authentication Strategies for authenticating into your app from a Momentic test without breaking on SSO or 2FA. Avoid using Momentic tests to log in using SSO. Providers like Google, Facebook, and GitHub often have security measures that block automated browsers. This page covers how to obtain credentials for specific login mechanisms. For **where to put login steps** (inline, in the `before` section, or a cached auth module) and which approach to choose, see [Authentication strategies](/docs/guides/auth/overview). ## Username and password The simplest case: add a **Type** step for the username, a **Type** step for the password, and a **Click** on the submit button. Pull the values from [environment variables](/docs/core-concepts/variables) (`{{ env.TEST_USERNAME }}`) rather than hard-coding credentials in the test file. ## Email magic link **Prerequisites**: An email address must be provisioned by Momentic. Add a **JavaScript** step with the following content: ```javascript theme={null} // fetch the latest email from the inbox const msg = await email.fetchLatest({ inbox: "", }); // extract the magic link using regex const link = msg.text.match(/https?:\/\/[^\s]+/)[0]; return link; ``` Use the **Save to environment variable** option to save the link to an environment variable, e.g., `MAGIC_LINK`. Then, use the **Navigate** step with content `{{ env.MAGIC_LINK }}` to navigate to the magic link and complete the login process. ## Email One-Time Password (OTP) **Prerequisites**: An email address must be provisioned by Momentic. Add a **JavaScript** step with the following content: ```javascript theme={null} // fetch the latest email from the inbox const msg = await email.fetchLatest({ inbox: "", }); // extract the code using regex const code = msg.text.match(/\b\d{6}\b/); return code; ``` Use the **Save to environment variable** option to save the code to an environment variable, e.g., `OTP_CODE`. Then, use the **Type** step with content `{{ env.OTP_CODE }}` to input the OTP code and complete the login process. ## SMS One-Time Password (OTP) **Prerequisites**: A SMS number must be provisioned by Momentic. Add a **JavaScript** step with the following content: ```javascript theme={null} // fetch the latest message from the inbox const msg = await sms.fetchLatest({ to: "", }); // extract the code using regex const code = msg.body.match(/\b\d{6}\b/); return code; ``` Use the **Save to environment variable** option to save the code to an environment variable, e.g., `OTP_CODE`. Then, use the **Type** step with content `{{ env.OTP_CODE }}` to input the OTP code and complete the login process. ## Vercel Deployment Protection Follow Vercel's [protection bypass for automation](https://vercel.com/docs/deployment-protection/methods-to-bypass-deployment-protection/protection-bypass-automation) guide. Configure the bypass header in your test options. ## IP whitelist For teams that use the Momentic dashboard, whitelist Momentic's fixed egress IP: `34.106.239.183`. For Azure-hosted customers, whitelist both `52.177.232.247` and `20.14.51.42`. # IDE lint Source: https://momentic.ai/docs/core-concepts/editor-validation Add Momentic's JSON Schemas to your IDE for autocomplete and inline validation while you hand-edit test and module YAML. Momentic publishes static JSON Schemas for simplified format tests and modules, as well as the project config file (`momentic.config.yaml`). Add them to your IDE to get autocomplete and inline validation as you write, instead of at run time. The schemas work for web, mobile, and mixed repos. The onboarding wizard (`npx @momentic/wizard@latest`) detects your installed editors and writes the matching config automatically: `.vscode/settings.json` for VS Code, Cursor, and Windsurf, or `.zed/settings.json` for Zed. Commit the file to share validation with your team. Add this to `.vscode/settings.json`: ```json theme={null} { "yaml.schemas": { "https://static.momentic.ai/momentic-test-v2.schema.json": "*.test.yaml", "https://static.momentic.ai/momentic-module-v2.schema.json": "*.module.yaml", "https://static.momentic.ai/momentic-config.schema.json": "momentic.config.yaml" } } ``` Requires the [YAML extension](https://marketplace.visualstudio.com/items?itemName=redhat.vscode-yaml). Cursor uses VS Code workspace settings. Commit the same `.vscode/settings.json` snippet from the VS Code tab so everyone opening the repo in Cursor gets the simplified format schemas automatically. Windsurf also reads VS Code-style workspace settings. Commit the same `.vscode/settings.json` snippet from the VS Code tab for shared team validation. Add this to your Zed settings: ```json theme={null} { "lsp": { "yaml-language-server": { "settings": { "yaml": { "schemas": { "https://static.momentic.ai/momentic-test-v2.schema.json": [ "*.test.yaml" ], "https://static.momentic.ai/momentic-module-v2.schema.json": [ "*.module.yaml" ], "https://static.momentic.ai/momentic-config.schema.json": [ "momentic.config.yaml" ] } } } } } } ``` IDE schemas catch shape errors as you type. For a full validation pass (schema validity, local file references, and entity conflicts), run [`momentic lint`](/docs/cli-reference/momentic/commands/lint) before committing agent-authored changes. # File format Source: https://momentic.ai/docs/core-concepts/file-format Structure web and mobile test and module files, including setup, teardown, parameters, and stable identifiers. Momentic stores tests and modules as YAML files in your repository. This page covers the top-level file structure. See [Steps](/docs/core-concepts/steps) for the syntax inside `before`, `steps`, and `after`. Web (`momentic`) and mobile (`momentic-mobile`) are separate CLIs that share the same simplified format. Their file types and available top-level fields differ where the platforms require it. ## Test and module files A test has a `fileType`, a readable kebab-case `id`, and a list of `steps`. A module uses a module `fileType` and adds a human-readable `name`. Both use `id` as their stable identifier. A test has no `name` field. Use `id` for identity and `description` for human-readable text. A `name` key in a test file is ignored. A web test can set its starting `url`. ```yaml checkout.test.yaml theme={null} fileType: momentic/test/v2 id: silver-river-lantern url: https://shop.example.com steps: - click: Checkout - type: text: jeff@example.com into: Email input - assert: An order confirmation is visible ``` ```yaml log-in.module.yaml theme={null} fileType: momentic/module/v2 id: violet-cedar-bridge name: Log in parameters: - name: USERNAME default: string: test@example.com - name: PASSWORD steps: - type: text: "{{ env.USERNAME }}" into: Email input - type: text: "{{ env.PASSWORD }}" into: Password input - click: Log in ``` A mobile test adds a `platform` key (`ios` or `android`, lowercase on disk). ```yaml checkout.test.yaml theme={null} fileType: momentic/mobile-test/v2 id: amber-forest-window platform: ios steps: - openApp: com.example.shop - tap: the Checkout button - type: text: jeff@example.com into: the Email field - assert: An order confirmation is visible ``` ```yaml log-in.module.yaml theme={null} fileType: momentic/mobile-module/v2 id: calm-sparrow-garden name: Log in platform: android parameters: - name: USERNAME default: string: test@example.com - name: PASSWORD steps: - type: text: "{{ env.USERNAME }}" into: the Email field - type: text: "{{ env.PASSWORD }}" into: the Password field - tap: the Log in button ``` Mobile tests also accept top-level settings such as `disabled`, `labels`, `retries`, `defaultChannel`, `defaultTag`, `defaultEnv`, `emulator`, `ai`, and local artifact paths. Each module parameter is `{ name, default?, enum? }`. `default` is a value object (`{ string }` or `{ javascript }`) used when an invocation does not supply that parameter. See [Modules](/docs/core-concepts/modules) for parameter defaults, inputs, and caching. ## IDs Every test and module ID must be unique across your Momentic organization. When Momentic creates a file, including through MCP, it assigns a readable slug such as `silver-river-lantern`. Generated IDs do not have a fixed number of words. Keep the ID if you rename or move the file. When authoring YAML by hand, choose any lowercase kebab-case slug up to 36 characters, such as `checkout` or `guest-checkout`. Keep it stable after the file is created. UUID IDs from older files remain valid. ## Before and after sections Tests can declare optional `before` and `after` arrays alongside `steps`. All three arrays use the same [step syntax](/docs/core-concepts/steps). In the editor, `before` is **Setup** and `after` is **Teardown**. ```yaml checkout.test.yaml theme={null} fileType: momentic/test/v2 id: quiet-copper-orbit url: https://shop.example.com before: - module: ../modules/log-in.module.yaml # authenticate before the main steps steps: - Add a "Gravity Blanket" to the cart and check out - assert: The order confirmation page is shown after: - Empty the cart # cleanup that runs even if the main steps fail ``` * `before` runs first, followed by `steps`, then `after`. * If a `before` step fails, the main steps are skipped and the test is marked as a setup failure. * `after` runs after the main steps whether they pass or fail. Use it for teardown such as resetting state or deleting test data. Use `before` for prerequisites the main steps assume, most commonly [authentication](/docs/guides/auth/overview). `before` and `after` run only when the whole test runs. Running a single step, or running from or until a step in the main body, skips both sections. Run the whole test to include setup and teardown. ## Step syntax For commands, targets, AI actions, assertions, control flow, module calls, and shared step options, see [Steps](/docs/core-concepts/steps). ## Related * [Steps](/docs/core-concepts/steps) * [Modules](/docs/core-concepts/modules) * [Variables](/docs/core-concepts/variables) * [Migrate to the simplified format](/docs/get-started/migrate-to-simplified-format) # Finding elements Source: https://momentic.ai/docs/core-concepts/finding-elements Write durable natural-language descriptions for element targets. Momentic locates elements from natural-language descriptions instead of CSS or XPath selectors. Descriptions capture what an element does, so if it moves or its markup changes, Momentic can use AI to find it again and automatically update its [cached locator](/docs/reliability/step-cache). ## Write durable descriptions A good target is the shortest description that uniquely identifies the element for a user. Start with its purpose, accessible name, or role, then add stable context only when you need to distinguish it from another match. | Target | Why it works | | --------------------------------------------------- | --------------------------------------------------------- | | `the Save button in the header` | Combines a clear purpose with a stable region. | | `the Confirm button in the account deletion dialog` | Scopes a common label to the relevant dialog. | | `the cell in the third row under the Color column` | Identifies a cell by its relationship to stable elements. | Avoid descriptions that depend on implementation details, incidental styling, or earlier steps: | Avoid | Problem | | ------------------------------------------ | ------------------------------------------------------------- | | `.modal-close` or `div:nth-child(2)` | CSS and XPath-style selectors break when markup changes. | | `data-testid=save` | Describes an HTML attribute instead of the element's purpose. | | `Confirm` | Ambiguous when the page contains more than one match. | | `the previously clicked cell` | Depends on test history that the locator does not receive. | | `the off-gray Submit button in the corner` | Over-specifies details when `the Submit button` is unique. | Use durable, user-facing details. Add color, exact position, or element order only when that detail is required to find the element or is part of the behavior you are testing. More detail can make a target less reliable when the extra detail changes. Accessible roles and names are usually the strongest signals. Prefer targets such as `the Submit button`, `the People tab`, or `the Month combobox` when those descriptions are unique. In the test editor, open the **Accessibility** tab in the bottom panel to inspect the tree Momentic uses. Search for the element and check that its role and name describe what a user can do with it. If an interactive element is missing or has no meaningful name, improve the product's accessibility metadata. Use `aria-labelledby` when a visible label already exists, or `aria-label` when it does not. Keep the label truthful to the control's user-facing purpose. For an automation-only identifier, use a stable `data-testid` instead of adding misleading ARIA metadata. ## Require exact text only when it matters Visible text is useful when it is stable: `the Welcome heading` or `the text area containing Lorem Ipsum`. Do not quote text by default. Single quotes make the quoted text a strict requirement, so use them only when an exact value is part of the behavior under test. This is useful for an ID, code, amount, or value created by the test: ```text theme={null} the page named '{{ env.PAGE_NAME }}' ``` Avoid strict matching for copy that may be reworded, localized, truncated, or only partially visible. For example, `the control showing that the job is still running` is more durable than `the 'In progress' badge` when either "In progress" or "Processing" is valid. ## Add visual and positional cues when needed Momentic can use colors, shapes, sizes, icons, and positions from the screenshot. These cues help when an element does not have a useful accessible name: * `the thumbs-up icon beside the response` * `the hamburger menu beside the logo` * `the button below the Introduction heading` * `the Submit button inside the user dialog` * `the closest Delete button to the account named Acme` Visual cues are limited to the current viewport. Avoid relying on them for very small targets or rows of similar icons. Prefer relative context such as a dialog, heading, row, or field over absolute positions such as `the button in the bottom right corner`. Use ordinal descriptions such as `the second result` only when order is part of the test. If the same description should intentionally resolve to a different element between runs, see [Caching](#caching). ## Auto-waiting Interactive preset steps such as **Click** and **Type** automatically wait for their target. Momentic lets the page or screen settle and retries cached targets until the smart-waiting timeout elapses, so do not add an element-exists check only to wait before an interaction. The default smart-waiting timeout is 5 seconds. Configure it separately for [web tests](/docs/configuration/browser#browser-smartwaitingtimeoutms) and [mobile tests](/docs/configuration/mobile#emulator-smartwaitingtimeoutms). When an asynchronous transition can outlast that timeout, wait on a durable page condition immediately before the interaction. Avoid fixed-duration sleeps and transient targets such as tooltips, toasts, loading spinners, or other elements that may disappear before Momentic resolves them. ## Caching On the first successful run, Momentic uses AI to resolve the description and caches the result. The cache stores multiple signals about the target, including its text, accessibility attributes, structure, position, and appearance. On later runs, Momentic validates those signals against the live page and performs the action without another AI call when they still match. If the cached target no longer matches because the element moved or its markup changed, [locator auto-healing](/docs/reliability/auto-maintenance#locator-auto-healing) uses the natural-language description to find the intended element with AI and updates the cache. This is why descriptions should capture the element's durable purpose instead of its current implementation. Interpolated `{{ }}` values are part of the cache identity. A description using `{{ env.USERNAME }}` can reuse its cache while `USERNAME` stays the same. A description using a value that changes every run, such as `{{ Date.now() }}`, gets a new cache identity every time, so Momentic resolves it again with AI. See [Step caching](/docs/reliability/step-cache) for cache eligibility, invalidation, storage, and isolation rules. Keep caching enabled unless the same description should intentionally identify a different element on each run, such as today's calendar cell, the last item in a rotating list, or an ordinal result whose contents change. Disable caching only on that dynamic step. Disabling it does not fix a vague description or a rendering race. ## Advanced ### Preserve useful HTML context Momentic prunes noisy HTML before sending page context to its AI. Common testing attributes such as `aria-label` and `data-test-id` are always preserved. If a useful custom attribute is missing, add it to [`browser.importantAttributes`](/docs/configuration/browser#browser-importantattributes) so Momentic keeps it. You can also preserve elements by class with [`browser.importantClasses`](/docs/configuration/browser#browser-importantclasses). If a framework-generated or frequently changing attribute causes cache misses, exclude it with [`browser.bannedAttributes`](/docs/configuration/browser#browser-bannedattributes). Do not ban an attribute that genuinely identifies the element. ### Canvas interaction AI action can handle canvas-based interfaces even when their controls do not exist as distinct DOM elements. It uses visual reasoning and can interact at arbitrary x/y coordinates, which makes it well suited to drawing tools, visual editors, games, maps, and other canvas-heavy UI. Preset steps such as **Click** and **Type** still need a distinct element in the DOM or mobile accessibility tree. Use an [AI action](/docs/core-concepts/agentic-testing) for a canvas, video, or other custom-rendered surface that does not expose one. ```yaml theme={null} - act: goal: Drag the blue node on the canvas into the Approved column ``` Prefer preset steps for known, targetable UI because they are faster and more deterministic. ### Choose the right check Use an element check for one stable, unambiguous element property, such as exact text, an attribute, or enabled state. Use an **AI check** when element existence must be a separate readiness gate, and for visual appearance, page position, relationships between elements, or other semantic outcomes. See [Writing assertions](/docs/core-concepts/writing-assertions) for examples. # Modules Source: https://momentic.ai/docs/core-concepts/modules Extract reusable sequences of steps, parameterize them, and share across tests. A module is a named sequence of steps you can call from any test. Use modules to share login flows, setup fixtures, or repeated user journeys. Modules can't call other modules. Editing a module updates every test that uses it. ## Example A module is a YAML file that ends in `.module.yaml`. Call it from any test with a **Module** step. ```yaml log-in.module.yaml theme={null} fileType: momentic/module/v2 id: misty-oak-bridge name: Log in parameters: - name: USERNAME default: string: test@example.com - name: PASSWORD steps: - type: text: "{{ env.USERNAME }}" into: Username input - type: text: "{{ env.PASSWORD }}" into: Password input - click: Log in ``` ```yaml checkout.test.yaml theme={null} fileType: momentic/test/v2 id: copper-meadow-kite url: https://saucedemo.com steps: - module: path: ../modules/log-in.module.yaml inputs: USERNAME: string: test@example.com PASSWORD: env.TEST_PASSWORD - act: Add a "Gravity Blanket" to the cart and check out - assert: The order confirmation page is shown ``` ## Parameters Parameters let a single module handle different inputs. Declare them under `parameters` on the module, then reference them inside steps via `{{ env.PARAM_NAME }}` (or `env.PARAM_NAME` in **JavaScript** steps). ```yaml log-in.module.yaml theme={null} fileType: momentic/module/v2 id: misty-oak-bridge name: Log in parameters: - name: USERNAME default: string: test@example.com # used when an invocation omits this input - name: ROLE enum: [admin, member] # restrict the input to a fixed set of values - name: PASSWORD # no default: every invocation must supply it steps: - type: text: "{{ env.USERNAME }}" into: Email input ``` ### Defaults vs instance inputs Each parameter can have a **default value** on the module and an **instance input** on a specific **Module** step. Instance inputs take precedence. Each input value is one of: * A shorthand string: evaluated as a **JavaScript expression** (e.g. `env.PARAM`, `someFn() + 1`). * `{ string: ... }`: a literal string. Use this for fixed text values. * `{ javascript: ... }`: the script's return value is bound to the parameter. Equivalent to the shorthand but supports multi-line scripts. ```yaml checkout.test.yaml theme={null} steps: - module: path: ../modules/log-in.module.yaml inputs: USERNAME: string: alice@example.com # literal, overrides default PASSWORD: env.TEST_PASSWORD # JS shorthand reads from the env map ``` ## Control flow ### Default retries Set **Default retries** under the module's **Control flow** tab to retry every invocation of the module a fixed number of times on failure. Invocations that set their own `retries` value override the module default. Use this for flaky setup modules (e.g. a login module that sometimes fails on slow environments) instead of setting `retries` on every invocation. ## Caching Modules are uncached by default and always execute. Enable caching to skip a module when its cache key and inputs are unchanged. The module's return value (the return value of its last step) is also cached. Configure caching with module-level fields: ```yaml log-in.module.yaml theme={null} fileType: momentic/module/v2 id: misty-oak-bridge name: Log in defaultCacheAllInvocations: true # cache every invocation of this module defaultCacheKey: admin-user # invocations sharing a key reuse the same cache entry defaultCacheTtl: 3600000 # expire the cache entry after 1 hour (milliseconds) steps: - # ... ``` Override the key or expiry on a single **Module** step with `cacheConfig`: ```yaml checkout.test.yaml theme={null} steps: - module: path: ../modules/log-in.module.yaml cacheConfig: cacheKey: member-user cacheExpiryMs: 600000 ``` ### Authentication modules Set `autoAuth: true` (the editor's **Treat as auth module**) to save and restore browser auth state between runs. Momentic persists: * [Cookies](https://playwright.dev/docs/api/class-browsercontext#browser-context-cookies) * `localStorage` * [IndexedDB](https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API) ```yaml log-in.module.yaml theme={null} fileType: momentic/module/v2 id: misty-oak-bridge name: Log in autoAuth: true defaultCacheAllInvocations: true defaultCacheKey: admin-user defaultCacheTtl: 3600000 steps: - # ... login steps, ending with a check of the authenticated state ``` Set the cache expiry shorter than your session's expiry. Add a final step that verifies the authenticated state so the cache only saves when login succeeded. See [Authentication strategies](/docs/guides/auth/overview) and [Cache authenticated sessions](/docs/guides/auth/cached-session) for the full workflow. # Steps Source: https://momentic.ai/docs/core-concepts/steps Combine preset steps, AI actions, control flow, module calls, and code in web and mobile tests. A step is one unit of work in a test or module. Steps run in order inside the `before`, `steps`, and `after` arrays. They can interact with your product, verify or extract state, choose or repeat a path, call a reusable module, or run custom code. Momentic supports exact, reviewable sequences and goal-driven execution in the same test: | Building block | What it does | Examples | | -------------------- | ------------------------------------------------------------------------------------------------- | ----------------------------------------- | | **Preset step** | Executes one configured operation. It can use AI or be fully deterministic. | Click, Type, Wait, Assert, and AI extract | | **AI action** | Uses a runtime agent to choose and execute the sequence needed to reach a goal. | Complete checkout or configure an account | | **Control flow** | Runs nested steps conditionally or repeatedly. | `if` and `while` | | **Module call** | Runs a reusable sequence of preset steps and AI actions. | Log in or seed a cart | | **Code integration** | Extends preset steps with JavaScript or Appium when no built-in operation expresses the behavior. | Generate data or call a native API | See [File format](/docs/core-concepts/file-format) for the top-level YAML structure. ## Preset steps A preset step performs one operation at a known point in the test. Use preset steps when the interaction or check should remain explicit. A preset step can still use AI. For example, Momentic can resolve a natural-language target, evaluate an assertion, or extract structured data with AI. The configured operation and its position in the sequence remain fixed. Other preset steps, such as navigating to a URL or waiting for a duration, are fully deterministic. Preset steps cover: * Interactions such as clicking, typing, tapping, swiping, and scrolling. * Browser navigation, app lifecycle, device controls, and waits. * Assertions, element checks, visual comparisons, and data extraction. * Network requests, route mocking, browser state, and files. * JavaScript and Appium integration for custom behavior. ```yaml theme={null} steps: - navigate: https://shop.example.com - click: Checkout - type: text: jeff@example.com into: Email input - assert: An order confirmation is visible ``` See the [Web steps reference](/docs/reference/commands/index) for every available preset step. ```yaml theme={null} steps: - openApp: com.example.shop - tap: the Checkout button - type: text: jeff@example.com into: the Email field - assert: An order confirmation is visible ``` See the [Mobile steps reference](/docs/reference/mobile-commands/index) for every available preset step. ### Targets Interactive preset steps identify the element they act on. Natural-language targets keep a step readable and let Momentic resolve the element from its text, appearance, accessibility attributes, and surrounding structure. Successful resolutions are cached for later runs. The target field depends on the operation. Common keys include `on`, `into`, `from`, and `that`; each preset step's reference lists the fields it accepts. Web preset steps accept natural language, CSS or XPath selectors, and absolute coordinates. ```yaml theme={null} - click: Submit - click: css: "button[type='submit']" - click: coords: 120, 240 ``` Mobile preset steps accept natural language or a percent pair. For example, `"50%, 50%"` targets the center of the screen. They do not accept CSS selectors or absolute pixels. ```yaml theme={null} - tap: the Add to cart button - tap: "50%, 50%" - scrollTo: on: the "Delete account" row in: the settings list ``` ### Shorthand and detailed syntax Use the shorthand form when a preset step only needs its primary value. Use the detailed form when it needs more options: ```yaml theme={null} - click: Submit - click: on: Submit timeout: 5000 retries: 1 ``` Preset steps without a value can use a bare alias, such as `- refresh` on web or `- killApp` on mobile. In the detailed form, place every option under the preset step key. The shorthand form cannot have additional options. ### Assertions and extraction Use `assert` for a condition that requires AI evaluation, `extract` to read structured data with AI, and `checkElement<...>` for a specific element state or value. ```yaml theme={null} - assert: The dashboard chart is visible and not cut off - checkElementVisible: The Download report button - extract: goal: The discounted subtotal in the order summary saveAs: SUBTOTAL schema: type: object properties: amount: type: number required: [amount] ``` See [Writing assertions](/docs/core-concepts/writing-assertions) for choosing the right assertion type and defining durable outcomes. ## AI actions An AI action takes a natural-language goal instead of a fixed interaction. At runtime, the agent observes the current page or screen and executes the steps needed to reach that goal. Write the goal directly for the common case: ```yaml theme={null} steps: - Complete the new-user signup flow using a fresh email ``` Use `act:` when the action needs a precondition, postcondition, cache control, or other options: ```yaml theme={null} - act: goal: Complete the new-user signup flow using a fresh email postcondition: The welcome screen is visible ``` See [Goal-based testing](/docs/best-practices/goal-based-testing) for writing bounded goals, postconditions, and cache guidance. ## Control flow Control-flow steps decide which nested steps run. Use `if` when a path depends on current product state and `while` when the same work must repeat until a condition changes or a limit is reached. ### Conditionals A conditional contains one condition and a `then` list. The condition can be an inline `assert`, an element or screen check, or a `javascript` expression. ```yaml theme={null} - if: checkElementVisible: the cookie banner then: - click: Accept all ``` There is no `else` branch. Use a separate conditional when another path is required. ### While loops A while loop contains a `do` list and at least one loop control: a condition or `maxIterations`. The condition is evaluated before each iteration. ```yaml theme={null} - while: checkElementVisible: the Load more button maxIterations: 20 do: - click: Load more ``` Nested steps share the test's `env`, so a value written with `saveAs` is available to the next condition check. Use only `maxIterations` when the loop should repeat a fixed number of times. ## Module calls A module call inserts a reusable sequence of preset steps and AI actions into a test. Reference the module relative to the file containing the call: ```yaml theme={null} steps: - module: path: ../modules/log-in.module.yaml inputs: USERNAME: env.QA_EMAIL PASSWORD: javascript: "return env.QA_PASSWORD" ``` When a module takes no inputs, write its path directly: ```yaml theme={null} - module: ../modules/log-in.module.yaml ``` Module input strings are JavaScript expressions, not mustache templates. Use `{ string: ... }` for a literal value and `{ javascript: ... }` for a script. See [Modules](/docs/core-concepts/modules) for parameters, defaults, and caching. ## Code integration JavaScript and Appium are preset steps that extend Momentic when a built-in operation does not express the work. Use them for test data, APIs, databases, application state, or platform APIs. Keep user interactions in the built-in preset steps so they retain Momentic's targeting, waiting, caching, and traces. Web JavaScript runs in a sandboxed Node environment by default. Set `environment: browser` when the code needs `window`, `document`, or page state. ```yaml theme={null} - javascript: code: return faker.person.fullName() saveAs: CUSTOMER_NAME ``` Use JavaScript for data and service integration. Use Appium when custom code must execute against the device. ```yaml theme={null} - appium: script: "mobile: shell" args: '{ "command": "echo", "args": ["ready"] }' ``` See [JavaScript](/docs/integrations/javascript) for runtimes, utilities, and variables. ## Shared syntax Detailed preset steps and AI actions keep their options under the step key. Common options include `retries`, `skipped`, `comment`, and `saveAs`. `saveAs` writes a returned value to `env.` for later steps. ### Variables and templating String fields can include `{{ expression }}` templates evaluated against the test's `env` map. JavaScript source reads values directly as `env.NAME` without mustache syntax. See [Variables](/docs/core-concepts/variables) for sources, scope, and module parameters. ### File references Relative paths resolve from the YAML file containing the step. A path inside a module is relative to that module, not the test that calls it or the project root. ```yaml theme={null} steps: - javascript: ./scripts/setup.js - authLoad: ./auth-state.json ``` ### Durations Durations in the simplified YAML format use milliseconds: ```yaml theme={null} - assert: that: The chart is visible timeout: 10000 # 10 seconds ``` ## Authoring references Use the generated [V2 format reference](https://static.momentic.ai/v2-format-reference.md) when you or a coding agent need exact YAML shapes, compatibility versions, or less common fields. When authoring through the [MCP server](/docs/coding-agents/mcp-server), read the platform-specific **Step Authoring Guide** returned by session start. It covers the CLI-style step arguments accepted by MCP tools, which differ from the on-disk YAML shown here. ## Related * [File format](/docs/core-concepts/file-format) * [Web steps reference](/docs/reference/commands/index) * [Mobile steps reference](/docs/reference/mobile-commands/index) * [Goal-based testing](/docs/best-practices/goal-based-testing) * [Modules](/docs/core-concepts/modules) # Variables Source: https://momentic.ai/docs/core-concepts/variables Store and reuse data across steps using the global `env` object and templating syntax. All variables live on a global `env` object. Access them anywhere a field accepts a string using `{{ env.NAME }}`, or directly as `env.NAME` inside **JavaScript** steps. See [Environment variables](/docs/configuration/environment-variables) for the full list of reserved variables and how Momentic loads them at runtime. ## Example Extract a value, then use it in a later step: ```yaml extract-order-id.test.yaml theme={null} fileType: momentic/test/v2 id: velvet-copper-orbit steps: - act: Click "Place order" - extract: goal: The order id shown in the confirmation banner saveAs: ORDER_ID - assert: "A confirmation email mentioning order {{ env.ORDER_ID }} was sent" ``` ## Setting variables ### From JavaScript ```javascript theme={null} setVariable("USERNAME", "testuser"); setVariable("PASSWORD", Math.random().toString(36).substring(2, 15)); ``` ### From any step with a return value Any step with a return value (e.g. **AI extract**, **JavaScript**) can write that value to the environment with `saveAs` (the editor's **Save to environment variable** option). Provide a key; the step's return value is written to `env` after execution. ```yaml theme={null} - extract: goal: The discounted subtotal in the order summary saveAs: SUBTOTAL - javascript: code: return faker.string.uuid() saveAs: SESSION_ID ``` ## Scope All variables are test-scoped. Set a variable in one step; any subsequent step in the same test can read it. ### Module parameters Module parameters are variables scoped to the module's execution. A parameter named `API_KEY` is available as `{{ env.API_KEY }}` inside that module. # Writing assertions Source: https://momentic.ai/docs/core-concepts/writing-assertions How to write **AI check** assertions that pass reliably and fail for the right reasons. Momentic's AI evaluates assertions against the DOM, accessibility tree, and a screenshot of the viewport. The same rules from [Finding elements](/docs/core-concepts/finding-elements) apply, plus a few specific to assertions. ## Best practices * **Keep assertions short and specific.** Aim for under 20 words; split compound assertions into multiple steps. * **Provide context.** Point at the relevant region of the page and define any non-standard terminology. * **Remove ambiguity.** The answer should be clearly true or false given the page state. When in doubt, use single quotes for exact text matches. Pair every meaningful or state-changing action with an explicit assertion. An action completing does not prove that the product reached the intended state. ```yaml theme={null} steps: - click: Submit order button - assert: The order table shows the new order ID ``` Avoid assertions on tooltips, toasts, loading spinners, and other UI that may disappear before a step evaluates it. Assert the durable side effect instead: * Instead of `A Saved toast is visible`, assert that the saved row has a green checkmark. * Instead of `A loading spinner is visible`, assert that the results table is populated. If a transient state is the behavior you need to verify, use a [run assertion](#run-assertions) for web tests. ## Good assertions | Category | Example | | ------------------------------- | ------------------------------------------------------------ | | Presence or absence of text | A congratulations message is shown in the modal | | Presence or absence of elements | The page shows 3 search results | | Logical statements | The publish date of this article is more than 30 days ago | | Page state | There is no error message present on the page | | Color | The buy button is blue | | Layout | The 'XL' button is the largest button in the submission form | | Images and video | There is a LinkedIn icon on the page | ## Bad assertions | Problem | Bad | Better | | -------------------- | ---------------------------------------------------------------------------------------- | ----------------------------------------------------- | | Malformed | Search results | There are search results displayed on the main body | | Ambiguous | The order of the results is correct | The search results are sorted by date | | Multiple focuses | The logo is blue, the page shows 4 results, and the last result is more than 30 days old | Split into 3 separate assertions | | Contains an action | Wait for the results to appear | Use a **Wait** step, then assert the results appeared | | Imperceivable detail | The color of line divider is #ff5733 | The color of the divider looks red | | Subjective | The page looks well designed | No text in the table overflows its cell | | Time-sensitive | The video plays a 10-second advertisement | Assert on DOM state instead | ## Pre-trained behavior ### Typos The agent tolerates minor typos. `john@@gmail.com` will match `john@gmail.com`. For exact matching, wrap the expected value in single quotes and instruct the agent explicitly: `the username is exactly 'john@@gmail.com'. do not allow any typos`. When generating test data programmatically, prefer long, distinct values to avoid accidental matches. ## Run assertions Run assertions are plain-English statements you expect to have been true *at some point* during the run, including transient UI like toasts, spinners, and pop-ups that appear and disappear too quickly for a step-based assertion to catch. They are evaluated after the run finishes by an AI agent that samples frames from the run's video recording, and any failed run assertion fails the run. Video recording is automatically enabled for tests that define them. Currently available for web tests. ```yaml theme={null} runAssertions: - after clicking Update record, "updating..." appears - a "successfully updated" toast appears before the page returns to Ready steps: - click: the Update record button ``` The same [best practices](#best-practices) apply, with one difference: run assertions may describe a *sequence* ("X appears, then Y") because the agent evaluates the whole timeline rather than a single moment. ### ffmpeg requirement Evaluating run assertions with the CLI requires [ffmpeg](https://ffmpeg.org) to sample video frames. If any test in a run defines run assertions, the CLI checks for ffmpeg before executing and exits with an error when it is missing. Install it with your package manager: * macOS: `brew install ffmpeg` * Debian/Ubuntu: `apt-get install ffmpeg` * Windows: `winget install ffmpeg` (or `choco install ffmpeg`) The CLI uses the first `ffmpeg` on `PATH`. To use a specific binary instead, set the `MOMENTIC_FFMPEG_PATH` environment variable to its full path. Cloud runs evaluate run assertions on Momentic's infrastructure and do not require a local ffmpeg. GitHub-hosted Actions runners (`ubuntu-latest`, `macos-latest`) already include ffmpeg; slim container images may not. # What is AI-native testing? Source: https://momentic.ai/docs/get-started/ai-native-testing Use AI across the testing lifecycle to build coverage faster, keep tests reliable, and turn run data into product intelligence. Most test automation uses AI for one isolated task, such as generating a test or healing a locator. AI-native testing uses agents throughout the development lifecycle: authoring coverage, choosing and executing tests, maintaining the suite, and learning from every run. Momentic connects those stages through tests that remain readable, reviewable YAML files in your repository. AI reduces the work at each stage without taking away control. Teams get faster development and more reliable coverage. Run data explains product risk alongside pass or fail status. ## Use AI throughout the lifecycle Coding agents use your code and a live product session to create or update coverage alongside application changes. Runtime agents find elements from their descriptions instead of brittle selectors, recover from transient conditions, and select the most relevant tests based on a code change. Agents classify failures, repair outdated tests, verify changes, and quarantine persistent flakes when needed. Memory, the knowledge base, and the app graph make future decisions more consistent while exposing journey coverage and product risk. ## Author with product context Install the [Momentic skill](https://github.com/momentic-ai/skills) so your coding agent knows how to add and edit tests. Connect the [MCP server](/docs/coding-agents/mcp-server) so the agent can combine repository context with a live browser or mobile session, execute steps, and inspect artifacts while it works. With the [`momentic-spec` skill](/docs/coding-agents/mcp-server#spec-driven-development), the agent captures the intended behavior of a change as tests before it writes the product code. This puts test development in the same loop as product development, so coverage changes with the product. Give coding agents direct access to the product, tests, and run artifacts. Capture the behavior of a change as tests before implementing it. ## Run intelligently Run tests locally, in coding-agent sandboxes, in CI, or on a schedule. Use the full suite for scheduled runs and bug bashes. For pull requests, AI test selection uses the code diff, local code index, and optionally the [app graph](/docs/ai/app-graph) to choose a representative set of web tests. This shortens feedback without manually maintained dependency rules. During execution, Momentic uses semantic element resolution and transient recovery to absorb routine UI variation. Deterministic replay and step caching keep successful paths fast, while AI handles tasks that require judgment. Run web or mobile tests by path, name, or label. Configure GitHub Actions, GitLab CI, CircleCI, Jenkins, and other runners. Use code and journey context to select the most relevant tests based on a code change. Upload runs or generate JUnit, Allure, and JSON reports. See [Performance](/docs/running-tests/performance) for latency benchmarks, parallelism, and sharding. ## Maintain automatically When a test fails, Momentic starts with the least invasive response and escalates only when needed. It can re-resolve a locator, recover from a transient condition, classify the failure, propose and verify a permanent repair, or quarantine a persistent flake. This keeps maintenance in the development loop and leaves durable changes reviewable in Git. Re-resolve locators and wait for page stability during a run. Clear temporary obstructions without changing the test. Classify failures, repair tests, and deliver reviewable changes. Keep flaky tests running without blocking CI. ## Turn runs into reusable insights Each run adds information that Momentic uses to make future AI decisions more consistent and model how tests exercise the product. Reuse relevant decisions from earlier runs so AI behaves consistently. Measure journey coverage, improve AI test selection, and analyze product risk. Give every agent shared product terminology, rules, and known flows. These systems provide reusable context about test execution: coverage across the product, journeys a change puts at risk, and information the next agent needs before acting. See [How Momentic works](/docs/get-started/how-momentic-works) for how preset steps, AI actions, custom code, and CLI agents fit together. # Cloud deprecation Source: https://momentic.ai/docs/get-started/cloud-deprecation Authoring and running tests in the Momentic cloud is deprecated. Run `npx momentic import` to pull your tests into your repo and own them with the CLI. Momentic is **CLI-first**. Tests live in your repo as YAML, are authored and edited with the CLI (and your coding agent through MCP), and run locally or in CI. The web app at [app.momentic.ai](https://app.momentic.ai) is the dashboard for triage, settings, and integrations. ## Move your tests with `momentic import` The whole migration is one command. From the root of the repo you want your tests to live in, run: ```bash theme={null} npx momentic import ``` This pulls every test, module, and environment from the cloud down into your repo as YAML. Commit the generated files alongside your application code and you are done with the cloud editor. See [`momentic import`](/docs/cli-reference/momentic/commands/import) for flags. You can also pass test paths to import individual tests or folder paths (e.g. `auth/onboarding`) to import an entire cloud folder; the folder hierarchy is recreated on disk so your local layout mirrors the dashboard. If you do not have the CLI set up yet, the onboarding wizard installs it, logs you in, and scaffolds a project in one step: ```bash theme={null} npx @momentic/wizard@latest ``` After that, run `npx momentic import` from the project root. ## What is deprecated These surfaces are no longer supported. They may still respond for backwards compatibility but will be removed in a future release. * **Authoring tests in the cloud editor.** Create and edit tests with the CLI (and the local editor it ships with) or your coding agent via the [MCP server](/docs/coding-agents/mcp-server). * **Cloud-hosted test runs** ([`momentic queue tests`](/docs/cli-reference/momentic/commands/queue) and `queue suites`). Run with [`momentic run`](/docs/cli-reference/momentic/commands/run) locally or in [CI](/docs/running-tests/ci/github-actions) instead. * **Momentic Copilot** (the cloud-based AI authoring assistant). Use your coding agent with the [MCP server](/docs/coding-agents/mcp-server) for natural-language test authoring. ## What is **not** deprecated The dashboard at [app.momentic.ai](https://app.momentic.ai) is still the home for everything that isn't authoring or execution: * [Results and the Run Viewer](/docs/running-tests/results): videos, traces, auto-heal history, step output * [API keys, team, and SSO](/docs/account/api-keys-and-team) * [Security and audit](/docs/account/security) * [Quarantine](/docs/reliability/auto-maintenance#quarantine) and quarantine rules * [Results classification](/docs/reliability/auto-maintenance#permanent-healing) and recovery history * AI settings and model version pinning * Integrations: [Slack](/docs/integrations/slack), [GitHub](/docs/integrations/github), [GitLab](/docs/integrations/gitlab) * Usage and billing Every CI template and quickstart in these docs still points at the dashboard for these. Nothing about that is changing. ## After importing Once your tests are in the repo: Edit imported tests (or write new ones) in the local editor that ships with the CLI, or hand your coding agent the [MCP server](/docs/coding-agents/mcp-server) and describe the behavior in natural language. Tests are YAML files in your repo. Replace `momentic queue tests` and `momentic queue suites` with [`momentic run`](/docs/cli-reference/momentic/commands/run). For CI, drop in one of the [ready-made templates](/docs/running-tests/ci/github-actions). Pass `--upload-results` to surface runs in [the dashboard](https://app.momentic.ai). Nothing changes about how you view, share, or quarantine runs. ## Why CLI-first means tests are versioned with your application code, run the same way on a laptop and in CI, and integrate naturally with coding agents through MCP. The dashboard's job is triage and configuration, not authoring or execution. ## Related * [`momentic import`](/docs/cli-reference/momentic/commands/import) * [`momentic run`](/docs/cli-reference/momentic/commands/run) * [`momentic queue`](/docs/cli-reference/momentic/commands/queue) (deprecated) * [How Momentic works](/docs/get-started/how-momentic-works) * Quickstart: [Web](/docs/quickstart/web), [iOS](/docs/quickstart/ios), [Android](/docs/quickstart/android) * [MCP server](/docs/coding-agents/mcp-server) # How Momentic works Source: https://momentic.ai/docs/get-started/how-momentic-works How Momentic combines preset steps, AI actions, modules, execution, CLI-based agents, and context from past runs. ## Anatomy of a test A Momentic test is a sequence of steps. There are many step types: some rely on AI, while others can be configured deterministically or execute code. ### Human in the loop and agentic | Step type | Behavior | Examples | | --------------- | ---------------------------------------------------------------------------- | ------------------------------------------------------ | | **Preset step** | Executes one configured action. It can use AI or be fully deterministic. | Click, Type, JavaScript, AI extract, and Drag and drop | | **AI action** | A runtime agent determines and executes the sequence needed to reach a goal. | Complete checkout or configure an account | | **Module** | Runs a reusable sequence of preset steps or AI actions. | Log in, create an account, or seed a cart | Mix preset steps, AI actions, and module calls within one test. Modules can also combine preset steps and AI actions. Use preset steps when the path needs exact, reviewable control and agentic steps when the goal matters more than the path. Preset steps can still use AI to locate elements, evaluate assertions, or extract data while keeping the sequence explicit. See [File format](/docs/core-concepts/file-format), [Steps](/docs/core-concepts/steps), [Variables](/docs/core-concepts/variables), and [Modules](/docs/core-concepts/modules) for the authoring syntax. See [AI action](/docs/core-concepts/agentic-testing) for goal-driven flows. ### Code integration Web tests run on Playwright and mobile tests run on Appium. Use preset steps for common interactions, then drop to code when a flow needs it: * [JavaScript steps](/docs/integrations/javascript) run custom code in a sandboxed Node environment or the current browser page. * [Appium steps](/docs/reference/mobile-commands/appium) execute Appium scripts against the current device. * [Modules](/docs/core-concepts/modules) and [variables](/docs/core-concepts/variables) connect reusable setup, application state, and data across the flow. See [Test portability and migration](/docs/get-started/test-portability) for where your YAML lives and how to move a suite in or out. ## Run locally and in CI A test provides immediate feedback during development and repeatable verification after a change leaves a developer's machine. The same test files and CLI work in both loops: | Environment | Value | | --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Local development** | Run focused tests while you code, inspect artifacts immediately, and let a coding agent verify its own changes before a pull request. | | **CI** | Gate pull requests and deployments, select the most relevant tests based on a code change, parallelize larger suites, and publish results for the whole team. | Use [`momentic run`](/docs/cli-reference/momentic/commands/run) locally or in your [CI system](/docs/running-tests/ci/custom-setups). [AI test selection](/docs/ai/select) keeps pull-request feedback focused, while [AI test maintenance](/docs/reliability/auto-maintenance) turns eligible failures into recovery, diagnosis, and reviewable repairs. ## CLI-based agents Momentic exposes its AI agents through the CLI so they can be composed in CI, scripts, and custom agent loops: | Command | Role | | ---------------------- | --------------------------------------------- | | `momentic ai select` | Choose representative tests for a code change | | `momentic ai classify` | Explain and route failed runs | | `momentic ai triage` | Investigate, repair, and verify failing tests | Commands can emit structured output and operate on repository files or saved results, so your orchestrator decides when they run and what happens next. See the [`momentic ai` reference](/docs/cli-reference/momentic/commands/ai) and [MCP server](/docs/coding-agents/mcp-server). ## Self-learning system Momentic reuses context across runs: * The [step cache](/docs/reliability/step-cache) reuses successful element resolutions for fast, deterministic replay. * [Memory](/docs/ai/memory) retrieves relevant decisions from earlier runs for locator and assertion agents. * The [app graph](/docs/ai/app-graph) turns run traces into product journeys and coverage, powering [AI test selection](/docs/ai/select) and product risk analysis. * The [knowledge base](/docs/ai/knowledge-base) adds your terminology, rules, and known flows. Your team can customize it from the dashboard. See [What is AI-native testing?](/docs/get-started/ai-native-testing) for the end-to-end developer workflow. # Simplified format Source: https://momentic.ai/docs/get-started/migrate-to-simplified-format Move existing tests and modules from legacy YAML to Momentic's simplified format, on web and mobile. The simplified format makes Momentic YAML easier to review and maintain: no volatile step IDs on disk, shorter command aliases, relative module references, and JSON Schema support in modern editors. The migration rewrites Momentic test and module files. Back up your repository first, start from a clean Git state, and make sure there are no untracked changes before running it. Web (`momentic`) and mobile (`momentic-mobile`) are separate CLIs with separate migrations. Each command only rewrites files belonging to its own CLI and only flips `fileFormat: v2` on its own project's `momentic.config.yaml`. If your repo has both web and mobile Momentic projects, run **both** migrations; one will not touch the other's files. ## Before you start Pick a migration window when teammates are not actively changing Momentic tests. Everyone should move to the simplified format at roughly the same time. If one branch keeps editing legacy YAML while another branch lands the rewrite, later merges can be noisy. Before running the migration: ```bash theme={null} git status --short ``` Commit, stash, or otherwise back up any local changes before continuing. For an extra local backup, create a branch before the migration: ```bash theme={null} git branch backup/momentic-v1-format ``` ## 1. Update Momentic Always invoke the migration through `momentic@latest` / `momentic-mobile@latest` so the project config and YAML rewrites are produced by the new CLI's serializers, not the version currently pinned in your `package.json`. Running the bare `npx momentic upgrade` on an older pinned version installs the new CLI but completes the rest of the upgrade with the old one, which means you would need a second invocation to see the new behavior take effect. Check your currently-pinned versions before continuing: ```bash theme={null} npx momentic --version # web npx momentic-mobile --version # mobile ``` If your MCP server is pinned in an editor config, update that command too. The MCP server must run a version that understands simplified format files before agents can create, preview, or edit them. ```bash theme={null} npx momentic mcp --config /absolute/path/to/momentic.config.yaml npx momentic-mobile mcp --config /absolute/path/to/mobile-momentic.config.yaml ``` ## 2. Run the migration You have two entry points, depending on how much you want to touch: * `momentic@latest upgrade` / `momentic-mobile@latest upgrade`: **overarching**. Installs the latest CLI into your project, applies the latest recommended project-config defaults (`ai.agentConfig` agent versions, `ai.useMemory`, `ai.failureRecovery`), sets `fileFormat: v2`, and rewrites every legacy `*.test.yaml` / `*.module.yaml` through the simplified format serializer. Use this when you want one command to bring the whole project current. * `momentic migrate simplified-format` / `momentic-mobile migrate simplified-format`: **file migration only**. Rewrites legacy test and module files to the simplified format and flips `fileFormat: v2` on the project config, but leaves your CLI version and `ai.*` defaults alone. Use this when you want a tight, isolated diff with no config-default changes mixed in. Runs against the CLI version already installed in your project; if it is older than the published `momentic@latest` the command will warn you and point at `npx momentic@latest upgrade` so you can install the newest serializers. Both paths share the same simplified format serializer and skip files that already use the simplified format. The first file that fails to migrate aborts the run; the migration is not designed to be resumable, so resolve the surfaced error and rerun the command before continuing. ### Preview with `--dry-run` Both upgrade commands accept `--dry-run` to preview what would change without writing anything to disk or pushing any snapshots: ```bash theme={null} npx momentic@latest upgrade --dry-run npx momentic-mobile@latest upgrade --dry-run ``` The output lists how many tests and modules would be migrated, how many already use the simplified format, and which `ai.agentConfig` entries would be updated. ### Web From the web project root, run **one** of: ```bash theme={null} npx momentic@latest upgrade # everything: CLI version + config + files npx momentic migrate simplified-format # just rewrite the YAML files (uses the installed CLI) ``` A typical web test in the simplified format should start with `fileType: momentic/test/v2`; a module should start with `fileType: momentic/module/v2`. ### Mobile From the mobile project root, run **one** of: ```bash theme={null} npx momentic-mobile@latest upgrade # everything: CLI version + config + files npx momentic-mobile migrate simplified-format # just rewrite the YAML files (uses the installed CLI) ``` A typical mobile test in the simplified format should start with `fileType: momentic/mobile-test/v2`; a mobile module should start with `fileType: momentic/mobile-module/v2`. If you maintain both a web and a mobile project, run the command in each project root. Neither CLI touches the other's files, so a single-platform run will silently leave the other platform's tests in legacy YAML. ### What to expect Each migration takes about 1 minute per 50 tests. Existing step caches are preserved across the conversion. Review the diff like application code, then commit all rewritten Momentic YAML files together with the `momentic.config.yaml` change. Do not split the config change into a separate commit because the project should switch formats as one unit. If your repo already uses the simplified format and the agent config is current, the upgrade command is a clean no-op. It will not rewrite any files. ## 3. Reinstall Momentic skills The Momentic skills teach coding agents and the MCP server how to author and edit simplified format files efficiently, including which MCP tools to reach for when making surgical edits to the readable YAML. Reinstall them from your project root after the migration so every editor that reads them picks up the latest guidance: ```bash theme={null} npx skills add momentic-ai/skills ``` The `skills` CLI is idempotent and auto-detects `.claude/`, `.cursor/`, `.agents/`, `.opencode/`, and `.github/copilot/` directories, rewriting the installed skill files in place. Run it once after the migration, then restart your editor so the new skill content is loaded. If you previously installed skills with `npx momentic install-skills` or `npx momentic-mobile install-skills`, switch to the standalone `skills` CLI; the bundled commands are deprecated. ## 4. Enable editor validation Momentic publishes static JSON Schemas for simplified format tests and modules. Add them to your editor to get autocomplete and inline validation as you write. The schemas work for web, mobile, and mixed repos. See [IDE lint](/docs/core-concepts/editor-validation) for VS Code, Cursor, Windsurf, and Zed config. The onboarding wizard (`npx @momentic/wizard@latest`) configures this automatically for the editors it detects. ## 5. Use lint for agent edits Editor schemas catch shape errors early. Momentic also runs simplified format lint automatically before starting the local app and before executing tests, so normal app and test workflows already block invalid YAML. Use the `lint` command when a coding agent or direct YAML edit changes Momentic test files and you want a quick validation without starting the app or running tests. It checks schema validity, local file references, and entity conflicts. Web: ```bash theme={null} npx momentic lint ``` Mobile: ```bash theme={null} npx momentic-mobile lint ``` Run the matching command once after the migration, then use it as a lightweight guardrail for agent-authored changes. To check one file during review: ```bash theme={null} npx momentic lint tests/checkout.test.yaml npx momentic-mobile lint mobile-tests/login.test.yaml ``` ## 6. Author simplified format files After migration, restart your editor so it launches the updated MCP command when you do need browser-backed authoring. MCP is still the most reliable way to create, preview, and execute steps against a live browser. For lightweight changes, simplified format files are also safe to edit directly. The readable YAML format, static schemas, and editor completions make small updates easier: * Prompt coding agents to directly edit `*.test.yaml` and `*.module.yaml` for simple changes that do not need a browser. * Hand-author tests with YAML tab completions and schema suggestions in your editor. * Reference local files from steps. JavaScript steps can point at local JS files, and those JS files can reference other local files with relative paths. See [File format](/docs/core-concepts/file-format) for the top-level YAML structure, [Steps](/docs/core-concepts/steps) for step syntax, and [MCP](/docs/coding-agents/mcp-server) for MCP setup. For a spec-driven workflow that uses Momentic tests as product specs, see [Spec-driven development](/docs/coding-agents/mcp-server#spec-driven-development) in the MCP guide. # Test portability and migration Source: https://momentic.ai/docs/get-started/test-portability Where your tests live, how to migrate an existing test suite, and how to migrate out of Momentic. Your tests are YAML files in your repository, under your own version control and code review. The format is published. ## Where your tests live Momentic tests and modules are `*.test.yaml` and `*.module.yaml` files in your repository. If a test or module is managed in the dashboard, [`momentic import`](/docs/cli-reference/momentic/commands/import) pulls it down to disk and recreates its folder hierarchy. Read the [V2 format reference](https://static.momentic.ai/v2-format-reference.md), the [web command reference](/docs/reference/commands/index), and [Steps](/docs/core-concepts/steps) for the published format and step references. ## Migrating an existing test suite Use a coding agent through the [MCP server](/docs/coding-agents/mcp-server) with the [skills](/docs/ai/skills) to write the YAML from an existing spec. This is the fastest way to port a suite. Momentic ships no automatic converter from Playwright, Cypress, or Selenium. Keep your existing suite running. Port the highest-value flows first. Label the ported tests and run them with `--labels` while both suites overlap. Delete an old spec only after its replacement passes a few consecutive runs. See [Run from the command line](/docs/running-tests/running-locally) for the CLI workflow. Keep existing setup code by calling it from a [JavaScript step](/docs/reference/commands/javascript) in the [Node sandbox](/docs/integrations/javascript). Reuse a Playwright storage-state file directly with the [`authLoad` step](/docs/reference/commands/auth-load). ## Migrate out of Momentic Momentic ships no exporter. Web tests run on Playwright and mobile tests run on Appium. See [How Momentic works](/docs/get-started/how-momentic-works) for the execution model. The YAML files are already in your repository, and the format is published, so you do not need to extract test source from a vendor first. Enterprise customers can ask for a one-time eject to open-source Playwright at contract termination. Ask your account team. Some steps have no equivalent in an open-source framework. An [AI action](/docs/reference/commands/act) takes a goal in plain English and decides the clicks and the types itself. An [AI check](/docs/reference/commands/assert) reads the DOM, the accessibility tree, and a screenshot to judge a semantic assertion. The [step cache](/docs/reliability/step-cache) replays a resolved step with no model call. [In-flow classification](/docs/guides/auto-heal/in-flow-classification) gives a failed run a category and a triage action before the CLI exits, and [auto-maintenance](/docs/reliability/auto-maintenance) repairs a step that moved. A port to Playwright must express each of these as explicit code, or drop it. Deterministic preset steps, such as navigating to a URL, waiting, or clicking a CSS selector, map onto a Playwright or Appium call. A preset step that resolves a target in plain English, evaluates an assertion, or extracts data with AI does not. Results already leave in standard formats. Use `--reporter junit`, `--reporter json`, or `--reporter playwright-json` so your dashboards and CI gates do not depend on ours. See [Results and reporting](/docs/running-tests/results) and [JUnit outputs](/docs/guides/reporting/junit-outputs). ## What stays behind If you leave Momentic, dashboard run history, AI memory, and step caches stay behind. They are organization-scoped Momentic state, not test source. See [AI memory](/docs/ai/memory) and [Step caching](/docs/reliability/step-cache). ## Reduce AI dependence Write preset steps where the action is stable. Keep AI steps for the parts that move. The step cache replays a resolved locator with no model call while its stored signals still match the page. See [Step caching](/docs/reliability/step-cache) and [Steps](/docs/core-concepts/steps). # Upgrading to momentic-mobile v1 Source: https://momentic.ai/docs/get-started/upgrade-to-mobile-v1 What changed in momentic-mobile 1.0 and how to move your mobile project from a 0.x release. momentic-mobile 1.0 drops Node.js 20 and changes how test videos are recorded. This guide covers the breaking changes and how to upgrade. This guide is for the mobile CLI (`momentic-mobile`). The web CLI (`momentic`) has its own [v3 upgrade guide](/docs/get-started/upgrade-to-v3). If your repo has both, upgrade each separately. ## 1. Use Node.js 22 momentic-mobile 1.0 requires **Node.js 22 or newer**. Node.js 20 has reached end of life and is no longer supported. Check your version and upgrade if needed: ```bash theme={null} node --version # must be v22 or newer ``` Update the Node version in your CI images and any `.nvmrc` / `engines` field before upgrading. ## 2. Run the upgrade From your mobile project root: ```bash theme={null} npx momentic-mobile@latest upgrade ``` This installs the latest CLI and applies the current recommended project defaults. Pass `--dry-run` first to preview what would change without writing anything. ## 3. Breaking changes * **`--record-video` flag removed.** Use `--video` instead (`--video true` to keep every recording, `--video false` to disable). Recording now defaults to `on-fail`: a video is captured for every run but kept only when the test fails. ## 4. Other changes These do not require action but are worth knowing: * AI Action steps default to the V3 agent. Existing steps continue to run unchanged. * New projects pin each AI agent to the latest exact sub-version so defaults stay fixed when a newer revision ships. ## Related * [Simplified format](/docs/get-started/migrate-to-simplified-format) * [`momentic-mobile upgrade`](/docs/cli-reference/momentic-mobile/commands/upgrade) * [`momentic-mobile run`](/docs/cli-reference/momentic-mobile/commands/run) # Upgrading to momentic v3 Source: https://momentic.ai/docs/get-started/upgrade-to-v3 What changed in momentic 3.0 and how to move your web project from a 2.x release. momentic 3.0 drops Node.js 20, retires the legacy `v1` AI agents, and removes a few config options that are now handled automatically. This guide covers the breaking changes and how to upgrade. This guide is for the web CLI (`momentic`). Mobile (`momentic-mobile`) has its own [v1 upgrade guide](/docs/get-started/upgrade-to-mobile-v1). If your repo has both, upgrade each separately. ## 1. Use Node.js 22 momentic 3.0 requires **Node.js 22 or newer**. Node.js 20 has reached end of life and is no longer supported. Check your version and upgrade if needed: ```bash theme={null} node --version # must be v22 or newer ``` Update the Node version in your CI images and any `.nvmrc` / `engines` field before upgrading. ## 2. Run the upgrade From your web project root: ```bash theme={null} npx momentic@latest upgrade ``` This installs the latest CLI and applies the current recommended project defaults. Pass `--dry-run` first to preview what would change without writing anything. ## 3. Reinstall your browsers momentic 3.0 bundles **Playwright 1.60.0**, which pins newer browser builds than earlier releases. `momentic upgrade` does not download these for you, and your existing browser binaries were installed for the old Playwright version, so reinstall them after upgrading to avoid launch errors: ```bash theme={null} npx momentic install-browsers chromium ``` Pass whichever browsers your tests use (`chromium`, `chrome`, or `chrome-for-testing`), or `--all` to install every supported browser. See [`momentic install-browsers`](/docs/cli-reference/momentic/commands/install-browsers) for details. ## 4. Breaking changes Each of these requires an edit if your project uses the affected feature: * **Legacy `v1` AI agents removed.** The `v1` locator, assertion, visual assertion, and text extraction agents have been retired. A run that pins one of these in `ai.agentConfig` in `momentic.config.yaml` now errors; switch those entries to a current version (see [AI configuration](/docs/configuration/ai)). * **`browser.bustCacheOnBoundingBoxChange` removed.** The element cache is now invalidated automatically when an element's bounding box changes, so the setting is no longer needed. Remove it from `momentic.config.yaml`. * **`--record-video` flag removed.** Use `--video` instead (`--video true` to keep every recording, `--video false` to disable). Recording now defaults to `on-fail`: a video is captured for every run but kept only when the test fails. * **AI Action steps default to the V3 agent.** The older V2 agent is marked "Legacy" and can no longer be selected for new AI Action steps in the editor. Existing V2 steps continue to run unchanged. ## 5. New-project defaults These apply to projects created with `momentic init` and do not change existing projects, but are worth knowing: * Hybrid selectors are enabled by default (`browser.hybridSelectorMode: prefer`). * New projects set `browser.disableSecondaryCacheResolution: true`. * New projects pin each AI agent to the latest exact sub-version so defaults stay fixed when a newer revision ships. Set any of these explicitly in `momentic.config.yaml` to override the default. ## Related * [Simplified format](/docs/get-started/migrate-to-simplified-format) * [`momentic upgrade`](/docs/cli-reference/momentic/commands/upgrade) * [`momentic run`](/docs/cli-reference/momentic/commands/run) * [Browser configuration](/docs/configuration/browser) * [AI configuration](/docs/configuration/ai) # Overview Source: https://momentic.ai/docs/guides Task-oriented recipes for the most common Momentic workflows, like auth, file uploads, network assertions, and data-driven runs. Each guide is a focused how-to, short enough to skim and copy from. Classify failures during a run, control CI gating, and route failures into AI test maintenance. Roll up imperative steps into declarative goals, group them into semantic phases, and design around the agent's limits. Choosing a strategy, email OTP, SMS OTP, magic links, TOTP, cached sessions, Vercel previews. Upload/download files, dropdowns, record and validate network requests. Generate fake data inline and run tests against CSV input rows. Store visual diff snapshots in the repo alongside tests. Export JSON reports, JUnit outputs, and self-hosted run results. Regression, smoke, PR, and agentic testing patterns. # Writing effective AI actions Source: https://momentic.ai/docs/guides/ai-actions/guide A practical guide to writing AI action steps, from rolling up imperative clicks into declarative goals to grouping goals into semantic phases, guarding flows with conditions, and the limits to design around. [AI action](/docs/core-concepts/agentic-testing) lets you hand Momentic a natural-language goal instead of a click-by-click series of steps. With an AI action, Momentic plans the flow, runs it in the browser or app, caches the resolved steps after the first successful run, and self-heals when a cached step misses. Each section below covers a pattern, when to reach for it, and the trade-off. If you are new to agentic steps, read [Agentic testing](/docs/core-concepts/agentic-testing) first for the basics, then come back here for patterns. ## The mental model A typical Momentic test is written as explicit `click` and `type` steps and spells out *how* to reach an outcome. Click this, type that. Instead, with AI action you tell Momentic *what* you want, and then AI figures out the how. Planning with AI is slow, so the agent caches the steps it resolves on the first successful run and replays them deterministically afterward, paying the model cost once instead of on every run. This changes what you maintain. Instead of a list of steps tied to the current layout, you keep a short statement of intent. Because your goal names the outcome rather than the exact path, the test holds up through UI churn, and the agent re-resolves the steps whenever the UI moves. ## Rolling up a Google Flights search The examples below use a flight search on [Google Flights](https://www.google.com/travel/flights) to show the core technique of AI action. You take a series of low-level steps whose only purpose is to reach some state, then collapse them into a single goal that names that state. First, here is the search written the imperative way. It spells out every click and keystroke, so the actual intent of searching two cities for two dates gets buried in the mechanics, and a reader has to reconstruct it from the steps. ```yaml flight-search.test.yaml theme={null} fileType: momentic/test/v2 id: bright-copper-lantern url: https://www.google.com/travel/flights steps: - click: The "Where from?" origin field - type: text: San Francisco into: The origin field - click: The "San Francisco" airport option in the suggestions - click: The "Where to?" destination field - type: text: New York into: The destination field - click: The "New York" option in the suggestions - click: The Departure date field - click: The August 10 date in the calendar - click: The Return date field - click: The August 17 date in the calendar - click: The Search button ``` Here is the same flow written as one declarative goal. ```yaml flight-search.test.yaml theme={null} fileType: momentic/test/v2 id: quiet-orchid-window url: https://www.google.com/travel/flights steps: - act: |- Search for round-trip flights from San Francisco to New York, departing August 10 and returning August 17. ``` The second version states the intent directly, so the specific clicks become an implementation detail the agent works out rather than something you maintain. When Google restyles the date picker or moves a field, the imperative version breaks and needs a rewrite. The declarative goal adapts, because the intent has not changed and the agent re-resolves the new UI. ### Assert the end state with a postcondition The agent cannot pass its own step. When it claims success, an independent reviewer reads the settled page state, the actions the harness recorded, and your goal, then decides whether the goal's outcome actually happened. You write an explicit `postcondition` when the goal alone does not tell the reviewer what "done" should look like. For a flight search you might require that results actually rendered, not just that the form was submitted. A `postcondition` is a protected requirement the reviewer must also confirm, and the agent cannot skip or edit it. ```yaml flight-search.test.yaml theme={null} fileType: momentic/test/v2 id: silver-maple-orbit url: https://www.google.com/travel/flights steps: - act: goal: |- Search for round-trip flights from San Francisco to New York, departing August 10 and returning August 17. postcondition: |- The results page lists round-trip flights from San Francisco to New York for the August 10 to August 17 dates, and each result shows a price and a departure time. ``` Think of the postcondition as the contract for an `act`, since it spells out what "done" means for that step. That makes each step a clean checkpoint when you chain them together, so one `act` hands off to the next at a known state instead of wherever the goal happened to stop. The [section on guards](#guarding-a-flow-with-pre--and-post-conditions) below goes deeper and covers preconditions too. ## Group goals into semantic phases The rollup above has a counterpart, which is that you should not collapse an *entire* test into one giant goal either. The sweet spot is a few AI actions that each map to a phase a reader would recognize. Each `act` becomes a labeled checkpoint in the trace, so when something fails you know which phase broke. ```yaml browse-products.test.yaml theme={null} fileType: momentic/test/v2 id: velvet-river-compass url: https://www.saucedemo.com/ steps: - act: Log in with username 'standard_user' and password 'secret_sauce'. - act: Sort the products by price from low to high. - act: Open the detail page for the first product in the list. ``` Each phase is small enough that the agent plans it reliably and the cache stays stable. Aim for goals that a teammate could read as a list of what the test proves, like log in, sort, then open a product. Avoid one 200-word goal that buries five distinct outcomes. ## Guarding a flow with pre- and post-conditions The rollup introduced `postcondition`. Its counterpart is `precondition`, which guards the *start* of a flow. Both are protected assertions the agent cannot edit or skip, so they are the honest definition of "did this work". A `postcondition` is more than a pass/fail gate, because if it is not met when the agent finishes, the agent treats it as a target and keeps working toward it, failing the step only if it cannot get there. A flow that "completed" in the wrong place is therefore either corrected or fails loudly. ```yaml login-guarded.test.yaml theme={null} url: https://www.saucedemo.com/ steps: - act: precondition: A login form with Username and Password fields is visible. goal: Log in with username 'standard_user' and password 'secret_sauce'. postcondition: The product inventory list is shown. ``` Use a `precondition` to fail fast and clearly when setup is wrong (wrong page, not logged out) instead of letting the agent flail. Add an explicit `postcondition` whenever the goal itself does not pin down the end state of a state-changing flow. Pre- and post-conditions follow the same rules as [AI check](/docs/core-concepts/writing-assertions) steps. Assert structural, qualitative facts ("a confirmation is shown"), and never exact counts, prices, timestamps, or IDs that change between runs. ## Feeding the agent context it cannot infer The agent only knows what is on screen. Anything external (an invite code, a specific record to act on, credentials) must come in through [variables](/docs/core-concepts/variables). Reference them with `{{ env.NAME }}` in the goal. ```yaml login.test.yaml theme={null} url: https://www.saucedemo.com/ steps: - act: goal: |- Log in with username '{{ env.QA_USERNAME }}' and password '{{ env.QA_PASSWORD }}'. postcondition: The product inventory list is shown. ``` ## Branching on UI that only sometimes appears Some UI appears on only some runs: cookie banners, "what's new" modals, A/B interstitials. When the agent handles that UI, the cache stores an `If ` branch with the steps for that case, plus an optional else branch. Later runs re-evaluate the condition against the live UI and replay only the branch that applies, so a flow that differs between runs no longer needs the agent every time. The condition is a check, so it follows check rules: write the goal so the condition can be a structural, qualitative fact ("a cookie banner is shown"). Everything inside the branch replays from cache. If the steps in a branch no longer match the UI, the cache busts and the step heals like any other cached step. See the [step cache](/docs/reliability/step-cache#ai-action-caches). ## Limitations of AI action An AI action is a bounded planning agent, not a general program. Designing within these limits keeps tests fast and deterministic. ### No unbounded or infinite loops The agent will not "keep clicking Next until the list is empty" forever. It runs a bounded plan with a retry budget and then stops, and it will not repeat an ineffective interaction more than a couple of times. If your intent is genuinely to repeat until some condition, express the bound explicitly and keep it finite. * Avoid `Keep loading more results until every order is on screen.` * Prefer `Click "Load more" up to 3 times, then stop.` ## Related * [Agentic testing](/docs/core-concepts/agentic-testing) * [act command reference](/docs/reference/commands/act) * [Writing assertions](/docs/core-concepts/writing-assertions) * [Variables](/docs/core-concepts/variables) * [Step cache](/docs/reliability/step-cache) and [Auto-heal](/docs/reliability/auto-maintenance#locator-auto-healing) * [Goal-based testing](/docs/best-practices/goal-based-testing) # Cache authenticated sessions Source: https://momentic.ai/docs/guides/auth/cached-session Wrap your login flow in an auth module so parallel tests only authenticate once. Running the full login flow for every test hits auth provider rate limits and wastes time. Wrap it in a module, enable caching, and Momentic reuses the saved browser state across runs. If you're new to auth in Momentic, start with [Authentication strategies](/docs/guides/auth/overview) for the full set of options and trade-offs. ## Setup 1. Extract your login steps into a **Module**. The last step should verify the authenticated state (e.g. a **Page check** for the dashboard URL). 2. In the module config, enable **Caching globally** (`defaultCacheAllInvocations`) and **Treat as auth module** (`autoAuth`). 3. Set a **Default cache key** (`defaultCacheKey`, e.g. `admin-user`). Parallel tests sharing the key reuse the same cached session. 4. Set a **Default expiry** (`defaultCacheTtl`, in milliseconds) shorter than your session lifetime. 5. Remove any **Save auth state** / **Load auth state** (`authSave` / `authLoad`) steps. A cached auth module handles this automatically; see [Save and restore a state file](/docs/guides/auth/overview#2-save-and-restore-a-state-file-authsave-authload). The module's stored config looks like this: ```yaml log-in.module.yaml theme={null} fileType: momentic/module/v2 id: golden-harbor-key name: Log in autoAuth: true # Treat as auth module defaultCacheAllInvocations: true # Caching globally defaultCacheKey: admin-user # Default cache key defaultCacheTtl: 3600000 # Default expiry (1 hour, in ms) steps: - type: text: "{{ env.USERNAME }}" into: Email input - type: text: "{{ env.PASSWORD }}" into: Password input - click: Log in - checkPageContains: text: Dashboard # verify the login worked before the session is cached ``` Invoke it from each test's [`before` section](/docs/core-concepts/file-format#before-and-after-sections): ```yaml checkout.test.yaml theme={null} before: - module: ../modules/log-in.module.yaml ``` Use different cache keys for different user roles (e.g. `admin`, `member`) so state doesn't carry over between them. ## How it works Momentic captures cookies, `localStorage`, and IndexedDB when the module finishes. On subsequent runs within the expiry window, it restores that state and skips the module's steps. ## Related * [Modules](/docs/core-concepts/modules#authentication-modules) * [Email OTP](/docs/guides/auth/email-otp) # Log in with email verification links Source: https://momentic.ai/docs/guides/auth/email-link Extract a magic login link from an email and navigate to it. **Prerequisite**: A Momentic-provisioned inbox. [Request one](mailto:support@momentic.ai). ## Fetch and navigate ```js theme={null} const msg = await email.fetchLatest({ inbox: "link+test", afterDate: new Date(Date.now() - 60_000), timeout: 30_000, }); const [link] = msg.text.match(/https?:\/\/[^\s]+/) ?? []; if (!link) throw new Error("No verification link found in email"); setVariable("VERIFICATION_LINK", link); ``` Then add a **Navigate** step with URL `{{ env.VERIFICATION_LINK }}`. This script polls for up to 30 seconds, well within the JavaScript step's **90 second** default timeout. For longer polls, raise the step's **Timeout** field (cloud is platform-capped at 60s; CLI supports up to 10 minutes). ## Related * [Email OTP](/docs/guides/auth/email-otp) * [Email integration](/docs/integrations/email) # Log in with email OTP codes Source: https://momentic.ai/docs/guides/auth/email-otp Fetch a one-time passcode from a Momentic-provisioned inbox and type it into your app. **Prerequisite**: A Momentic-provisioned inbox (`@usemomentic.com` or `@gomomentic.com`). [Request one](mailto:support@momentic.ai). ## Fetch the code Add a **JavaScript** step that reads the latest email, parses the code, and saves it to the environment. ```js theme={null} const msg = await email.fetchLatest({ inbox: "otp+test", afterDate: new Date(Date.now() - 60_000), timeout: 30_000, }); const [code] = msg.text.match(/\b\d{6}\b/) ?? []; if (!code) throw new Error("No OTP code found in email"); setVariable("OTP_CODE", code); ``` Then add a **Type** step with value `{{ env.OTP_CODE }}` targeting the OTP input. Always pass `afterDate` to avoid matching a stale code from a previous run. This script polls for up to 30 seconds, well within the JavaScript step's **90 second** default timeout. For longer polls, raise the step's **Timeout** field (cloud is platform-capped at 60s; CLI supports up to 10 minutes). ## Related * [SMS OTP](/docs/guides/auth/sms-otp) * [Email verification links](/docs/guides/auth/email-link) * [Email integration](/docs/integrations/email) # Log in with OTPAuth (TOTP) Source: https://momentic.ai/docs/guides/auth/otpauth Generate authenticator-app 2FA codes inside a **JavaScript** step using the `otpauth` library. **Prerequisite**: A Base32 TOTP secret (shown during 2FA enrollment) or an `otpauth://` URI (often embedded in a QR code). The [`otpauth`](https://www.npmjs.com/package/otpauth) library is preloaded in the **JavaScript** step sandbox. ## From a Base32 secret ```js theme={null} const totp = new OTPAuth.TOTP({ issuer: "MyApp", label: "alice@example.com", algorithm: "SHA1", digits: 6, period: 30, secret: env.TOTP_SECRET, // Base32-encoded }); setVariable("TOTP_CODE", totp.generate()); ``` ## From an `otpauth://` URI ```js theme={null} const totp = OTPAuth.URI.parse(env.TOTP_URI); setVariable("TOTP_CODE", totp.generate()); ``` Then add a **Type** step with value `{{ env.TOTP_CODE }}`. Store the secret as an [environment variable](/docs/core-concepts/variables#environment-variables) rather than hardcoding it. ## Related * [Email OTP](/docs/guides/auth/email-otp) * [SMS OTP](/docs/guides/auth/sms-otp) * [otpauth code generator](https://otpauth.molinero.dev/) # Authentication strategies Source: https://momentic.ai/docs/guides/auth/overview How to authenticate in your tests and reuse the session across runs. Compares live login, authSave/authLoad state files, and cached auth modules, with trade-offs and a recommended order. Most tests need to be logged in before they do anything useful. There are three ways to handle that. Reach for them in this order: stay with **live login** while it is fast enough, then add an **`authSave` / `authLoad` state file**, and only move to a **cached auth module** when you need it. ## 1. Live login (recommended default) Wrap your login steps in a **module** and call it from the [`before` section](/docs/core-concepts/file-format#before-and-after-sections) of each test. It logs in for real on every run, so the session is never stale and there is nothing to invalidate. ```yaml log-in.module.yaml theme={null} fileType: momentic/module/v2 id: coral-maple-bridge name: Log in steps: - type: text: "{{ env.USERNAME }}" into: Email input - type: text: "{{ env.PASSWORD }}" into: Password input - click: Log in - checkPageContains: text: Dashboard # verify the authenticated state ``` ```yaml checkout.test.yaml theme={null} fileType: momentic/test/v2 id: quiet-orchid-compass url: https://shop.example.com before: - module: ../modules/log-in.module.yaml steps: - act: Add a "Gravity Blanket" to the cart and check out - assert: The order confirmation page is shown ``` Prefer this whenever login is quick and not rate-limited. Move to one of the options below only when logging in on every run is too slow or trips auth-provider rate limits. Running the test **from a step in the main body** (a common thing to do while editing) skips the `before` section, so the login never runs and the first step lands on a logged-out page. Run the **whole test** to exercise the `before` section. See [Before and after sections](/docs/core-concepts/file-format#before-and-after-sections). ## 2. Save and restore a state file (`authSave` / `authLoad`) The `authSave` and `authLoad` steps (the editor's **Save auth state** / **Load auth state**) write and read the browser's cookies, `localStorage`, and IndexedDB to a JSON file you manage yourself. This is the closest analog to [Playwright's `storageState`](https://playwright.dev/docs/auth), so it is the natural next step if you are migrating from Playwright: log in once, save the state, and load it instead of logging in again. ```yaml checkout.test.yaml theme={null} before: - authLoad: ./auth-state.json after: - authSave: ./auth-state.json ``` The file is portable and version-controllable: you can generate it in a setup step, commit a fixture, or hand it to a non-Momentic tool. The trade-off is that you own its freshness: refresh it when the saved session expires. ## 3. Cached auth module When you want the speed-up without managing a file, let Momentic cache the session for you. Mark the login module as an auth module and enable caching: the first run logs in for real, and later runs (and parallel tests sharing the same cache key) restore the saved browser state server-side and skip the login steps entirely. ```yaml log-in.module.yaml theme={null} fileType: momentic/module/v2 id: coral-maple-bridge name: Log in autoAuth: true # "Treat as auth module": save & restore cookies/localStorage/IndexedDB defaultCacheAllInvocations: true # "Cache globally": reuse across tests defaultCacheKey: admin-user # parallel tests sharing this key reuse one session defaultCacheTtl: 3600000 # expire after 1 hour (shorter than the session lifetime) steps: - type: text: "{{ env.USERNAME }}" into: Email input - type: text: "{{ env.PASSWORD }}" into: Password input - click: Log in - checkPageContains: text: Dashboard # verify the authenticated state so the cache only saves on success ``` Call it from the `before` section exactly like the live-login module. This is the fastest option at scale (parallel tests reuse one session) and Momentic handles capture, storage, expiry, and per-key isolation for you. See [Cache authenticated sessions](/docs/guides/auth/cached-session) for the full walkthrough and [Modules](/docs/core-concepts/modules#authentication-modules) for every cache field. Don't combine `authSave` / `authLoad` with a cached auth module for the same session; both save and restore state, and doing both leads to stale or conflicting auth. Pick one. ## Options and trade-offs | Strategy | When it runs | Trade-offs | | ----------------------------------------- | ---------------------------------- | -------------------------------------------------------------------------------------- | | **Live login** (recommended) | Every run (whole-test runs only) | Most reliable, never stale. Logs in every run, so slower and can hit rate limits. | | `authSave` / `authLoad` state file | Whenever you place the steps | Portable JSON, like Playwright's `storageState`. You own refreshing it when it stales. | | Cached auth module (`autoAuth` + caching) | Once per cache key, within the TTL | Fastest at scale; parallel tests reuse one session. Needs a cache key and expiry. | ## In CI Live login works in CI with no extra setup; provide credentials as [secrets](/docs/configuration/environments#secrets) (`env.USERNAME`, `env.PASSWORD`, OTP secrets) rather than committed values. If logging in every run is too slow, add an `authSave` / `authLoad` state file or a cached auth module; the module's session is stored server-side alongside the [step cache](/docs/reliability/step-cache), so once one run logs in, other runs and shards can reuse it within the TTL. ## SSO, 2FA, and provisioned inboxes Avoid logging in through SSO providers (Google, Facebook, GitHub). They often block automated browsers. For one-time codes and magic links, fetch the code in a **JavaScript** step and save it to the environment: * [Email OTP](/docs/guides/auth/email-otp) * [SMS OTP](/docs/guides/auth/sms-otp) * [Email magic links](/docs/guides/auth/email-link) * [Authenticator-app codes (TOTP)](/docs/guides/auth/otpauth) ## Related * [Cache authenticated sessions](/docs/guides/auth/cached-session) * [Authentication concepts](/docs/core-concepts/authentication) * [Modules](/docs/core-concepts/modules) * [File format: before and after sections](/docs/core-concepts/file-format#before-and-after-sections) # Log in with SMS OTP codes Source: https://momentic.ai/docs/guides/auth/sms-otp Fetch a one-time passcode from a Momentic-provisioned phone number and type it into your app. **Prerequisite**: A Momentic-provisioned phone number. [Request one](mailto:support@momentic.ai). ## Single-number setup If you only need OTP login from one fixed number (or your tests don't run in parallel), fetch the latest message and pull the code out: ```js theme={null} const msg = await sms.fetchLatest({ to: "+18888888888", afterDate: new Date(Date.now() - 60_000), timeout: 30_000, }); const [code] = msg.body.match(/\b\d{6}\b/) ?? []; if (!code) throw new Error("No OTP code found in SMS"); setVariable("OTP_CODE", code); ``` Then add a **Type** step with value `{{ env.OTP_CODE }}`. ## Parallel runs against the same OTP flow If you run the same OTP login test in parallel (e.g. multiple shards in CI), two tests can race on the same inbound code. Lease a number from your pool so each shard gets its own. Momentic releases it back to the pool when the test finishes. ```js theme={null} const { phoneNumber } = await sms.lease(); // trigger your app's "Send code" flow against `phoneNumber` const msg = await sms.fetchLatest({ to: phoneNumber, afterDate: new Date(Date.now() - 60_000), timeout: 30_000, }); const [code] = msg.body.match(/\b\d{6}\b/) ?? []; if (!code) throw new Error("No OTP code found in SMS"); setVariable("OTP_CODE", code); ``` See [`sms.lease()`](/docs/integrations/sms#sms-lease) for full options (TTL, fail-fast, optional manual release). Both examples poll for up to 30 seconds, well within the JavaScript step's **90 second** default timeout. For longer polls, raise the step's **Timeout** field (cloud is platform-capped at 60s; CLI supports up to 10 minutes). ## Related * [Email OTP](/docs/guides/auth/email-otp) * [OTPAuth (TOTP)](/docs/guides/auth/otpauth) * [SMS integration](/docs/integrations/sms) # Test Vercel protected preview environments Source: https://momentic.ai/docs/guides/auth/vercel-previews Bypass Vercel's authentication wall using a protection bypass secret. **Prerequisite**: A Vercel [protection bypass secret](https://vercel.com/docs/security/deployment-protection/methods-to-bypass-deployment-protection/protection-bypass-automation). Two methods: headers (fast, but blocked by CORS on some apps) or query parameters (work even when CORS blocks headers). ## Option A: Headers In the test's **Network options**, add: | Header | Value | | ---------------------------- | --------------- | | `x-vercel-protection-bypass` | `` | | `x-vercel-set-bypass-cookie` | `true` | These headers are sent with **every** request in the session, including third-party script requests. If you see CORS errors, use query parameters instead. ## Option B: Query parameters Override the base URL in the test's **General options**: ``` https://your-preview.vercel.app?x-vercel-protection-bypass=&x-vercel-set-bypass-cookie=true ``` Vercel sets the bypass as a cookie for the rest of the session, so subsequent requests don't need the query string. ## Related * [Vercel docs: Protection bypass automation](https://vercel.com/docs/security/deployment-protection/methods-to-bypass-deployment-protection/protection-bypass-automation) # Turn on in-flow classification Source: https://momentic.ai/docs/guides/auto-heal/in-flow-classification Classify failures during the run itself, so every failed run carries a category, reasoning, and a triage action by the time the CLI exits. In-flow classification runs the classification agent inside `momentic run`, at the moment a run exhausts its retries. The CLI includes a category, reasoning, and triage action when the run exits, so CI does not need a separate classification step. Prefer this over invoking [`momentic ai classify`](/docs/cli-reference/momentic/commands/ai#classify) afterwards. ## Enable it Turn it on in `momentic.config.yaml`: ```yaml momentic.config.yaml theme={null} ai: classification: true ``` The toggle is versioned with your tests and applies to local and CI runs. See the [AI configuration reference](/docs/configuration/ai#ai-classification) for every field. ## What happens on a failure When a run fails after all retries, the CLI shows a `Classifying failure` step and the agent inspects the failed step, screenshots, error details, evidence from past runs, and git context when available. The verdict is written into the run's results: * The category, reasoning, confidence, and recoverability appear in the CLI output and in the run viewer's failure details. * The category's configured action (**heal**, **warn**, or **fail**) is attached to the run, so downstream steps such as [`momentic ai triage`](/docs/reliability/auto-maintenance#permanent-healing) and [`momentic results check`](/docs/cli-reference/momentic/commands/results) can act on it without re-classifying. * With [transient failure recovery](/docs/reliability/auto-maintenance#failure-recovery) enabled, a failure the classifier judges one-time recoverable triggers an in-run recovery attempt guided by its reasoning. Failure categories, their actions, and the optional custom prompt stay cloud-managed in [Settings > Classification](https://app.momentic.ai/settings/classification). ## Let the verdict gate CI By default the classifier only records a category: every failed test still fails CI. Set `overrideExitCode: true` so failures routed to **heal** or **warn** exit `0`, keeping the job passing while the failure is repaired or reported. Failures routed to **fail** (for example `BUG`) still exit `1`. ```yaml momentic.config.yaml theme={null} ai: classification: enabled: true overrideExitCode: true ``` To opt in for a single invocation instead, pass [`--classify-override-exit-code`](/docs/cli-reference/momentic/commands/run) to `momentic run`. To skip classification for one invocation, pass `--no-classify`. ## In-flow vs `momentic ai classify` `momentic ai classify` runs the same agent as a separate command against already-finished runs. Prefer the config-driven in-flow setup for CI: * No extra CI step, API round trip, or run selector to wire up; the verdict is part of the run result the moment `momentic run` exits. * The exit-code override can only be applied while the run is still deciding its exit code, so `overrideExitCode` works only in-flow. * Verdicts are saved automatically; `ai classify` persists only with `--save`. Reach for `ai classify` when you want to re-classify a past run, classify runs from an older CLI version, batch-classify a run group or commit, or ask follow-up questions with `--interactive`. # Run tests against multiple inputs Source: https://momentic.ai/docs/guides/data-driven-tests/parametrized-runs Parameterize a test and drive it from a CSV to run the same flow against different data. Run one test against many sets of inputs (login matrices, pricing tiers, locale variations) by declaring parameters and feeding them from a CSV, so you maintain a single flow instead of one test per case. ## 1. Declare parameters Add a `parameters` key to your test file. Parameters become available as `env.` inside steps. ```yaml inputs-test.test.yaml theme={null} fileType: momentic/test/v2 id: amber-forest-kite parameters: - name: USERNAME required: true - name: PASSWORD required: true steps: - javascript: assert(env.USERNAME.length > 0) ``` Each entry is `{ name, required?, default?: { string } }`. Add a `default` when the test should run without the parameter supplied: ```yaml theme={null} parameters: - name: TENANT default: string: acme ``` ## 2. Create a CSV The first row is the header (parameter names). Each subsequent row is one run. ```csv inputs.csv theme={null} USERNAME,PASSWORD alice@example.com,hunter2 bob@example.com,correcthorse ``` ## 3. Run it ```bash theme={null} npx momentic run --input-csv inputs.csv inputs-test.test.yaml ``` Momentic runs the test once per CSV row, substituting the column values into `env`. ## Related * [Variables](/docs/core-concepts/variables) * [`momentic run`](/docs/cli-reference/momentic/commands/run) # Download files Source: https://momentic.ai/docs/guides/page-interactions/download-files Wait for a file download triggered by a **Click** step and optionally save the URL for later use. Capture a file your app downloads when a step clicks a button or link, and optionally save its URL to reuse later in the test (for example, to feed into an upload step). ## Setup 1. Add a **Click** step on the button/link that triggers the download. 2. Enable **Wait for download** on that step. 3. (Optional) Set **Save to environment variable** to capture the file URL (e.g. `DOWNLOADED_FILE`). You can then pass `file://{{ env.DOWNLOADED_FILE }}` to a later [upload step](/docs/guides/page-interactions/upload-files). ## Limits * One file per **Click** step. * Download timeout: 10 seconds. * Maximum file size: 50MB. * Downloads are deleted after each session or after 15 minutes. * Direct file manipulation (reading contents, checking format) is not supported. ## Related * [Upload files](/docs/guides/page-interactions/upload-files) # Select options from a dropdown Source: https://momentic.ai/docs/guides/page-interactions/dropdowns Use **Select** for native `` or a custom menu (e.g. Headless UI, Radix, shadcn). The approach differs. ## Native `` dropdown. | | [`type`](/docs/reference/commands/type) | Type text into an input, optionally clearing and submitting. | ## Form | Command | Summary | | ---------------------------------------------------- | ----------------------------------------------------- | | [`fileUpload`](/docs/reference/commands/file-upload) | Attach a file to the next file picker the page opens. | ## Scroll | Command | Summary | | ------------------------------------------------------ | ------------------------------------- | | [`scrollDown`](/docs/reference/commands/scroll-down) | Scroll the page or a container down. | | [`scrollLeft`](/docs/reference/commands/scroll-left) | Scroll the page or a container left. | | [`scrollRight`](/docs/reference/commands/scroll-right) | Scroll the page or a container right. | | [`scrollUp`](/docs/reference/commands/scroll-up) | Scroll the page or a container up. | ## Navigation | Command | Summary | | -------------------------------------------------- | ------------------------------------------------------------ | | [`closeTab`](/docs/reference/commands/close-tab) | Close the active tab or a matching tab. | | [`goBack`](/docs/reference/commands/go-back) | Navigate back in the browser history. | | [`goForward`](/docs/reference/commands/go-forward) | Navigate forward in the browser history. | | [`navigate`](/docs/reference/commands/navigate) | Navigate the current tab to a URL. | | [`newTab`](/docs/reference/commands/new-tab) | Open a URL in a new tab and switch to it. | | [`refresh`](/docs/reference/commands/refresh) | Reload the current page. | | [`switchTab`](/docs/reference/commands/switch-tab) | Switch the active tab by index, URL substring, or URL regex. | ## Waits | Command | Summary | | ---------------------------------------------------------------------------- | --------------------------------------------------------------------------- | | [`wait`](/docs/reference/commands/wait) | Pause execution for a fixed duration in milliseconds. | | [`waitForUrl`](/docs/reference/commands/wait-for-url) | Wait until the page URL matches a substring, glob, regex, or domain. | | [`waitForUrlNotToMatch`](/docs/reference/commands/wait-for-url-not-to-match) | Wait until the page URL stops matching a substring, glob, regex, or domain. | ## Page checks | Command | Summary | | --------------------------------------------------------------------------------- | --------------------------------------------------------------- | | [`checkPageContains`](/docs/reference/commands/check-page-contains) | Assert that the visible page text contains a substring. | | [`checkPageDoesNotContain`](/docs/reference/commands/check-page-does-not-contain) | Assert that the visible page text does NOT contain a substring. | ## Element checks | Command | Summary | | --------------------------------------------------------------------------- | ----------------------------------------------------------------------- | | [`checkElement`](/docs/reference/commands/check-element) | Element-level assertion family for the element itself. | | [`checkElementAttribute`](/docs/reference/commands/check-element-attribute) | Element-level assertion family for an HTML attribute on the element. | | [`checkElementContent`](/docs/reference/commands/check-element-content) | Element-level assertion family for the element's text content. | | [`checkElementName`](/docs/reference/commands/check-element-name) | Element-level assertion family for the element's tag name. | | [`checkElementStyle`](/docs/reference/commands/check-element-style) | Element-level assertion family for a computed CSS style on the element. | ## Network | Command | Summary | | ------------------------------------------------------------------------------- | ---------------------------------------------------------------- | | [`awaitListener`](/docs/reference/commands/await-listener) | Block until a previously registered listener captures a request. | | [`getRecordedRequests`](/docs/reference/commands/get-recorded-requests) | Retrieve the list of requests captured by `recordRequests`. | | [`graphqlRequest`](/docs/reference/commands/graphql-request) | Make a server-side GraphQL request and capture the response. | | [`header`](/docs/reference/commands/header) | Set an HTTP request header on outgoing requests. | | [`mock`](/docs/reference/commands/mock) | Intercept a network route and return a custom response. | | [`recordRequests`](/docs/reference/commands/record-requests) | Start recording every request that matches a URL pattern. | | [`registerRequestListener`](/docs/reference/commands/register-request-listener) | Start listening for requests that match a URL pattern. | | [`removeRouteMock`](/docs/reference/commands/remove-route-mock) | Remove a previously installed route mock by key. | | [`request`](/docs/reference/commands/request) | Make an out-of-band HTTP request and capture the response. | ## Storage | Command | Summary | | -------------------------------------------------------- | -------------------------------------------------- | | [`cookie`](/docs/reference/commands/cookie) | Set a browser cookie via a `name=value` string. | | [`localStorage`](/docs/reference/commands/local-storage) | Write a key/value pair into `window.localStorage`. | ## Authentication | Command | Summary | | ------------------------------------------------ | ----------------------------------------------------------------------- | | [`authLoad`](/docs/reference/commands/auth-load) | Restore browser auth state from a Playwright storage-state file. | | [`authSave`](/docs/reference/commands/auth-save) | Save the current browser auth state to a Playwright storage-state file. | ## Visual | Command | Summary | | ---------------------------------------------------- | --------------------------------------------------------------- | | [`captcha`](/docs/reference/commands/captcha) | Solve a captcha challenge on the current page. | | [`dialog`](/docs/reference/commands/dialog) | Auto-handle the next browser dialog (alert/confirm/prompt). | | [`visualDiff`](/docs/reference/commands/visual-diff) | Compare a viewport or element screenshot against a golden file. | ## Connectivity | Command | Summary | | --------------------------------------------- | ----------------------------------------- | | [`offline`](/docs/reference/commands/offline) | Put the browser into offline mode. | | [`online`](/docs/reference/commands/online) | Restore the browser's network connection. | ## Scripts | Command | Summary | | --------------------------------------------------- | ------------------------------------------------- | | [`javascript`](/docs/reference/commands/javascript) | Run arbitrary JavaScript inside the test runtime. | ## Control flow | Command | Summary | | ------------------------------------------- | ------------------------------------------------- | | [`if`](/docs/reference/commands/if) | Run a block of steps only when a condition holds. | | [`module`](/docs/reference/commands/module) | Invoke a reusable module of steps. | ## Bare commands These commands can be written as single-key scalars without an object payload: * [`authSave`](/docs/reference/commands/auth-save) * [`blur`](/docs/reference/commands/blur) * [`captcha`](/docs/reference/commands/captcha) * [`closeTab`](/docs/reference/commands/close-tab) * [`goBack`](/docs/reference/commands/go-back) * [`goForward`](/docs/reference/commands/go-forward) * [`offline`](/docs/reference/commands/offline) * [`online`](/docs/reference/commands/online) * [`paste`](/docs/reference/commands/paste) * [`refresh`](/docs/reference/commands/refresh) * [`visualDiff`](/docs/reference/commands/visual-diff) # javascript Source: https://momentic.ai/docs/reference/commands/javascript Run arbitrary JavaScript inside the test runtime. The simplified form takes a single string of JavaScript. Use `code` for multi-line scripts. Variables on `env` are available without templating: `env.MY_VAR` rather than `{{ env.MY_VAR }}`. ## Parameters | Parameter | Type | Required | Description | | ------------- | --------------------- | -------- | --------------------------------------------------------------------- | | `code` | `string` | Yes | JavaScript source. | | `environment` | `"node" \| "browser"` | No | Where to run the script. Defaults to `node`. | | `fragment` | `boolean` | No | Treat `code` as a fragment (no implicit `return`). | | `timeout` | `number` | No | Maximum time in milliseconds. | | `saveAs` | `string` | No | Name of the variable to write this step's return value to. | | `retries` | `number` | No | Number of times to retry the step on failure before failing the test. | | `skipped` | `boolean` | No | Skip this step at execution time. | ## Shorthand JavaScript expression as a single string. `env.NAME` refers to a variable directly. Do not wrap it in `{{ }}`. ```yaml theme={null} - javascript: setVariable('USERNAME', 'testuser') ``` ## Examples ```yaml theme={null} - javascript: code: return faker.person.fullName() saveAs: NAME # available later as env.NAME ``` ```yaml theme={null} - javascript: code: return `random-module-name-${Date.now()}` saveAs: MODULE_NAME ``` ```yaml theme={null} - javascript: code: |- assert(env.TODOS.length === 3) for (const todo of env.TODOS) { assert("request" in todo) assert("response" in todo) } ``` ```yaml theme={null} - javascript: code: |- const permission = await navigator.permissions.query({ name: 'camera' }) if (permission.state !== "granted") { throw new Error(`Expected camera permission, got ${permission.state}`) } environment: browser # run in the page context instead of node ``` ## Related * [Javascript](/docs/integrations/javascript) * [Variables](/docs/core-concepts/variables) * [Steps](/docs/core-concepts/steps) # keyDown Source: https://momentic.ai/docs/reference/commands/key-down Press a key down without releasing it. Pair with `keyUp` for chorded interactions that span multiple steps. ## Parameters | Parameter | Type | Required | Description | | ------------- | --------- | -------- | --------------------------------------------------------------------- | | `key` | `string` | Yes | Key name. | | `convertMeta` | `boolean` | No | Translate `Meta` to `Control` on non-mac platforms. | | `saveAs` | `string` | No | Name of the variable to write this step's return value to. | | `retries` | `number` | No | Number of times to retry the step on failure before failing the test. | | `skipped` | `boolean` | No | Skip this step at execution time. | ## Shorthand Key name as a single string. ```yaml theme={null} - keyDown: Shift ``` ## Examples ```yaml theme={null} - keyDown: key: Shift+Control ``` ```yaml theme={null} - keyDown: key: Tab convertMeta: true ``` ## Related * [Steps](/docs/core-concepts/steps) # keyUp Source: https://momentic.ai/docs/reference/commands/key-up Release a previously pressed key. Use after `keyDown` to release the held key. ## Parameters | Parameter | Type | Required | Description | | ------------- | --------- | -------- | --------------------------------------------------------------------- | | `key` | `string` | Yes | Key name. | | `convertMeta` | `boolean` | No | Translate `Meta` to `Control` on non-mac platforms. | | `saveAs` | `string` | No | Name of the variable to write this step's return value to. | | `retries` | `number` | No | Number of times to retry the step on failure before failing the test. | | `skipped` | `boolean` | No | Skip this step at execution time. | ## Shorthand Key name as a single string. ```yaml theme={null} - keyUp: Shift ``` ## Examples ```yaml theme={null} - keyUp: key: Shift ``` ## Related * [Steps](/docs/core-concepts/steps) # localStorage Source: https://momentic.ai/docs/reference/commands/local-storage Write a key/value pair into `window.localStorage`. Sets the value before the next step runs. Useful for seeding the page with feature flags, onboarding state, or auth tokens that the app reads from `localStorage`. ## Parameters | Parameter | Type | Required | Description | | --------- | --------- | -------- | --------------------------------------------------------------------- | | `key` | `string` | Yes | `localStorage` key. | | `value` | `string` | Yes | `localStorage` value. | | `saveAs` | `string` | No | Name of the variable to write this step's return value to. | | `retries` | `number` | No | Number of times to retry the step on failure before failing the test. | | `skipped` | `boolean` | No | Skip this step at execution time. | ## Examples ```yaml theme={null} - localStorage: key: momenticTestKey2 value: momenticTestValue3 ``` ```yaml theme={null} - localStorage: key: featureFlags value: '{"newCheckout":true}' ``` ## Related * [Steps](/docs/core-concepts/steps) # mock Source: https://momentic.ai/docs/reference/commands/mock Intercept a network route and return a custom response. Requires exactly one URL matcher. `responseGenerator` is a JavaScript function body evaluated for every match. It receives the captured `mock.request` (and `mock.response` when `fetchOriginalResponse` is set) and returns the response body. ## Parameters | Parameter | Type | Required | Description | | ----------------------- | --------- | -------- | --------------------------------------------------------------------- | | `substring` | `string` | No | Match URLs that contain this substring. | | `glob` | `string` | No | Match URLs against a glob pattern. | | `regex` | `string` | No | Match URLs against a regular expression. | | `domain` | `string` | No | Match all URLs under the given domain. | | `method` | `string` | No | Restrict mocking to a specific HTTP method. | | `responseGenerator` | `string` | Yes | JavaScript expression that returns the response body. | | `fetchOriginalResponse` | `boolean` | No | Make the real request first and pass the response to the generator. | | `key` | `string` | No | Stable key for `removeRouteMock`. | | `saveAs` | `string` | No | Name of the variable to write this step's return value to. | | `retries` | `number` | No | Number of times to retry the step on failure before failing the test. | | `skipped` | `boolean` | No | Skip this step at execution time. | ## Examples ```yaml theme={null} - mock: substring: /todos method: get responseGenerator: |- return new Response( JSON.stringify([ { id: 1, title: "mocked" }, ]), { status: 200, headers: { "content-type": "application/json" } } ) fetchOriginalResponse: false key: TODOS_MOCK ``` ```yaml theme={null} - mock: domain: setcookie.net fetchOriginalResponse: true responseGenerator: |- mock.response.headers.set("Set-Cookie", "sessionId=a3fWa") return mock.response ``` ## Related * [Request mocking](/docs/platforms/web/request-mocking) * [Steps](/docs/core-concepts/steps) # module Source: https://momentic.ai/docs/reference/commands/module Invoke a reusable module of steps. Module paths resolve relative to the YAML file that contains the step. Inputs override the module's `defaultParameters` for this invocation. Inputs accept three shapes: raw JavaScript expressions (the default), `{ string: ... }` for explicit literals, and `{ javascript: ... }` for explicit expressions. ## Parameters | Parameter | Type | Required | Description | | --------- | -------------------------------------------------------- | -------- | --------------------------------------------------------------------- | | `path` | `string` | Yes | Path to the `.module.yaml` file, relative to the current file. | | `inputs` | `Record` | No | Inputs to pass to the module's parameters. | | `saveAs` | `string` | No | Name of the variable to write this step's return value to. | | `retries` | `number` | No | Number of times to retry the step on failure before failing the test. | | `skipped` | `boolean` | No | Skip this step at execution time. | ## Shorthand Module path as a single string. Use when the module needs no inputs. ```yaml theme={null} - module: ./create-local-mobile-test.module.yaml ``` ## Examples ```yaml theme={null} - module: inputs: url: javascript: "'https://www.ycombinator.com'" path: ../modules/create-ci-test-with-url.module.yaml ``` ```yaml theme={null} - module: inputs: TEST_NAME: javascript: env.CREATED_TEST_NAME NEW_TEST_BASE_URL: string: https://storage.googleapis.com/staging-test-sites/neverssl.html NEW_TEST_NAME: javascript: env.CREATED_TEST_NAME path: ./fill-new-browser-test-form.module.yaml ``` ```yaml theme={null} - module: inputs: STEP_TYPE: string: ELEMENT CHECK path: ./add-step-to-end.module.yaml ``` ## Notes Module paths must not start with `file://`. Use a plain relative path. Inputs accept three shapes: a raw value (interpreted as a JavaScript expression, e.g. `env.QA_EMAIL`), `{ string: "literal" }`, or `{ javascript: "expr" }`. ## Related * [Modules](/docs/core-concepts/modules) * [Variables](/docs/core-concepts/variables) * [Steps](/docs/core-concepts/steps) # mouseDrag Source: https://momentic.ai/docs/reference/commands/mouse-drag Drag the mouse a relative delta from an origin. Lower-level companion to `dragAndDrop`. Specify an origin (default: the current pointer position) and a relative `delta` in pixels. ## Parameters | Parameter | Type | Required | Description | | --------- | -------------------- | -------- | ----------------------------------------------------------------------------------------------- | | `delta` | `string \| { x, y }` | Yes | Relative pixel delta from the origin. Either `x, y` string or `{ x, y }` object. | | `from` | `string` | No | Description of the origin element. | | `css` | `string` | No | CSS selector for the target. Use instead of the description key. | | `coords` | `string \| { x, y }` | No | Absolute viewport coordinates. Either an `x, y` string (e.g. `120, 40`) or a `{ x, y }` object. | | `x` | `number \| string` | No | X coordinate. Must be provided together with `y`. | | `y` | `number \| string` | No | Y coordinate. Must be provided together with `x`. | | `force` | `boolean` | No | Force the action even when the element is not actionable. | | `iframe` | `string` | No | URL or URL pattern of the iframe that contains the target element. | | `steps` | `number` | No | Number of mouse-move steps to interpolate. | | `saveAs` | `string` | No | Name of the variable to write this step's return value to. | | `retries` | `number` | No | Number of times to retry the step on failure before failing the test. | | `skipped` | `boolean` | No | Skip this step at execution time. | ## Shorthand `delta` as `x, y` from the current pointer position. ```yaml theme={null} - mouseDrag: 200, 0 ``` ## Examples ```yaml theme={null} - mouseDrag: delta: x: 11 y: 22 ``` ```yaml theme={null} - mouseDrag: from: the slider thumb delta: 200, 0 steps: 20 ``` ## Related * [Finding elements](/docs/core-concepts/finding-elements) * [Steps](/docs/core-concepts/steps) # navigate Source: https://momentic.ai/docs/reference/commands/navigate Navigate the current tab to a URL. URLs can be absolute or relative. Relative URLs resolve against the project's base URL. ## Parameters | Parameter | Type | Required | Description | | --------- | --------- | -------- | --------------------------------------------------------------------- | | `url` | `string` | Yes | Destination URL. | | `timeout` | `number` | No | Maximum navigation time in milliseconds. | | `saveAs` | `string` | No | Name of the variable to write this step's return value to. | | `retries` | `number` | No | Number of times to retry the step on failure before failing the test. | | `skipped` | `boolean` | No | Skip this step at execution time. | ## Shorthand URL as a single string. ```yaml theme={null} - navigate: http://localhost:4173/practice-ai-action-library ``` ## Examples ```yaml theme={null} - navigate: url: http://localhost:3000/tests timeout: 60000 ``` ```yaml theme={null} - navigate: url: https://www.ycombinator.com/apply timeout: 15000 ``` ## Related * [Steps](/docs/core-concepts/steps) # newTab Source: https://momentic.ai/docs/reference/commands/new-tab Open a URL in a new tab and switch to it. Opens the URL in a new tab in the same browser context and makes that tab active for subsequent steps. ## Parameters | Parameter | Type | Required | Description | | --------- | --------- | -------- | --------------------------------------------------------------------- | | `url` | `string` | Yes | URL to load in the new tab. | | `timeout` | `number` | No | Maximum navigation time in milliseconds. | | `saveAs` | `string` | No | Name of the variable to write this step's return value to. | | `retries` | `number` | No | Number of times to retry the step on failure before failing the test. | | `skipped` | `boolean` | No | Skip this step at execution time. | ## Shorthand URL as a single string. ```yaml theme={null} - newTab: https://news.ycombinator.com ``` ## Examples ```yaml theme={null} - newTab: url: http://localhost:4173/practice-tab-search timeout: 30000 ``` ```yaml theme={null} - newTab: url: https://www.salesforce.com/ ``` ## Related * [Steps](/docs/core-concepts/steps) # offline Source: https://momentic.ai/docs/reference/commands/offline Put the browser into offline mode. Drops the browser context's network connectivity until `online` is called. The bare scalar `- offline` is equivalent to `- offline: {}`. ## Parameters | Parameter | Type | Required | Description | | --------- | --------- | -------- | --------------------------------------------------------------------- | | `saveAs` | `string` | No | Name of the variable to write this step's return value to. | | `retries` | `number` | No | Number of times to retry the step on failure before failing the test. | | `skipped` | `boolean` | No | Skip this step at execution time. | ## Shorthand Bare command. ```yaml theme={null} - offline ``` ## Examples ```yaml theme={null} - offline: {} ``` ## Related * [Steps](/docs/core-concepts/steps) # online Source: https://momentic.ai/docs/reference/commands/online Restore the browser's network connection. Re-enables network for the browser context after a prior `offline`. The bare scalar `- online` is equivalent to `- online: {}`. ## Parameters | Parameter | Type | Required | Description | | --------- | --------- | -------- | --------------------------------------------------------------------- | | `saveAs` | `string` | No | Name of the variable to write this step's return value to. | | `retries` | `number` | No | Number of times to retry the step on failure before failing the test. | | `skipped` | `boolean` | No | Skip this step at execution time. | ## Shorthand Bare command. ```yaml theme={null} - online ``` ## Examples ```yaml theme={null} - online: {} ``` ## Related * [Steps](/docs/core-concepts/steps) # paste Source: https://momentic.ai/docs/reference/commands/paste Paste the current clipboard contents. Pairs with `copy`. The bare scalar `- paste` is equivalent to `- paste: {}`. ## Parameters | Parameter | Type | Required | Description | | --------- | --------- | -------- | --------------------------------------------------------------------- | | `saveAs` | `string` | No | Name of the variable to write this step's return value to. | | `retries` | `number` | No | Number of times to retry the step on failure before failing the test. | | `skipped` | `boolean` | No | Skip this step at execution time. | ## Shorthand Bare command. ```yaml theme={null} - paste ``` ## Examples ```yaml theme={null} - paste: {} ``` ## Related * [Steps](/docs/core-concepts/steps) # press Source: https://momentic.ai/docs/reference/commands/press Press a key or key combination. Issues a single key press. Use `+` to combine modifiers, e.g. `Meta+Enter`, `Control+Shift+P`. ## Parameters | Parameter | Type | Required | Description | | ------------- | --------- | -------- | --------------------------------------------------------------------- | | `key` | `string` | Yes | Key name or chord (e.g. `Enter`, `Meta+Enter`). | | `repeat` | `number` | No | Number of times to repeat the press. | | `delay` | `number` | No | Milliseconds between key down and key up. | | `convertMeta` | `boolean` | No | Translate `Meta` to `Control` on non-mac platforms. | | `saveAs` | `string` | No | Name of the variable to write this step's return value to. | | `retries` | `number` | No | Number of times to retry the step on failure before failing the test. | | `skipped` | `boolean` | No | Skip this step at execution time. | ## Shorthand Key name as a single string. ```yaml theme={null} - press: Enter ``` ## Examples ```yaml theme={null} - press: key: Meta+Shift+Enter ``` ```yaml theme={null} - press: key: Control+Shift+Enter convertMeta: true ``` ```yaml theme={null} - press: key: ArrowDown repeat: 3 ``` ## Related * [Steps](/docs/core-concepts/steps) # recordRequests Source: https://momentic.ai/docs/reference/commands/record-requests Start recording every request that matches a URL pattern. Pair with `getRecordedRequests` to retrieve the recorded list later. Unlike `registerRequestListener`, multiple matches are kept. ## Parameters | Parameter | Type | Required | Description | | ----------- | --------- | -------- | --------------------------------------------------------------------- | | `substring` | `string` | No | Match URLs that contain this substring. | | `glob` | `string` | No | Match URLs against a glob pattern. | | `regex` | `string` | No | Match URLs against a regular expression. | | `domain` | `string` | No | Match all URLs under the given domain. | | `key` | `string` | Yes | Identifier used by `getRecordedRequests`. | | `method` | `string` | No | Restrict the recorder to a specific HTTP method. | | `saveAs` | `string` | No | Name of the variable to write this step's return value to. | | `retries` | `number` | No | Number of times to retry the step on failure before failing the test. | | `skipped` | `boolean` | No | Skip this step at execution time. | ## Examples ```yaml theme={null} - recordRequests: key: todos regex: .*/todos.* ``` ```yaml theme={null} - recordRequests: key: requests regex: .+jsonplaceholder.+ ``` ## Related * [Network requests](/docs/guides/page-interactions/network-requests) * [Steps](/docs/core-concepts/steps) # refresh Source: https://momentic.ai/docs/reference/commands/refresh Reload the current page. Equivalent to pressing the browser's reload button. ## Parameters | Parameter | Type | Required | Description | | --------- | --------- | -------- | --------------------------------------------------------------------- | | `timeout` | `number` | No | Maximum reload time in milliseconds. | | `saveAs` | `string` | No | Name of the variable to write this step's return value to. | | `retries` | `number` | No | Number of times to retry the step on failure before failing the test. | | `skipped` | `boolean` | No | Skip this step at execution time. | ## Shorthand Bare command. ```yaml theme={null} - refresh ``` ## Examples ```yaml theme={null} - refresh: timeout: 30000 ``` ## Related * [Steps](/docs/core-concepts/steps) # registerRequestListener Source: https://momentic.ai/docs/reference/commands/register-request-listener Start listening for requests that match a URL pattern. Begins capturing the first request that matches. Pair with `awaitListener` to read the captured request/response in a later step. ## Parameters | Parameter | Type | Required | Description | | ----------- | --------- | -------- | --------------------------------------------------------------------- | | `substring` | `string` | No | Match URLs that contain this substring. | | `glob` | `string` | No | Match URLs against a glob pattern. | | `regex` | `string` | No | Match URLs against a regular expression. | | `domain` | `string` | No | Match all URLs under the given domain. | | `key` | `string` | Yes | Identifier used by `awaitListener` to pick up the captured request. | | `method` | `string` | No | Restrict the listener to a specific HTTP method. | | `saveAs` | `string` | No | Name of the variable to write this step's return value to. | | `retries` | `number` | No | Number of times to retry the step on failure before failing the test. | | `skipped` | `boolean` | No | Skip this step at execution time. | ## Examples ```yaml theme={null} - registerRequestListener: key: response regex: .+jsonplaceholder.+ ``` ```yaml theme={null} - registerRequestListener: key: create_test substring: /api/tests method: post ``` ## Related * [Network requests](/docs/guides/page-interactions/network-requests) * [Steps](/docs/core-concepts/steps) # removeRouteMock Source: https://momentic.ai/docs/reference/commands/remove-route-mock Remove a previously installed route mock by key. Pair with the `saveAs` key set on the corresponding `mock` step. Omit `key` to remove every route mock currently installed. ## Parameters | Parameter | Type | Required | Description | | --------- | --------- | -------- | --------------------------------------------------------------------- | | `key` | `string` | No | Key set on the corresponding `mock` step. Omit to remove all mocks. | | `saveAs` | `string` | No | Name of the variable to write this step's return value to. | | `retries` | `number` | No | Number of times to retry the step on failure before failing the test. | | `skipped` | `boolean` | No | Skip this step at execution time. | ## Shorthand Key as a single string. ```yaml theme={null} - removeRouteMock: TODOS_MOCK ``` ## Examples ```yaml theme={null} - removeRouteMock: key: TODOS_MOCK ``` Remove every installed route mock at once: ```yaml theme={null} - removeRouteMock: {} ``` ## Related * [Request mocking](/docs/platforms/web/request-mocking) * [Steps](/docs/core-concepts/steps) # request Source: https://momentic.ai/docs/reference/commands/request Make an out-of-band HTTP request and capture the response. Runs server-side without going through the browser. Combine with `saveAs` to feed the response into later steps. ## Parameters | Parameter | Type | Required | Description | | --------- | ------------------------ | -------- | --------------------------------------------------------------------- | | `url` | `string` | Yes | Request URL. | | `method` | `string` | No | HTTP method. Defaults to GET. | | `headers` | `Record` | No | Request headers. | | `params` | `Record` | No | Query parameters. | | `body` | `unknown` | No | Request body. | | `timeout` | `number` | No | Maximum time in milliseconds. | | `saveAs` | `string` | No | Name of the variable to write this step's return value to. | | `retries` | `number` | No | Number of times to retry the step on failure before failing the test. | | `skipped` | `boolean` | No | Skip this step at execution time. | ## Shorthand URL as a single string. Defaults to GET. ```yaml theme={null} - request: https://postman-echo.com/get ``` ## Examples ```yaml theme={null} - request: url: https://postman-echo.com/get headers: test-header: header {{ env.TEST_VALUE }} params: test-param: param {{ env.TEST_VALUE }} saveAs: GET_REQUEST ``` ```yaml theme={null} - request: url: https://postman-echo.com/post method: POST headers: test-header: header {{ env.TEST_VALUE }} params: test-param: param {{ env.TEST_VALUE }} body: payload: "{{ env.TEST_VALUE }}" saveAs: POST_REQUEST ``` ## Related * [Network requests](/docs/guides/page-interactions/network-requests) * [Steps](/docs/core-concepts/steps) # rightClick Source: https://momentic.ai/docs/reference/commands/right-click Right-click an element to open a context menu. Same target rules as `click`. Equivalent to `click` with `rightClick: true`. ## Parameters | Parameter | Type | Required | Description | | ----------------- | -------------------- | -------- | ----------------------------------------------------------------------------------------------- | | `on` | `string` | No | Natural-language description of the click target. | | `css` | `string` | No | CSS selector for the target. Use instead of the description key. | | `coords` | `string \| { x, y }` | No | Absolute viewport coordinates. Either an `x, y` string (e.g. `120, 40`) or a `{ x, y }` object. | | `x` | `number \| string` | No | X coordinate. Must be provided together with `y`. | | `y` | `number \| string` | No | Y coordinate. Must be provided together with `x`. | | `force` | `boolean` | No | Force the action even when the element is not actionable. | | `iframe` | `string` | No | URL or URL pattern of the iframe that contains the target element. | | `offset` | `string \| { x, y }` | No | Pixel offset from the resolved target. Either an `x, y` string or a `{ x, y }` object. | | `times` | `number` | No | Number of times to click. | | `waitForDownload` | `boolean` | No | Wait for a download to start after the click. | | `delay` | `number` | No | Milliseconds between mousedown and mouseup. | | `downloadTimeout` | `number` | No | Max time in milliseconds to wait for a download. | | `saveAs` | `string` | No | Name of the variable to write this step's return value to. | | `retries` | `number` | No | Number of times to retry the step on failure before failing the test. | | `skipped` | `boolean` | No | Skip this step at execution time. | ## Shorthand Target description as a single string. ```yaml theme={null} - rightClick: right click target ``` ## Examples ```yaml theme={null} - rightClick: on: the javascript step card with the "await" code ``` ```yaml theme={null} - rightClick: css: '[data-test-id="row-action-menu"]' ``` ## Related * [Finding elements](/docs/core-concepts/finding-elements) * [Steps](/docs/core-concepts/steps) # scrollDown Source: https://momentic.ai/docs/reference/commands/scroll-down Scroll the page or a container down. Scrolls the viewport (or the container described by `in`) down by `pixels` pixels. Without `pixels`, scrolls one viewport. The simplified scalar form is the pixel count. ## Parameters | Parameter | Type | Required | Description | | --------- | -------------------- | -------- | ----------------------------------------------------------------------------------------------- | | `pixels` | `number` | No | Pixels to scroll. Defaults to a full viewport when omitted. | | `in` | `string` | No | Description of the scroll container. Defaults to the page when omitted. | | `css` | `string` | No | CSS selector for the target. Use instead of the description key. | | `coords` | `string \| { x, y }` | No | Absolute viewport coordinates. Either an `x, y` string (e.g. `120, 40`) or a `{ x, y }` object. | | `x` | `number \| string` | No | X coordinate. Must be provided together with `y`. | | `y` | `number \| string` | No | Y coordinate. Must be provided together with `x`. | | `force` | `boolean` | No | Force the action even when the element is not actionable. | | `iframe` | `string` | No | URL or URL pattern of the iframe that contains the target element. | | `saveAs` | `string` | No | Name of the variable to write this step's return value to. | | `retries` | `number` | No | Number of times to retry the step on failure before failing the test. | | `skipped` | `boolean` | No | Skip this step at execution time. | ## Shorthand Pixels as a non-negative number. ```yaml theme={null} - scrollDown: 500 ``` ## Examples ```yaml theme={null} - scrollDown: 650 ``` ```yaml theme={null} - scrollDown: 1250 ``` ```yaml theme={null} - scrollDown: pixels: 900 in: Results panel ``` ## Related * [Steps](/docs/core-concepts/steps) # scrollLeft Source: https://momentic.ai/docs/reference/commands/scroll-left Scroll the page or a container left. Scrolls the viewport (or the container described by `in`) left by `pixels` pixels. Without `pixels`, scrolls one viewport. The simplified scalar form is the pixel count. ## Parameters | Parameter | Type | Required | Description | | --------- | -------------------- | -------- | ----------------------------------------------------------------------------------------------- | | `pixels` | `number` | No | Pixels to scroll. Defaults to a full viewport when omitted. | | `in` | `string` | No | Description of the scroll container. Defaults to the page when omitted. | | `css` | `string` | No | CSS selector for the target. Use instead of the description key. | | `coords` | `string \| { x, y }` | No | Absolute viewport coordinates. Either an `x, y` string (e.g. `120, 40`) or a `{ x, y }` object. | | `x` | `number \| string` | No | X coordinate. Must be provided together with `y`. | | `y` | `number \| string` | No | Y coordinate. Must be provided together with `x`. | | `force` | `boolean` | No | Force the action even when the element is not actionable. | | `iframe` | `string` | No | URL or URL pattern of the iframe that contains the target element. | | `saveAs` | `string` | No | Name of the variable to write this step's return value to. | | `retries` | `number` | No | Number of times to retry the step on failure before failing the test. | | `skipped` | `boolean` | No | Skip this step at execution time. | ## Shorthand Pixels as a non-negative number. ```yaml theme={null} - scrollLeft: 500 ``` ## Examples ```yaml theme={null} - scrollLeft: 300 ``` ```yaml theme={null} - scrollLeft: pixels: 500 in: the horizontal timeline ``` ## Related * [Steps](/docs/core-concepts/steps) # scrollRight Source: https://momentic.ai/docs/reference/commands/scroll-right Scroll the page or a container right. Scrolls the viewport (or the container described by `in`) right by `pixels` pixels. Without `pixels`, scrolls one viewport. The simplified scalar form is the pixel count. ## Parameters | Parameter | Type | Required | Description | | --------- | -------------------- | -------- | ----------------------------------------------------------------------------------------------- | | `pixels` | `number` | No | Pixels to scroll. Defaults to a full viewport when omitted. | | `in` | `string` | No | Description of the scroll container. Defaults to the page when omitted. | | `css` | `string` | No | CSS selector for the target. Use instead of the description key. | | `coords` | `string \| { x, y }` | No | Absolute viewport coordinates. Either an `x, y` string (e.g. `120, 40`) or a `{ x, y }` object. | | `x` | `number \| string` | No | X coordinate. Must be provided together with `y`. | | `y` | `number \| string` | No | Y coordinate. Must be provided together with `x`. | | `force` | `boolean` | No | Force the action even when the element is not actionable. | | `iframe` | `string` | No | URL or URL pattern of the iframe that contains the target element. | | `saveAs` | `string` | No | Name of the variable to write this step's return value to. | | `retries` | `number` | No | Number of times to retry the step on failure before failing the test. | | `skipped` | `boolean` | No | Skip this step at execution time. | ## Shorthand Pixels as a non-negative number. ```yaml theme={null} - scrollRight: 500 ``` ## Examples ```yaml theme={null} - scrollRight: 300 ``` ```yaml theme={null} - scrollRight: pixels: 500 in: the horizontal timeline ``` ## Related * [Steps](/docs/core-concepts/steps) # scrollUp Source: https://momentic.ai/docs/reference/commands/scroll-up Scroll the page or a container up. Scrolls the viewport (or the container described by `in`) up by `pixels` pixels. Without `pixels`, scrolls one viewport. The simplified scalar form is the pixel count. ## Parameters | Parameter | Type | Required | Description | | --------- | -------------------- | -------- | ----------------------------------------------------------------------------------------------- | | `pixels` | `number` | No | Pixels to scroll. Defaults to a full viewport when omitted. | | `in` | `string` | No | Description of the scroll container. Defaults to the page when omitted. | | `css` | `string` | No | CSS selector for the target. Use instead of the description key. | | `coords` | `string \| { x, y }` | No | Absolute viewport coordinates. Either an `x, y` string (e.g. `120, 40`) or a `{ x, y }` object. | | `x` | `number \| string` | No | X coordinate. Must be provided together with `y`. | | `y` | `number \| string` | No | Y coordinate. Must be provided together with `x`. | | `force` | `boolean` | No | Force the action even when the element is not actionable. | | `iframe` | `string` | No | URL or URL pattern of the iframe that contains the target element. | | `saveAs` | `string` | No | Name of the variable to write this step's return value to. | | `retries` | `number` | No | Number of times to retry the step on failure before failing the test. | | `skipped` | `boolean` | No | Skip this step at execution time. | ## Shorthand Pixels as a non-negative number. ```yaml theme={null} - scrollUp: 500 ``` ## Examples ```yaml theme={null} - scrollUp: 100 ``` ```yaml theme={null} - scrollUp: coords: 0, 0 ``` ## Related * [Steps](/docs/core-concepts/steps) # select Source: https://momentic.ai/docs/reference/commands/select Pick an option from a `` element. | | `css` | `string` | No | CSS selector for the target. Use instead of the description key. | | `coords` | `string \| { x, y }` | No | Absolute viewport coordinates. Either an `x, y` string (e.g. `120, 40`) or a `{ x, y }` object. | | `x` | `number \| string` | No | X coordinate. Must be provided together with `y`. | | `y` | `number \| string` | No | Y coordinate. Must be provided together with `x`. | | `force` | `boolean` | No | Force the action even when the element is not actionable. | | `iframe` | `string` | No | URL or URL pattern of the iframe that contains the target element. | | `label` | `string` | No | Visible label of the option to choose. | | `value` | `string` | No | `value` attribute of the option to choose. | | `index` | `number \| string` | No | Zero-based index of the option to choose. | | `saveAs` | `string` | No | Name of the variable to write this step's return value to. | | `retries` | `number` | No | Number of times to retry the step on failure before failing the test. | | `skipped` | `boolean` | No | Skip this step at execution time. | ## Examples ```yaml theme={null} - select: from: The select element labeled "Dropdown:" label: "{{ env.OPTION_LABEL }}" ``` ```yaml theme={null} - select: from: The select element "Dropdown:" value: "{{ env.OPTION_VALUE }}" ``` ```yaml theme={null} - select: from: The "Dropdown:" select element index: "{{ env.OPTION_INDEX }}" ``` ## Related * [Finding elements](/docs/core-concepts/finding-elements) * [Dropdowns](/docs/guides/page-interactions/dropdowns) * [Steps](/docs/core-concepts/steps) # switchTab Source: https://momentic.ai/docs/reference/commands/switch-tab Switch the active tab by index, URL substring, or URL regex. Provide exactly one of `substring`, `regex`, or `index`. The simplified form is a substring (string) or an index (number). ## Parameters | Parameter | Type | Required | Description | | ------------- | ------------------ | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ | | `substring` | `string` | No | Match the URL by substring. | | `regex` | `string` | No | Match the URL by regular expression. | | `index` | `number \| string` | No | Zero-based tab index. | | `timeout` | `number` | No | Maximum milliseconds to keep retrying failed switches. Defaults to `browser.smartWaitingTimeoutMs`. | | `loadTimeout` | `number` | No | Maximum milliseconds for each selected tab load. Defaults to `timeout` for backwards compatibility and never reduces the configured page load timeout. | Both timeout values must be whole seconds expressed in milliseconds, from `0` to `60000`. A switch always gets at least two attempts. `timeout` controls whether further attempts start; it does not reload the target page or cancel an attempt already in progress. Existing steps with only `timeout` keep using it as their load timeout as well, so their serialized form and runtime behavior remain compatible. The effective load timeout is the larger of `loadTimeout` (or its legacy `timeout` fallback) and `browser.pageLoadTimeoutMs`. This lets you use a short retry window to stop looking for a missing tab without also making an existing tab more likely to fail while loading. ## Shorthand Substring (string) or zero-based index (number). ```yaml theme={null} - switchTab: 1 ``` The shorthand cannot include timeouts. Setting either timeout uses the detailed form: ```yaml theme={null} - switchTab: index: 1 timeout: 5000 loadTimeout: 30000 ``` ## Examples ```yaml theme={null} - switchTab: substring: /companies/momentic/jobs/938G5qp timeout: 5000 loadTimeout: 15000 ``` ```yaml theme={null} - switchTab: substring: randomly-changing-link ``` ```yaml theme={null} - switchTab: regex: practice-tab-search ``` ```yaml theme={null} - switchTab: 1 ``` ## Related * [Steps](/docs/core-concepts/steps) # type Source: https://momentic.ai/docs/reference/commands/type Type text into an input, optionally clearing and submitting. Types the given text key by key. Without `into`, types into whatever currently has focus. `clear` controls whether existing input is cleared first. Use the `fill` alias to replace the value in one operation without per-keystroke events. ## Parameters | Parameter | Type | Required | Description | | ------------ | -------------------------------------------- | -------- | ----------------------------------------------------------------------------------------------- | | `text` | `string` | Yes | The text to type. | | `into` | `string` | No | Description of the input to focus before typing. | | `css` | `string` | No | CSS selector for the target. Use instead of the description key. | | `coords` | `string \| { x, y }` | No | Absolute viewport coordinates. Either an `x, y` string (e.g. `120, 40`) or a `{ x, y }` object. | | `x` | `number \| string` | No | X coordinate. Must be provided together with `y`. | | `y` | `number \| string` | No | Y coordinate. Must be provided together with `x`. | | `force` | `boolean` | No | Force the action even when the element is not actionable. | | `iframe` | `string` | No | URL or URL pattern of the iframe that contains the target element. | | `offset` | `string \| { x, y }` | No | Pixel offset from the resolved target. Either an `x, y` string or a `{ x, y }` object. | | `pressEnter` | `boolean` | No | Press Enter after typing. | | `clear` | `"inputs" \| "always" \| "never" \| boolean` | No | Clear existing input before typing. `inputs` only clears ``/`