> ## 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. > Mo is the AI QA engineer, a separate product from the YAML test framework: its npm package and CLI are `qa` (not `mo` — `npx mo` is a different project). Install with `npm install -g qa`, authenticate the same MOMENTIC_API_KEY way, install repo skills with `qa skills -y`, and start a session with `qa start ""` or `qa `. Docs: https://momentic.ai/docs/mo.md. > You cannot complete the browser sign-in yourself. Read the API key from the exact MOMENTIC_API_KEY environment variable (similarly named vars like BILT_MOMENTIC_API_KEY are ignored), 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 momentic skills --yes` (or `npx momentic-mobile skills --yes` for mobile). > 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. Repository tests are YAML files under your own version control. You choose whether to upload their run artifacts. ## 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. Repository tests supply context from the applications, pages, and artifacts they use. [Mo](/docs/mo/index) can also use files you upload and read-only context from repositories you connect to the session. ## 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 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 run artifacts stay local unless you pass `--upload-results`. See [Results and reporting](/docs/running-tests/results). | Mo sessions run on hosted infrastructure. Their chat, reports, and available evidence are stored with the session and accessible in the Mo web app. 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. Only authorized Momentic personnel with a business need can access them. 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 Momentic may use data from self-serve accounts to improve its 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. The [knowledge base](/docs/ai/knowledge-base) uses embeddings to retrieve relevant entries. To discuss training or retention requirements, ask your account team or [contact support](/docs/account/help). ## 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. Page content and screenshots can contain sensitive data if it is present in the application under test. ## How the agents are constrained Agents receive page data, including screenshots and simplified HTML. Tool schemas constrain the commands an agent can request, and the runtime validates tool inputs before executing them. Prompts instruct agents to target elements on the current page and treat webpage content, traces, and prior run memory as untrusted input. Natural language goals and these checks do not prevent an agent from making an incorrect decision; review results and evidence. ## 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), so you can revoke a leaked dev key without touching production The dashboard shows each key once at creation; copy it 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 | ### Remove a team member An admin can remove a member from the [Members page](https://app.momentic.ai/settings/members). Open the member's menu and select **Remove user**. This removes the member's access to that workspace. It does not delete their user account or the workspace. You cannot remove yourself or the workspace's only admin. Ask another admin to remove you, or promote a second admin before removing the current one. ## Delete an account or workspace To request deletion of your Momentic user account or workspace, email [support@momentic.ai](mailto:support@momentic.ai). Include the account email, workspace name, and whether you want to delete the user account, the workspace, or both. Revoking an API key, removing a member, or running `momentic logout` does not delete the workspace. See [Get help](/docs/account/help) for the support contact paths. ## Domain claiming Claim your company email domain so anyone who signs up with that domain joins your workspace automatically instead of waiting for an invitation. Domain claiming is available on paid plans. 1. Sign in with an address on the domain you want to claim. Personal email providers cannot be claimed. 2. Open [Settings > Workspace](https://app.momentic.ai/settings/workspace) and turn on the toggle under **Domain**. You need permission to manage workspace settings. 3. Add the TXT record shown (host and value) at your DNS provider, then click **Verify**. The domain shows **Pending verification** until the record resolves. If verification fails, check the record and verify again. Turn the toggle off to remove the claim. ## SSO SSO is available on the Enterprise plan. [Contact support](/docs/account/help) to configure SSO for your workspace. See [Security](/docs/account/security) for security policies and trust documentation. ## 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 # Common problems Source: https://momentic.ai/docs/account/common-problems Recurring support problems, their causes, and the fixes. For Mo, run `qa doctor`. For repository tests, run `npx momentic doctor` (web) or `npx momentic-mobile doctor` (mobile). See [Get help](/docs/account/help) if your problem is not on this page. ## Mo sessions ### Mo cannot reach the target Check the exact URL from the brief, the account's permissions, and deployment protection. See [Give Mo access](/docs/mo/bot-protection) for sign-in and firewall settings. For an app on your machine or private network, keep its [tunnel](/docs/mo/tunneling) running while the session needs it. ### `qa report --require-idle` says "Report not ready" Mo or its sub-agents are still working. Follow the session with `qa status` and `qa read`, then retry the export. The flag checks readiness once. See [Mo reports](/docs/mo/reports#export-the-report) for partial snapshots and export options. ## Setup ### `install-browsers` takes more than 10 minutes in CI `chrome` pulls in more system packages than `chromium`, and a Node module cache does not cover them. If your tests do not depend on branded Chrome, install `chromium` only: ```bash theme={null} npx momentic install-browsers chromium ``` To remove the install step from every job, build a runner image with the browsers and their system packages preinstalled. ### Node.js version Node.js 22.12.0 or later in the 22.x line, or 24.0.0 or later. Node.js 23 is not supported. `momentic` 3.0 and `momentic-mobile` 1.0 dropped Node.js 20. See the [v3 upgrade guide](/docs/get-started/upgrade-to-v3) and the [mobile v1 upgrade guide](/docs/get-started/upgrade-to-mobile-v1). ### A CLI command hangs Record the exact command, the last terminal output, and how long it has been waiting. Run [`npx momentic doctor`](/docs/cli-reference/momentic/commands/doctor) from the same project and shell. It checks the Node.js version, authentication, network connectivity, installed browsers, and missing browser system libraries. Follow the fixes in the report. For a browser installation, check the [`install-browsers` requirements](/docs/cli-reference/momentic/commands/install-browsers) and the CI installation notes above. Node.js 24 is supported; a hang alone does not identify Node.js as the cause. If the command still hangs, [contact support](/docs/account/help#what-to-include) with the report and terminal output. If `doctor` also hangs, include the last section it printed. For a test run, use `--reporter steps` to log step progress and `--timeout-minutes` to set a run limit. See [`momentic run`](/docs/cli-reference/momentic/commands/run). ### "Test has schema version X, which is newer than this version of the CLI supports" A newer CLI than the one in CI saved the test. Each save writes the schema version of the CLI that runs the editor, so `npx momentic@latest app` on one laptop can break every pipeline that pins an older version. Pin one version in `package.json`, start the editor from that install with `npx momentic app`, and upgrade the pin and the test files in the same pull request. ## Authentication ### The CLI cannot find my API key The CLI reads `--api-key`, then `MOMENTIC_API_KEY`, then `~/.momentic/auth.json` from `momentic login`. Run [`momentic whoami`](/docs/cli-reference/momentic/commands/whoami) to see which key it found and which organization the key belongs to. In CI, set `MOMENTIC_API_KEY` from your secret store. Create keys in the [dashboard](https://app.momentic.ai/settings/api-keys). ### The login step fails on an OTP or MFA code When parallel runs sign in with one email address, each run reads the other runs' codes and the codes expire or fail. Give each run its own address with plus addressing, for example `qa+{{ Date.now() }}@example.com`, or create the user in an API request step at the start of the test. Momentic reads codes from a Momentic inbox or an SMS number. See [Email OTP](/docs/guides/auth/email-otp) and [SMS OTP](/docs/guides/auth/sms-otp). For an authenticator app, use the TOTP secret with [otpauth](/docs/guides/auth/otpauth) or turn off MFA for the test user. Keep passwords and TOTP secrets in [environment variables](/docs/configuration/environment-variables#secrets), not in test files. ### The cached login module passes, but the page is logged out The module cache stores browser state after the module's last step. If that step clicks **Sign in**, the stored state predates the redirect. End the module with a check that passes only when the user is signed in, such as an element check on the account menu. If the app's session is shorter than `defaultCacheTtl`, lower the TTL. To drop a bad entry, change the cache key. The stored state has cookies, `localStorage`, and IndexedDB, not `sessionStorage`; if your app keeps its token in `sessionStorage`, do not cache the module. See [Authentication modules](/docs/core-concepts/modules#authentication-modules). ### Cloudflare, a WAF, or bot detection blocks the run With a local browser, requests to your app come from the machine that runs `momentic run`. Allowlist your CI runners, or give them a fixed egress IP. With [hosted browsers](/docs/running-tests/hosted-test-environments), requests can come from Momentic's infrastructure or pass through your network tunnel. See [IP whitelist](/docs/core-concepts/authentication#ip-whitelist). Momentic does not solve CAPTCHAs; turn them off for test traffic with a header or cookie your app recognizes. ## Writing tests ### Slow-motion execution (`slowmo`) Set [`browser.slowMoMs`](/docs/configuration/browser#execution-timing) to pause between web test steps. The value is in milliseconds, from `0` to `10000`. The first executed step has no delay. Individual tests can override the project setting. Use the [local editor](/docs/local-app) to watch the test and inspect its steps. Remove the delay after debugging to avoid adding wait time to subsequent runs. ### "Template fragment 'env.NAME' evaluated to undefined" Nothing set the variable before this step read it, or the name differs. Check spelling and case. Confirm the variable is set in `momentic.config.yaml`, the environment, or an earlier step. A module parameter is visible inside that module only. Names inside `{{ }}` are JavaScript identifiers, so `MY_VAR#1` is invalid. See [Variables](/docs/core-concepts/variables). ### The AI cannot find an element inside an iframe Steps do not look inside iframes by default. Set `browser.autoExpandIframes: true` in `momentic.config.yaml`. If a recorded step targets the iframe by URL and the URL changes on each run (payment providers do this), remove the URL from the target or match it with a regular expression. See [Page handling](/docs/configuration/browser#page-handling). ### A link opens a new tab and the next step fails Steps keep acting on the original tab. Add a [`switchTab`](/docs/reference/commands/switch-tab) step after the click. We deprecated `browser.autoFollowNewTabs` because it races the page load. If the new tab loads slowly, raise `browser.pageLoadTimeoutMs` (see [Timeouts](/docs/configuration/browser#timeouts)). ### A cookie banner, toast, or dialog breaks a step For a banner that appears on some runs only, set the cookie or `localStorage` value that hides it in the `browser` config (see [Headers, storage, and identity](/docs/configuration/browser#headers-storage-and-identity)). For a toast that disappears before the check runs, use [`assertVisually`](/docs/reference/commands/assert-visually) right after the action that shows it. On Android, set `emulator.autoGrantPermissions: true` so permission dialogs do not appear (see [Mobile configuration](/docs/configuration/mobile)). ### A step passes locally and fails in CI Slow runners change timing. Open the **Resources** tab of the failed run. CPU near 100% produces `Page.captureScreenshot timed out`, `DOMStorage.enable timed out`, and missed elements. Lower `--parallel`, use a larger runner, or shard the suite. Raise `browser.pageLoadTimeoutMs` for slow environments. If the element description is the cause, see [Finding elements](/docs/core-concepts/finding-elements). See [Parallelism and sharding](/docs/running-tests/performance#parallelism-and-sharding). ## Results ### "Unknown Momentic platform error" This category reports an internal Momentic error. Open the failed run and the failing step to read the full error and inspect its artifacts. The category alone does not identify the cause. Run the diagnostic command for your CLI listed at the top of this page. If the failure persists, [contact support](/docs/account/help#what-to-include) with the run URL or ID, the full error, the failing step, and the diagnostic output. Keep the failing run so support can inspect the original evidence. ### `results upload` or `results merge` exits with code 137 The runner killed the process for memory. Upgrade to the latest CLI first. If the merge still fails, skip it: pass one `--run-group-id` to every shard with `--upload-results`, so each shard uploads its own results and the dashboard groups them. See [Group independent invocations](/docs/running-tests/results#group-independent-invocations). ### "Upload failed: results path does not exist" The run wrote to a different `--output-dir` than the one passed to `results upload`, or the upload job runs on another runner without the artifact. Upload from the job that ran the tests, or pass the results directory between jobs as an artifact. See [Results](/docs/running-tests/results). ### Classification settings disappeared from the dashboard **Classify on fail** and **Override CI exit code** moved to `momentic.config.yaml`: ```yaml momentic.config.yaml theme={null} ai: classification: enabled: true overrideExitCode: true ``` With `overrideExitCode: true`, failures the classifier routes to **heal** or **warn** exit `0`. Omit it if you did not use the dashboard toggle. If you run `momentic ai classify` in a separate job, start it after the upload finishes. See [AI configuration](/docs/configuration/ai). ## Mobile ### The emulator does not start or disconnects Close other Momentic sessions on the same machine, then run `adb emu kill` and `adb disconnect` before you start `npx momentic-mobile app` again. Remote Android emulators need a local `adb`; install platform-tools and set `ANDROID_HOME`. See [Install adb](/docs/platforms/android/app-setup#install-adb). A VPN or proxy that injects its own certificates also breaks the connection; turn it off or allowlist `*.momentic.ai`. If the error is `Could not find a driver for automationName 'UiAutomator2'`, several concurrent sessions raced on the device-driver manifest. Lower `--parallel` and retry. If iOS works and Android does not, and nothing changed on your side, ask [support](/docs/account/help) before you reinstall. ## Coding agents ### The MCP server does not start in VS Code, Cursor, or Claude A server entry in a user-level config (Claude Desktop, Codex `~/.codex/config.toml`) needs an absolute `--config` path, because the editor does not start in your project directory. Project-level entries, which `install-mcp` writes by default, can use a relative path. The editor process also needs `MOMENTIC_API_KEY`; set it in the entry's `env` block or run `momentic login`. Restart the editor after each config change. `npx momentic install-mcp` writes a correct entry for each detected client. See [MCP server](/docs/coding-agents/mcp-server). ### One editor, several `momentic.config.yaml` files Each project needs its own server entry with its own `--config` path. Web and mobile servers use the names `momentic` and `momentic-mobile`, so one config file holds both. For two web projects, give each entry a different name. # Get help Source: https://momentic.ai/docs/account/help How to reach Momentic support, what to include in a report, and how to request a feature. Reach Momentic support when you cannot solve a problem yourself, when you need to report a security issue, or when you want to request a feature. This page lists the contact paths and what to include in a report. ## Contact support Check [Common problems](/docs/account/common-problems) first. It lists the errors support sees most, with fixes. Email [support@momentic.ai](mailto:support@momentic.ai). Customers on a plan with a shared Slack channel can post there instead. Include the items below so support can investigate the failure. ## What to include * The Mo session URL or ID, the test run URL or ID, or the local results directory for a CLI run. * The output of `qa doctor`, `npx momentic doctor`, or `npx momentic-mobile doctor`, matching the CLI you use. These commands report authentication and setup problems. * The exact command, CLI and Node.js versions, operating system, and whether the problem occurs locally or in CI. For a command that stops making progress, include its last output and how long it waited. * The full error message and the time of the failure, including your timezone. * The test file, if the problem is in one test. * What you expected and what happened instead. Add `--json` to the diagnostic command to get a report you can attach. Remove API keys, passwords, tokens, and other secrets from commands, logs, and test files before sharing them. ## Report a security issue Do not post details in a shared channel. Email [support@momentic.ai](mailto:support@momentic.ai) with "Security" in the subject. See [Security](/docs/account/security) and the [Trust Center](https://trust.momentic.ai) for our practices. ## Request a feature Email [support@momentic.ai](mailto:support@momentic.ai) with the problem you want to solve, how you work around it today, and which tasks it blocks. Watch the [changelog](/docs/changelog) to see when a request ships. # 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. This page collects links to Momentic's trust resources and lists the sub-processors that handle customer data. ## 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 announces agent deprecations at least 90 days in advance. When upgrading an agent version, we recommend testing the migration in a branch first. AI model decisions can vary between versions. Supported locator and assertion agents use [memory](/docs/ai/memory) (insights saved from past runs) and custom [knowledge base](/docs/ai/knowledge-base) entries. Agents can fall back to configured alternative models when a provider fails. Fallbacks can change latency and decisions. [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. ## Web agents | Agent | Recommended | Other versions | | - | - | - | | `locator` | `v5` | `v2`, `v3`, `v4` | | `assertion` | `v5` | `v2`, `v3`, `v4` | | `visual-assertion` | `v5` | `v2`, `v3`, `v4` | | `text-extraction` | `v3` | `v2` | | `failure-recovery` | `v2` | `v1` | ## Mobile agents | Agent | Recommended | Other versions | | - | - | - | | `android-locator` | `v2` | `v1` | | `ios-locator` | `v2` | `v1` | ## V5 effort routing V5 requires `momentic` 3.52.10 or later. `v5` routes each locator and assertion query to one of three effort levels (fast, medium, or extended) based on the query's complexity. You set `v5` in `agentConfig`; the effort level is not configurable. The effort level sets the credit usage for the query: | Effort | Credit usage | | - | - | | Fast | 1x | | Medium | 2x | | Extended | 3x | Credit multipliers apply only to credit-based organizations. `visual-assertion` `v5` does not use effort routing. Every visual assertion uses 1x credits, the same as `v4`. Setting `visual-assertion: v5` in `momentic.config.yaml` requires `momentic` 3.60.0 or later; selecting it in workspace settings works with any CLI version. ## What each agent does Locates elements from a natural language description, used by **Click**, **Type**, and **Element check** steps. Exact single-quoted text constrains matching. Successful resolutions can populate the step cache. Evaluates natural language statements against a snapshot of the page, used by **AI check** steps. Prioritizes exact single-quoted text values and resolves visual detail from the current page context. Evaluates natural language statements from a viewport screenshot. Use it for visible layout, text, and appearance within the viewport. Extracts structured data from the page given a JSON schema, used by **AI extract** steps. Supports nested objects and arrays. Generates and executes recovery steps when a recoverable failure is detected. Requires [`ai.failureRecovery`](/docs/configuration/ai#ai-failurerecovery). Locates elements in the Android UI hierarchy from a natural language description, used by mobile **Tap**, **Type**, and **Element check** steps. Locates elements in the iOS UI hierarchy from a natural language description, used by mobile **Tap**, **Type**, and **Element check** steps. # 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 appear 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 row shows the reason (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 adding unreviewed entries. ## 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 Give agents product terminology, rules, and expected flows. Scope entries to an organization, app, environment, or test. 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. Agents retrieve relevant entries for a task and include them in their prompts as priority context. You manage it from the **Knowledge** section of the dashboard at [app.momentic.ai/knowledge](https://app.momentic.ai/knowledge). ## Knowledge types You can create three types of knowledge. Pick the type that matches the information you want to provide. * **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. 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. The knowledge base can also contain generated **Code insight** entries. These are read-only in the knowledge editor and describe the code behind a product area. See [App graph](/docs/ai/app-graph). Definitions, instructions, and steps all support Markdown. Retrieval preserves Markdown but can omit or truncate entries to fit the agent's context budget. Keep essential rules concise and put them early in an entry. Agent-rule instructions accept up to 100,000 characters when created or edited, including through bulk upload. Existing longer instructions remain readable and can still be archived. ## 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 when indexing finishes. 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. * **App scope** limits the item to a specific app. 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. Momentic accepts up to 200 rows per upload and validates the whole upload together: if any row is invalid, Momentic creates nothing 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`. The `examples` field accepts 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 includes 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. Momentic manages the system knowledge it authors, so it can't be edited or disabled. ## Trust and conflicts Each item carries a **trust** score from 0 to 100 that shows how authoritative it is. Manually authored knowledge is trusted more than auto-generated suggestions, and Momentic's own system knowledge is trusted highest by default. Prompts instruct agents to prefer the higher-trust entry when entries conflict. Agent rules are treated as binding instructions and are given extra retrieval weight. ## How agents use knowledge Momentic uses semantic retrieval to select entries relevant to an agent's task and includes the retrieved entries as 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. Prompts require agents to follow entries that directly address the task and cite entries they rely on in written reasoning or summaries. Use those citations to 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 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. This lets the agent distinguish the currently active tab from one literally labeled "Selected". ## When memory is used Momentic uses memory for supported locator and assertion agents, including locator resolution (**Click**, **Type**) and assertions (**AI check**, **Element check**). It treats memory as a form of caching and skips it 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 can include failed locator results and false assertion results. The agent can reuse those decisions when the page still shows the same failure. ## 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 selection 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 apart from applicable knowledge-base rules. 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." ``` For persistent guidance, create an **Agent rule** in the [knowledge base](/docs/ai/knowledge-base) and choose **Test selection**. Selection uses relevant organization-wide rules and rules for the environment passed via `--env`, but ignores test-scoped rules. ## 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 `--ai-select-dry-run` 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 runs for up to 180 seconds by default and reserves time to finalize gathered evidence before the deadline. If Momentic cannot recover a selection, it falls back to running every in-scope test. Slow billing or telemetry does not discard a completed selection. Use `--timeout` to change the limit, in seconds, for the standalone command. The minimum is 60 seconds: ```bash theme={null} npx momentic ai select --base origin/main --timeout 300 ``` In JSON output, an unrecoverable 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. When onboarding to AI test 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 test selection 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 We benchmarked Momentic on QAWorkflowSelect, our custom 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) # Runtime 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. These skills guide Momentic's own agents during runs. Skills for the coding agent in your editor (Claude Code, Cursor, Codex) install with `npx momentic skills`. See [Coding agent skills](/docs/coding-agents/skills). ## 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 replaces it 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. * Momentic skips a skill with missing frontmatter, invalid YAML, an unknown agent target, an empty body, or a name that doesn't match its directory, and prints a warning naming the file so you can fix it. ## Skills and prompt flags Prompt flags provide guidance to the command that accepts them. For example, [`momentic ai select`](/docs/cli-reference/momentic/commands/ai#select) accepts `--prompt`, but test selection does not load these runtime skills. Use a [knowledge base agent rule](/docs/ai/select#guide-selection-with-a-prompt) for persistent test-selection guidance. # 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 organization 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} curl --fail-with-body \ -H "Authorization: Bearer $MOMENTIC_API_KEY" \ "https://api.momentic.ai/v1/runs?pageSize=20" ``` Create or manage keys in [API keys and team](/docs/account/api-keys-and-team). ## Error handling | Status | Meaning | Handling | | - | - | - | | `400` | Invalid query or cursor. | Correct the request before retrying. | | `401` | Missing authentication or authenticated user/organization context. | Check the `Authorization` header and API key configuration. The response can be JSON or a text body. | | `403` | Invalid API key. | Replace the key with a valid key for your organization. | | `429` | Request rate limit exceeded. | Reduce polling and wait for the `Retry-After` interval. The response is a text body. | | `500` | Internal server error or request timeout. | Preserve the response and contact support if the failure persists. The response is a text body. | | `503` | Temporary failure validating the API key. | Retry later. | | `529` | Database overload. | Stop automatic retries and try again later. | ## Shared request rules * All endpoints in this reference use `GET`. * 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. * Pass `pageSize` (max 100, default 20) to size each page. * Each response includes a `pagination` object: ```json theme={null} { "pageSize": 20, "hasMore": true, "nextCursor": "eyJmIjoxNzgyOTA3MzM0MDAwLCJpZCI6InJ1bl8wMUo5RDkwWFBYTUE0VDBUU043NlZGUTJLOCJ9", "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 "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 Write 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: checkout-goal 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: checkout-goal 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 user flow. 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, so repeated runs are faster and more consistent. If the cached path no longer works, eligible failure recovery can clear 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 path 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. 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 tests 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` | Team ownership | Label per-test in YAML: ```yaml checkout.test.yaml theme={null} fileType: momentic/test/v2 id: checkout labels: [smoke, owner:payments] steps: - assert: The order confirmation is visible ``` 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. Select an environment to reuse the test against compatible targets. Keep URLs, accounts, and credentials in environment variables instead of hard-coding them in tests. ## Shared fixtures Keep seed scripts and non-secret fixture data in `fixtures/` at the project root. Supply API keys through environment variables or CI secrets. Reference fixtures from test variables or modules. # Product updates Source: https://momentic.ai/docs/changelog New updates and improvements ## Features ### Testing * [Failure recovery](/docs/reliability/auto-maintenance#transient-recovery) is out of beta and now runs on iOS as well as web and Android. On every platform it stops after three recoveries in one run, and the temporary steps it generates never edit the test or, on mobile, the replay cache. Set `ai.failureRecovery: true` in `momentic.config.yaml` to turn it on. * `momentic run --remote-browser-region westus3` (or `eastus2`) runs one invocation on hosted browsers in a specific Browser Fleet region. The flag turns on hosted browsers for that run, fails instead of falling back when the region cannot serve it, and is not available through a private Connector. Ships in the next `momentic` release. See [Regions](/docs/running-tests/hosted-test-environments#regions). * The [`visual-assertion`](/docs/ai/agents) agent has a new `v5`, and it is now the default for new projects and after `momentic upgrade`. It reads small text and fine positional detail more accurately, with 75% fewer errors than `v4` on our visual understanding benchmark at a similar median latency. Visual assertions still use 1x credits. Select it in workspace settings, or set `visual-assertion: v5` in `momentic.config.yaml` with `momentic` 3.60.0 or later. * [Hosted browsers](/docs/running-tests/hosted-test-environments) and the [knowledge base](/docs/ai/knowledge-base) are generally available. Result [classification](/docs/reliability/auto-maintenance#permanent-healing), [triage](/docs/reliability/auto-maintenance#triage), and [AI test selection](/docs/ai/select) have dropped their beta and alpha labels as well. The Explore agent is now marked **Legacy** in settings; use [Mo](/docs/mo) for autonomous bug finding. * New projects from `momentic init` and the setup wizard get a documented [`momentic.config.yaml`](/docs/configuration/momentic-config): every option carries a comment, and hosted browsers (`browser.remoteBrowser`), `turbo`, and the timeout settings appear as commented-out hints. New web projects also start with `parallel: auto`, which picks a worker count from your CPU cores and a higher one on hosted browsers. Hosted browsers apply to `momentic run`; the editor and the MCP server still use local Chromium. * `email.send` steps can deliver to an address outside Momentic. Ask Momentic to allowlist the recipient address or domain for your organization; delivery to Momentic-provisioned inboxes is unchanged. See [email](/docs/integrations/email). * V5 assertions without an explicit effort now route themselves to a fast, medium, or extended effort level based on how much reasoning the check needs, and a locator description the fast tier cannot handle moves up a tier on its own. A step that pins its own effort keeps it. * The step cache survives a rebuild of your application: generated SVG reference ids are normalized before hashing, and a `src`-style attribute that carries a source file and line number (`Button.tsx:3016`) is left out of the cached selector, so a new build no longer misses on every step. ### Mobile * Soft reset on a hosted iOS device now clears app data, the keychain, privacy settings, preferences, and shared containers between runs, matching Android. Requires `momentic-mobile` `1.28.8`. * A hosted emulator that reaches its plan's session time limit now reports the limit as an expected expiry instead of an emulator failure, and the mobile editor offers **Start new session**. * A hosted emulator whose liveness renewal stalls mid-run is no longer reaped during a long test. ### CLI * When `momentic`, `momentic-mobile`, or `qa` fails, it writes one machine-readable line to stderr with a stable error code. The prefixes are `momentic-error` (`MOM_*` codes), `momentic-mobile-error` (`MOB_*` codes), and `mo-error` (`MO_*` codes), respectively. Each error includes a group, retry advice, and whether the fix belongs to your input, your environment, or Momentic. See [Errors](/docs/cli-reference/momentic/overview#errors). * `qa https://preview.example.com` starts a session against that URL without typing `start`. Subcommands and other positionals are unchanged. * `qa whoami` prints the account, organization, and server for the active key and which credential the CLI resolved. `qa doctor` now reports auth from `MOMENTIC_API_KEY`, checks connectivity, and exits non-zero on a problem, the same as `momentic doctor`. `mo upgrade` on a standalone install renames the binary to `qa` and leaves an existing `qa` alone. See [`qa whoami`](/docs/cli-reference/mo/commands/login#whoami) and [`qa upgrade`](/docs/cli-reference/mo/commands/upgrade). * `momentic install-mcp --client devin` and the setup wizard configure Devin, writing `.devin/mcp_config.json` in the project. A Devin VM is detected automatically, so `install-mcp -y` picks it without a flag. See [`install-mcp`](/docs/cli-reference/momentic/commands/install-mcp). * The `momentic-mobile` [MCP server](/docs/coding-agents/mcp-server) exposes run history: `momentic_list_runs`, `momentic_get_run`, `momentic_get_test_steps_for_run`, and `momentic_get_step_result`. Queries default to Android and iOS runs; pass `executionType` to override. * `momentic init --yes` and `momentic-mobile init --yes` set up a project without prompts, taking the default name and skipping the Git-repository confirmation. Both CLIs treat a shell without a terminal as non-interactive: an answer prompt takes its default, and a confirmation that would overwrite or delete something stops with instructions to re-run with `--yes` instead of hanging on `ExitPromptError`. See [`init`](/docs/cli-reference/momentic/commands/init). * Clearer errors for coding agents and people alike: an unknown step type suggests the closest valid one, a `waitForUrl` pattern with a wildcard explains that substring matching is literal and points at `glob:`, a run that fails because a browser or `ffmpeg` is missing suggests [`momentic doctor`](/docs/cli-reference/momentic/commands/doctor), and a test or module file that cannot be written names the file permission or lock that blocked it. * `momentic run tests/auth` no longer also runs `tests/auth-extra`. A directory filter matches the directory and its children only. * Every published CLI prints the sign-in hint for its own command instead of pointing at `momentic login`. * Allure reports from `momentic run` and `momentic-mobile run` now include disabled tests and tests skipped by quarantine as skipped results, with zero attempts and no artifacts, so the report's test count matches your suite. Requires `momentic` `3.58.6` and `momentic-mobile` `1.32.8`. The next `momentic-mobile` release also reports disabled Android and iOS tests as skipped in JUnit output and the terminal summary instead of dropping them. See [local reports](/docs/running-tests/results#generating-local-reports). * [`browser.slowMoMs`](/docs/configuration/browser#execution-timing) in `momentic.config.yaml` sets a project-wide pause before each step, from `0` to `10000` milliseconds. A test's own `slowMoMs` still takes precedence. Ships in the next `momentic` release. * The `momentic` and `momentic-mobile` [MCP servers](/docs/coding-agents/mcp-server) expose `momentic_search_docs`, which searches these docs and returns the matching sections with their links. Tell your coding agent to call it before it writes step options, CLI flags, or configuration keys from memory. * The setup wizard no longer fails with `EALLOWSCRIPTS` when you launch it with `npx` and it runs `npm install`. Your own npm configuration is kept. An install that fails for another reason (a root-owned npm cache, a full disk, a registry timeout, an unsupported Node version) now names the cause instead of ending with "See output above". ### AI test maintenance * Routed repairs for the same reviewer land in one pull request, and auto-heal notifications report every pull request that was delivered, including a stability patch produced after a test recovered. * GitHub and Slack notifications for a commit that auto-heal repaired carry an **Auto-heal triggered** prefix, so a repaired run is distinguishable from a failure at a glance. Risk findings such as **Bug detected** or **Broken test** keep their own prefix. ### Dashboard * The Usage page is split into **Test execution**, **Infrastructure**, and **AI agents** tabs. The AI agents tab shows invocations of AI test selection, classification, and triage, and triage outcomes (**Test healed**, **No fix needed**, **Test heal unsuccessful**, **Error**), with breakdowns by agent, outcome, and label. * The **Monthly spend limit** card under **Settings > Billing** shows current spend against the limit and says when the limit is reached and usage is paused. Usage-threshold emails for pay-as-you-go plans now state the overage rate, 1.5x the base per-credit rate, and that a credit block bills at the base rate. * **Settings > Integrations** groups integrations by category with search and **All / Connected / MCP** tabs, and each integration has its own page. An MCP server page gains **Test connection**, which lists the tools the server exposes with your saved credentials. * The knowledge base library is paginated, with the page and page size in the URL. Semantic search still returns the top 50 matches. * Hosted browser concurrency is now capped per organization according to your plan. A run that asks for more sessions than the plan allows waits for capacity instead of failing. * The GitHub integration card has a **Pull request comments** section. Turn off **Passing runs** to remove the Momentic comment once every run group for the commit passes, and set **Failure details** to list failed tests with run links or to show the run group summary. See [GitHub](/docs/integrations/github#pull-request-comments). * Paid plans can claim a company email domain under **Settings > Workspace**. After you verify the domain with a TXT record, new users who sign up with that domain join your workspace automatically. See [domain claiming](/docs/account/api-keys-and-team#domain-claiming). ### Mo Mo is live. [Sign up](https://momentic.ai/mo) to try it. * Mo runs mobile sessions on hosted Android and iOS devices. * `qa status` prints the state, dashboard URL, and a count per findings category by default; add `--full` for the latest message and the findings themselves. A script that reads `.findings` or `.latestMessage` needs the flag from Mo CLI `0.12.0`. See [`qa status`](/docs/cli-reference/mo/commands/status). * `qa stop --subagents` stops the root turn and every active sub-agent turn without closing their conversations. `qa version` checks whether a newer Mo is available. * Mo reads repositories through the Momentic GitHub App installation instead of a per-session `--repository` option. Name the repository in the brief. See [use GitHub context](/docs/mo/integrations/github#add-repository-context). * Mo can call tools from the MCP servers you add under **Settings > Integrations**, and Mo schedules have detail views with a run history and **Run now**. * Attach secrets to a Mo message from the composer's attachment menu. Each one is saved into the session environment before the message is delivered, and `$NAME` references in the chat render as lock chips instead of the value. From the CLI, `qa start --env-file .env.qa` and `qa start --env-var NAME` load variables into the session the same way. Requires Mo CLI `0.16.0`. See [`qa start`](/docs/cli-reference/mo/commands/start). * The Mo session header shows the environment the session runs in. * A Mo schedule can pin an **Environment** and a **Max concurrent agents** count. Both apply to every recurring run and to **Run now**; a schedule whose environment was deleted fails at session start instead of running without its variables. See [schedules](/docs/mo/sessions#repeat-a-session-on-a-schedule). * The Mo **Sessions** page filters by platform and environment, and the filters live in the URL. * **Interaction speed** in the Mo composer settings, or `qa start --interaction-speed human`, adds 250 ms between steps and types at 60 ms per keystroke for the session's agents. See [`qa start`](/docs/cli-reference/mo/commands/start). ## Bug fixes * A cached web step whose CSS selector also matches inside an open shadow root now resolves by its cached Momentic id instead of failing a strict-mode check and re-running AI. * Renaming a suite to a name that already exists, or a module to a name that ends with a dash, returns the validation message instead of a server error. * The **Caches are not being saved** warning in the editor header no longer wraps onto three lines when a test sits in a deeply nested folder; long breadcrumb segments truncate instead. * Startup of an iOS session is retried once after a timeout, with the on-device agent and driver restarted, instead of discarding the simulator. * The iOS simulator rejecting an incompatible app bundle now fails at once with the cause instead of retrying, and one mobile module that fails to parse no longer hides the other tests and modules in the editor. * The run video playhead is no longer drawn in the same green as a passing step. * A click or other element action whose target is covered by an overlay, hidden, disabled, or off screen on the first attempt is retried with the step cache and then AI, as before `momentic` `3.58.0`, instead of failing the test at once. Requires `momentic` `3.58.2`. * Steps that failure recovery runs to repair a failed step are billed as AI steps. * The default triage reviewer in **Settings** can be cleared once set. ## 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, the mobile driver 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/coding-agents/mcp-server) 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 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 an MCP-connected 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/coding-agents/mcp-server) 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`](https://www.npmjs.com/package/@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: 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 runs now attempt to reconnect to the device session 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 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 the bundled browser engine. ### 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 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 with the [MCP server](/docs/coding-agents/mcp-server). ### 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 [MCP server documentation](/docs/coding-agents/mcp-server). ### Additional features * Support for network [request mocking](/docs/platforms/web/request-mocking): test your frontend without a backend, override feature flags, or exercise 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](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](/docs/reliability/auto-maintenance#transient-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](/docs/ai/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 are no longer converted to a string. * AI model configurations in Settings now correctly show the models in use. * Search results in the network viewer now show 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. * Modules can now be duplicated. * 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 shows 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 different 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** steps that 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 step-level details will be kept for 3 months. * Run metadata will be kept for 6 months. * Analytics will be available indefinitely. ## Features * Analytics loads faster and helps identify failing and 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 copying 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 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 run 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 supports a vision-only mode tuned for visual checks. * A module can now be treated as an auth module. This automatically saves and restores the module's state. Turn on **Treat as auth module** to enable it. * You can now use x and y coordinates to target elements, such as a specific part of the screen. * Pressing keys now supports a delay between key presses to simulate typing. * Empty string is a valid value for the Type step. ## Debug data You can now see the HTML and the a11y tree in the editor and the test results. The console log and network log viewers are updated as well. ## 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 A dedicated [knowledge base](https://momentic.ai/docs/guides) now hosts detailed guides and tutorials for customers. ## Performance See the [in-depth guide on Momentic's performance characteristics](/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 IndexedDB 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 waits 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 The Momentic CLIs for web tests, mobile tests, and Mo sessions. Momentic ships three CLIs. Two run tests: `momentic` for web and `momentic-mobile` for iOS and Android. The third, `qa`, drives [Mo](/docs/mo/index) sessions rather than running tests. ## Test runners Web test runner: drives Chromium, Google Chrome, and Chrome for Testing. Mobile test runner: drives iOS simulators and Android emulators. ## Mo sessions Start, follow, and control Mo sessions from a terminal. Private beta. ## Shared flags Both test runners 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) # qa 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} qa 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 [`qa download`](/docs/cli-reference/mo/commands/download) before archiving, because archiving removes the session machine. * `qa send` to an archived session fails. Unarchive the session in the dashboard to continue it. * Archiving does not stop a tunnel. Run [`qa tunnel stop`](/docs/cli-reference/mo/commands/tunnel) separately. # qa doctor Source: https://momentic.ai/docs/cli-reference/mo/commands/doctor Check the qa CLI installation and PATH for possible problems. `qa doctor` checks which `mo` and `qa` executables your shell finds, how the running copy was installed, whether credentials are saved, and whether the Momentic server is reachable. Include the output when you report a CLI problem. ```bash theme={null} qa doctor ``` Add `--json` for machine-readable output: ```bash theme={null} qa doctor --json ``` ## Checks The report renders labeled sections with a status for each check: * `qa`: the CLI version (checked against the latest release), the Node.js version, the install method (`npm` or `standalone`), and the resolved binary path. * `Executables on PATH`: every `qa`, `mo`, and `momentic` executable on your `PATH`, in order. On macOS and Linux, the first match for each name is the one your shell runs. Each entry shows the executable's real path, so npm launcher shims (`cli.cjs`) are distinguishable from standalone binaries. * `Authentication`: the auth directory, the saved credentials file, and a live check of the API key against the Momentic server. * `Connectivity`: HTTPS reachability, TLS verification, and clock skew against the server. Warnings and problems print as a numbered list at the end, each with the fix. The command exits non-zero when any problem is found. ## Options Check this API key instead of the saved credentials or `MOMENTIC_API_KEY`. Momentic server URL. Defaults to `MOMENTIC_SERVER`, then the server saved by `qa login`, then `https://api.momentic.ai`. ## Warnings `qa doctor` warns when: * A legacy Momentic `mo` executable is on `PATH`. `mo` was the command's name before 0.18. When the running install is still named `mo`, `mo upgrade` moves it to `qa`. Remove any other stale `mo` file; curl installs left one at `$HOME/.local/bin/mo`. * Multiple executables with the same name are on `PATH`. On macOS and Linux, the earlier directory wins, so a stale copy can shadow a newer install. Remove the old copy or reorder `PATH`, then run `hash -r` in the current shell so it forgets the old location. * `MO_BINARY_PATH` is set. The npm launcher runs that binary instead of the installed one. # qa 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, HTTP Archive (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} qa 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=$(qa 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} qa 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" qa download /home/user/report.json --session-id "$session_id" ``` ## Notes * The session machine must still exist. Download before you [`qa archive`](/docs/cli-reference/mo/commands/archive) the session. * `download` copies a single file. To fetch a directory, ask Mo to zip it first. # qa licenses Source: https://momentic.ai/docs/cli-reference/mo/commands/licenses Print third-party license notices bundled with the Mo CLI. Review the license notices for executables bundled with your `qa` build, for example when auditing what ships in a CI image. ```bash theme={null} qa licenses ``` ## Output The command prints the full third-party license text to stdout. Pipe it to a pager or a file: ```bash theme={null} qa licenses | less qa licenses > THIRD-PARTY-LICENSES.txt ``` ## Notes The npm package launches the same compiled binaries as the standalone release. The command prints notices when that build embeds them. A build without the embedded notices exits with `This Mo build does not include bundled third-party executable licenses.` # qa 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. `qa 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} qa 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 the server saved by an earlier login, then `https://api.momentic.ai`. Env: `MOMENTIC_SERVER`. ## `logout` Remove the saved API key. ```bash theme={null} qa logout ``` The command deletes `~/.momentic/auth.json`. Because the file is shared, this also signs out `momentic` and `momentic-mobile`. ## `whoami` Show the account and organization for the active API key. ```bash theme={null} qa whoami ``` The command prints your email, user ID, org ID, the server the key belongs to, and which credential the CLI resolved (`--api-key`, `MOMENTIC_API_KEY`, or the saved file). ## 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 `qa login`. Create keys in the dashboard; see [API keys and team](/docs/account/api-keys-and-team). # qa read Source: https://momentic.ai/docs/cli-reference/mo/commands/read Read the transcript or wait for 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 wait for Mo to finish its current turn, ask a question, or reach the time limit. Use [`qa wait`](/docs/cli-reference/mo/commands/wait) when a script needs to wait without a time limit. ```bash theme={null} qa read --timeout 290s ``` ## Arguments The session to read, from the output of `qa 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 `qa stop` or a stop from the dashboard. With `--json`, the object has this shape: ```json theme={null} { "sessionId": "", "state": "waitingOnUser", "sessionState": "waitingOnUser", "displayState": "needs_you", "timedOut": false, "messages": [ { "role": "assistant", "text": "Which environment should I test?" } ], "pendingInput": { "id": "", "question": "Which environment should I test?", "options": ["staging", "production"] } } ``` `displayState` is the session's state as the UI shows it, the same word [`qa status`](/docs/cli-reference/mo/commands/status) reports: `needs_you`, `running`, `waiting_on_agents`, `failed_start`, `cancelled`, `ready`, or `sleeping`. `state` and `sessionState` carry the lifecycle value (`starting`, `working`, `waitingOnUser`, `waitingOnAgents`, `idle`, or `stopped`); `state` is the legacy field kept for shipped clients such as `qa wait`. Servers running an earlier API omit `displayState`; use `qa status` for the display word on those. `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 [`qa send`](/docs/cli-reference/mo/commands/send). ## Examples Follow a session until Mo stops working: ```bash theme={null} while true; do output=$(qa read "$session_id" --from latest --timeout 290s --json) || exit $? jq -r '.messages[].text' <<<"$output" || exit $? timed_out=$(jq -r .timedOut <<<"$output") || exit $? [[ "$timed_out" == true ]] || break done ``` ## Notes Reading does not remove messages from the session. For a snapshot of the session state and its findings, run [`qa status`](/docs/cli-reference/mo/commands/status) instead. # qa report Source: https://momentic.ai/docs/cli-reference/mo/commands/report Export a Mo session's findings and reproduction videos. Export the session report to a local directory, with one file per findings category and any available bug recordings. Give the directory to a coding agent to investigate or fix the reported bugs. ```bash theme={null} qa report ``` ## Arguments The session to export. ## Options Directory to write the report and videos to. Defaults to `MOMENTIC_ARTIFACTS_DIR/mo-report-` when that variable is set, or `.momentic-artifacts/mo-report-` otherwise. Only export when Mo is idle and all sub-agents are done. Checks once and exits without writing otherwise; it does not wait. ## Output The command prints the output directory. Inside it, `report.json` is the manifest: ```json theme={null} { "sessionId": "", "findings": { "bugs": "bugs.json", "testCases": "testCases.json", "verdicts": "verdicts.json", "triage": "triage.json" }, "artifacts": [{ "bugName": "...", "path": "..." }] } ``` Read every file `findings` names; newer servers can add categories. `artifacts` holds each recording download as `{ bugName, path }` or `{ bugName, error }`. | File | Contents | | - | - | | `bugs.json` | Reviewed bugs: expected and actual behavior, reproduction steps, recording metadata. | | `testCases.json` | The intended coverage: preconditions, outline, and acceptance criteria per case. | | `verdicts.json` | The verification outcome, confirmed behavior, and coverage gaps per case. | | `triage.json` | Human dispositions (accepted, duplicate, works as intended). No entry means open. | ## Examples Export once the session finishes: ```bash theme={null} qa report "$session_id" --require-idle --output mo-report ``` List every bug name: ```bash theme={null} jq -r '.[].name' mo-report/bugs.json ``` ## Notes Exporting does not rerun anything. To compare a recheck, `qa send` the recheck request, wait for idle, and export again into a second `--output` directory. # qa 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 testing the wrong thing. If Mo is working, it reads your message between tool calls while continuing its active turn. If Mo is idle, your message starts its next turn. ```bash theme={null} qa 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 [`qa 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} qa 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 CLI retries delivery once when the response is lost, so a message can still arrive even when the command reports a network error. Check with [`qa read`](/docs/cli-reference/mo/commands/read) before sending it again. # qa skills Source: https://momentic.ai/docs/cli-reference/mo/commands/skills Install the Momentic skills for your coding agent. Install the Momentic skills into your repository and add an always-on pointer to your coding agent's instructions file. See [Coding agent skills](/docs/coding-agents/skills) for what the skills contain and how updates work. ```bash theme={null} qa skills ``` Without flags, the command asks which coding agents you use. It preselects the agents it detects in the repository. ## Options Coding agents to install for. Skips the agent prompt. One or more of `claude-code`, `cursor`, `codex`, `copilot`, or `opencode`. Skip all prompts. Installs for the agents detected in the repository, or for the agents in `--target`. ## Install location Inside a git repository, the skills install at the repository root. Outside git, they install in the current directory. | Agent | Skills | Pointer | | - | - | - | | `claude-code` | `.claude/skills//` | `CLAUDE.md` | | `cursor` | `.cursor/skills//` | `.cursor/rules/momentic-skills.mdc` | | `codex` | `.agents/skills//` | `AGENTS.md` | | `copilot` | `.github/skills//` | `.github/copilot-instructions.md` | | `opencode` | `.opencode/skills//` | `AGENTS.md` | The command installs the shared skills (`momentic-spec`, `momentic-maintain`, `momentic-triage-quarantined-tests`) and `mo-qa`. It keeps skills that `momentic skills` or `momentic-mobile skills` installed. ## Examples Install for Claude Code and Cursor without prompts: ```bash theme={null} qa skills --target claude-code cursor ``` Install for the detected agents in CI or an agent shell: ```bash theme={null} qa skills --yes ``` # qa 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 [`qa read`](/docs/cli-reference/mo/commands/read) to follow its output. ```bash theme={null} qa start "Test the checkout flow on https://preview.example.com. Sign in with the staging QA buyer. Do not submit payment." ``` You can omit `start` when the message is a bare URL: ```bash theme={null} npx qa https://preview.example.com ``` ## Arguments The brief. Include the target URL, credentials or how to get them, and any boundaries Mo must respect. Required unless you select a PR with `--pr`. ## Options Test a named GitHub PR. Accepts a PR URL or `owner/repo#123`. Without a brief, Mo tests the changed app behavior and its regressions. Changes with no testable app behavior finish without launching testing agents. Choose the deployment for a PR session, including previews created by a coding agent or a custom deployment system. An environment needs no preview URL. Otherwise, without this option, Mo looks for one preview tied to the PR commit in Vercel, Cloudflare Pages, or Netlify posts. Discovery failures do not block startup; Mo can inspect the PR or ask you for the target. Ignored without `--pr`; include the target in the brief for a general session. Send a reviewed Git patch when you cannot push local changes to the PR. Requires `--pr`. Run from the PR checkout: Mo uses local `HEAD` as the patch base and rejects it before starting if it differs from the published PR head. The deployment URL must serve those changes; sending a patch does not deploy them. Accepts text-only patches up to 256 KiB. Exclude secrets, logs, temporary files, generated outputs, blobs, and data files. Ignored without `--pr`. Route Mo's traffic through a tunnel started with [`qa tunnel start`](/docs/cli-reference/mo/commands/tunnel). Required when the target runs on your machine or a private network. Maximum number of sub-agents Mo runs at the same time. Must be a positive integer. The organization limit caps the value. Browser interaction speed: `default` (the default) or `human`. `human` adds 250 ms between steps in a batch and sets the default typing delay to 60 ms per keystroke. The first step and single-step calls have no added step delay. Explicit typing-step delays override the default. Enable experimental WebGL support for apps that render 3D graphics. Rendering uses the CPU, so graphics-heavy apps may run slowly. Applies to the session's root browser and delegated browsers. Cannot be combined with `--platform`. Start in a named workspace environment. Mo sees variable names, descriptions, and the literal `BASE_URL` starting URL. Values are available during execution. Load variables from a dotenv-format file into the session environment. Repeatable; a later file overrides earlier values for the same name. Requires Mo CLI `0.16.0`. Copy one variable from your current shell environment into the session environment. Repeatable. The command fails if the variable is not set. ## 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 Test a PR using its preview deployment: ```bash theme={null} qa start --pr https://github.com/acme/shop/pull/42 qa start "Check declined payments. Do not place an order." --pr acme/shop#42 --url https://preview.example.com ``` Paste the full GitHub PR link, including a comment permalink if that is what you have. Query parameters and fragments are ignored; Mo keeps the repository and PR number. `owner/repo#number` also works. PR sessions use the workspace's GitHub App access and show a **PR** badge in Mo. The session tests the commit captured at startup. Supply `--url` when you know the target deployment, even when its host is not Vercel, Cloudflare, or Netlify. Mo focuses on the changed and affected flows. Its default plan targets about 10 minutes of combined agent interactions within about 20 minutes elapsed. Set a different scope or duration in the brief when needed. These are planning targets, not hard limits. Mo prepares a shallow checkout of the captured commit in the background. It reuses the workspace snapshot when available and fetches the requested revision. Mo can inspect the preview while source downloads. GitHub tools remain available for older commits and other branches. Mo posts a review comment with the session link, then updates it with the results. Each PR session gets a separate review. A new session collapses earlier Mo reviews as **Outdated**, with their session and report links preserved. On the same commit, the Mo check tracks the latest request; earlier attempts stay in its history. Installations with **Issues: write** alone receive PR comments with the same updates and supersession behavior. Clean runs that include a local patch finish with a neutral GitHub check, because they do not verify the remote commit alone. Session starts are submitted once. If Mo cannot confirm startup after a connection failure, check your sessions in Mo before retrying. Commit and push local changes before starting when you have permission. If pushing is prohibited, send a reviewed patch from a checkout at the published PR head: ```bash theme={null} qa start --pr acme/shop#42 --url https://preview.example.com --patch /tmp/checkout.patch ``` Include only the files and hunks needed for testing. Include relevant untracked source files explicitly; `git diff` alone omits them. The CLI reads local `HEAD` as the base revision; a stale or different PR revision is rejected before Mo starts. Send the patch at startup so Mo has the source context before it begins. Mo investigates the PR revision plus that patch and reports the local changes separately from the published SHA. Start a session and wait up to 290 seconds for output: ```bash theme={null} session_id=$(qa start "Bug bash the new billing page on https://preview.example.com" | jq -r .sessionId) qa read "$session_id" --timeout 290s ``` The read can time out while Mo is still working. Use [`qa wait`](/docs/cli-reference/mo/commands/wait) to wait for the session and its sub-agents to finish or ask for input. Give Mo credentials from a local `.env` file without putting them in the brief: ```bash theme={null} qa start "Sign in to https://preview.example.com with \$QA_EMAIL and \$QA_PASSWORD, then test checkout." --env-file .env.qa ``` Test a local build through a tunnel: ```bash theme={null} tunnel_id=$(qa tunnel start localhost:3000 | jq -r .tunnelId) qa start "Smoke test http://localhost:3000 after the login refactor." --tunnel "$tunnel_id" ``` # qa status Source: https://momentic.ai/docs/cli-reference/mo/commands/status Check a Mo session's state and findings. Get the session state and counts for test cases, bugs, and verdicts. Add `--full` for the findings and latest message. ```bash theme={null} qa status ``` ## Arguments The session to inspect. ## Output By default, the command prints: ```json theme={null} { "sessionId": "", "state": "idle", "displayState": "ready", "sessionState": "idle", "webUrl": "https://app.momentic.ai/mo/sessions/", "counts": { "testCases": 4, "bugs": 2, "verdicts": 4 } } ``` `--full` replaces `counts` with `findings.testCases`, `findings.bugs`, and `findings.verdicts` arrays. It also adds `latestMessage` (`null` when unavailable). Test cases and bugs are limited to the main agent. Verdicts are the signed-off outcomes from sub-agents. `displayState` is the session's state as the UI shows it: `needs_you`, `running`, `waiting_on_agents`, `failed_start`, `cancelled`, `ready`, or `sleeping`. It is the field to prefer. `state` is a legacy alias of `sessionState`, and both carry the lifecycle state (`starting`, `working`, `waitingOnUser`, `waitingOnAgents`, `idle`, or `stopped`). Servers running an earlier API report the display word in `state` instead. [`qa read`](/docs/cli-reference/mo/commands/read) and `qa report` report the identical `displayState`, so scripts can compare the commands directly. ## Examples List bug names: ```bash theme={null} set -o pipefail qa status "$session_id" --full | jq -r '.findings.bugs[].name' ``` Poll a session until it stops running, then list the bugs it found: ```bash theme={null} set -o pipefail while :; do state=$(qa status "$session_id" | jq -r '.displayState // .state') || exit $? [[ "$state" == running || "$state" == waiting_on_agents ]] || break sleep 10 done qa status "$session_id" --full | jq -r '.findings.bugs[].name' ``` ## Notes * `status` returns immediately. Use [`qa read --timeout`](/docs/cli-reference/mo/commands/read) to wait for output. * Send input to a `needs_you` session with [`qa send`](/docs/cli-reference/mo/commands/send). # qa stop Source: https://momentic.ai/docs/cli-reference/mo/commands/stop Stop the active turn of a Mo session. Interrupt Mo's active turn and its in-flight tool work while preserving the session history. Sub-agents can continue working unless you pass `--subagents`. Resume the root conversation with [`qa send`](/docs/cli-reference/mo/commands/send) when you have new instructions. ```bash theme={null} qa stop ``` Add `--subagents` to stop the root turn and every active sub-agent turn: ```bash theme={null} qa 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 [`qa archive`](/docs/cli-reference/mo/commands/archive) when you are finished with it. * To redirect Mo while its current work continues, use [`qa send`](/docs/cli-reference/mo/commands/send). # qa 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 Mo through a Momentic Connector. Start the tunnel, pass its ID to [`qa start --tunnel`](/docs/cli-reference/mo/commands/start), and stop it when the session is done. ```bash theme={null} qa tunnel start [--foreground] qa tunnel stop qa tunnel list ``` ## `tunnel start` Start a tunnel to one or more addresses. ```bash theme={null} qa tunnel start localhost:3000 qa 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} qa 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} qa 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 `qa tunnel stop` to finish cleanup). ## Example: test a local dev server Keep the tunnel open while Mo and its sub-agents work. Export the report before closing it: ```bash theme={null} tunnel_id=$(qa tunnel start localhost:3000 | jq -r .tunnelId) session=$(qa start "Test the signup flow on http://localhost:3000" --tunnel "$tunnel_id") session_id=$(jq -r .sessionId <<<"$session") if qa wait "$session_id" --json; then qa report "$session_id" --require-idle --output mo-report && qa tunnel stop "$tunnel_id" fi ``` If `qa wait` exits `2`, answer Mo with `qa send` and wait again. If it fails or the session is stopped, decide whether to resume the session before closing the tunnel with `qa tunnel stop`. ## Notes * Tunnel state lives in `~/.momentic/mo-tunnels`. `qa 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. It stays open until you run `qa tunnel stop`. # qa upgrade Source: https://momentic.ai/docs/cli-reference/mo/commands/upgrade Replace the installed Mo CLI binary with the latest release. Download the latest published `qa` release and replace the binary you are running. For an npm installation, run `npm install -g qa@latest` instead. `qa upgrade` prints the npm update command without replacing the installed binary. Update project dependencies with your project's package manager. ```bash theme={null} qa upgrade ``` ## Behavior 1. Reads the latest version from the release manifest. 2. Downloads the binary for your OS, CPU, and libc (the same selection the installer makes). 3. Verifies the download against its published SHA-256 checksum. 4. Installs the verified file as `qa` in the directory holding the current executable. If any step fails, the command leaves the existing binary untouched. When you are already on the latest release, the command reports that and exits `0`. The current updater renames an install still named `mo` to `qa` in the same directory and removes `mo`. An older updater can install the new release without renaming the file. Run `mo upgrade`, check `qa --version`, and run `mo upgrade` again if `qa` is still missing. The second run uses the new updater. If the binary is already on the latest release, it renames the file without downloading anything. If `mo` cannot be deleted, `qa doctor` flags the leftover file. ## Arguments Install this exact version instead of the latest release, for example `qa upgrade 1.4.2`. Downgrades are allowed. ## Upgrade prompt For standalone installations, interactive commands show an update notice when a newer release exists and ask: ```text theme={null} Upgrade qa to v1.5.0 now? (Y/n) ``` Answering yes runs the same upgrade in place; the current command then continues on the old version. The prompt does not appear in CI, without a TTY, with `--json`, on `qa upgrade`, `qa version`, `qa skills`, `qa licenses`, or `qa doctor`, or when `NO_UPDATE_NOTIFIER` or `MOMENTIC_SKIP_UPGRADE_PROMPT` is set. After it is shown once, it stays quiet for that version for 24 hours. ## Notes * The command needs write access to the directory that holds the installed binary (`~/.local/bin` by default). If the install directory is not writable, re-run the installer instead: `curl -fsSL https://cli.momentic.ai/qa | sh`. * `qa upgrade` only works on a released binary. A source checkout run through `bun` reports that it cannot self-update. # qa 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 [`qa send`](/docs/cli-reference/mo/commands/send). ```bash theme={null} qa 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=$(qa upload ./fixtures/accounts.csv accounts.csv --session-id "$session_id") qa send --session-id "$session_id" "Use the accounts in $remote to test login for each role." ``` ## Notes * 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. # qa 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 `qa` you are running and whether a newer one is available. ```bash theme={null} qa 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. npm-installed copies check the `qa` package on npm instead. If the version differs from yours, a warning follows: ```text theme={null} New Mo functionality is available in 1.5.0. Run `qa upgrade` to update Mo. ``` The check times out after five seconds and fails silently, so `qa 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 [`qa login`](/docs/cli-reference/mo/commands/login), then `https://api.momentic.ai`. ## Update Run [`qa upgrade`](/docs/cli-reference/mo/commands/upgrade) to install the latest release in place. Re-running the installer also works: ```bash theme={null} curl -fsSL https://cli.momentic.ai/qa | sh ``` If you installed with npm, the warning says to run `npm install -g qa@latest` instead. For project dependencies, update `qa` with your project's package manager. ## Notes * `qa --version` prints the version number only, with no update check. * The check is informational. `qa version` does not install anything. # qa CLI Source: https://momentic.ai/docs/cli-reference/mo/overview Start, follow, and control Mo sessions from a terminal. The `qa` CLI drives [Mo](/docs/mo/index), Momentic's AI QA engineer, 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). ## Start a session Sign in, then run the npm package with instructions in plain language. You need Mo access in your Momentic organization and the Node.js version listed under [Install](#install): ```bash theme={null} npx qa login npx qa start "Test the checkout flow on https://preview.example.com." ``` Quote multiword instructions so the shell passes them as one argument. If you installed the CLI, use `qa start ` instead. A bare URL works without `start`: `qa https://preview.example.com`. ## Install Install the npm package and run `qa`: ```bash theme={null} npm install -g qa qa --help ``` The package is `qa`, and the command is `qa` on every install channel. You can also run `npx qa --help`. Releases before 0.18 named the command and the installed file `mo`; see [Troubleshoot the install](#troubleshoot-the-install) if a `mo` remains on your PATH. The npm launcher requires Node.js 22.12 or later in the 22.x series, or Node.js 24 or later. It supports macOS ARM64/x64, Linux ARM64/x64 (glibc and musl), and Windows x64. Linux musl requires `libstdc++`. Keep optional dependencies enabled. To install the standalone binary without Node.js, run: ```bash theme={null} curl -fsSL https://cli.momentic.ai/qa | sh ``` The installer writes `qa` 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. ## Troubleshoot the install If `npm install -g qa` fails with `EEXIST`, a file named `qa` already exists in npm's global bin directory. Check `ls -la $(npm prefix -g)/bin` and remove the stale entry. Do not pass `--force`; it would overwrite the file. `qa` 0.17.x also installed a `mo` command. Updating with `npm install -g qa@latest` removes it automatically. An older standalone install may still use `$HOME/.local/bin/mo`. Run `mo upgrade`, then check `qa --version`. If `qa` is still missing, run `mo upgrade` again. The first run uses the old updater and can leave the new binary named `mo`; the second run uses the new updater to rename it to `qa`. It removes `mo` when it can. If the binary is already on the latest release, the rename does not download it again. If more than one `mo` or `qa` is on your `PATH`, the first one runs. For example, a standalone `qa` in `$HOME/.local/bin` can shadow the npm install. Run `qa doctor` to list every matching executable and the one that wins, or `which -a mo qa` to see the order. In a shell that already ran the old command, run `hash -r` so it forgets the old location. `npx mo` is not Momentic. The `mo` package on npm is a different project. Use `npx qa`. ## 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. Wait for a session and its sub-agents to finish. Get a session snapshot with findings. Export a report to files. Get AI and runtime cost line items for a session. 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. Install the Momentic skills for your coding agent. Print the installed version and check for updates. Replace the installed Mo CLI binary with the latest release. Print licenses for bundled executables. Print diagnostics for the installation and PATH. ## Global flags These flags are shared by several commands. Check `qa --help` for the flags a command accepts; for example, `login` accepts `--server` but does not accept `--api-key`. Momentic API key. Defaults to the value saved by `qa login` in `~/.momentic/auth.json`. Env: `MOMENTIC_API_KEY`. Momentic server URL. Defaults to the server saved by `qa 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 Starting a session with `qa start ` prints a `sessionId`. Every later command takes that ID, either as a positional argument (`qa read `) or as `--session-id` (`qa send`, `qa upload`, `qa 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 `qa login`. | | `MOMENTIC_SERVER` | Override the API host. | | `MOMENTIC_ARTIFACTS_DIR` | Default directory for `qa download` and parent directory for `qa report` when `--output` is not passed. | | `MO_VERSION` | Version for the installer script to install. | | `MO_INSTALL_DIR` | Directory for the installer script to write `qa` into. | ## Errors A command that fails on an error such as invalid arguments, a missing credential, an API failure, or a broken local environment exits with a non-zero code, prints the reason, and writes one machine-readable line to stderr that a CI job or coding agent can parse without scraping the human output: ```text theme={null} mo-error: {"code":"MO_AUTH_REQUIRED","group":"auth","retry":"no","attribution":"user-action","message":"..."} ``` `code` is a stable `MO_*` identifier. `group` is one of `args`, `auth`, `api`, `env`, `run`, or `internal`. `retry` is `yes`, `no`, or `case-by-case`. `attribution` says who owns the fix: `user-action` for input or credentials, `user-env` for the local machine or project configuration, `product` for a Momentic bug, or `unknown`. A command that reports a result through its own exit code, such as `qa doctor` finding a problem, does not write this line. `--help` and `--version` exit `0`. ## 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`. * Command errors exit `1` and print the reason to stderr. `qa wait` also exits `2` when Mo needs input or `4` when the session was stopped. The waiting commands (`read`, `send --wait`, `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. Launch 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. When omitted, Momentic searches the current directory and its parents for `momentic.config.yaml` or a workspace configuration. Use this flag to select a project when discovery finds more than one. 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 step cache state for the session. Saving still follows the normal branch rules; add `--save-cache` to save on protected branches. Use it to refresh 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: Android APK files and iOS `.app` bundles. Each asset belongs to 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, the command 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 `, the command 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. ### Output With `--json`, 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 `(platform, 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 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, a semantic version such as `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 move to 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 Android APK or a zipped iOS app from the Momentic dashboard. Downloads default to Android; pass `--platform ios` for an iOS build. ```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, the command uses the current working directory. If a directory is provided, the file is named `-.apk` for Android or `-.app.zip` for iOS. ### Options Release channel for the asset to download. Version label within the channel to download. Platform of the asset to download. One of `android` or `ios`. ## `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 move the `nightly` alias to 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. Run a read-only health check of your Momentic mobile setup. The report covers: * CLI version * Authentication * Connectivity to the Momentic API (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 device drivers and the local-emulator-only Java setup * Reachability of the remote emulator provider * 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 The command lists each problem at the end with a suggested fix and exits non-zero when it finds any. Warnings do not affect the exit code. ```bash theme={null} npx momentic-mobile doctor ``` If `doctor` reports no problem but a run still fails, see [Common problems](/docs/account/common-problems). ## Options Momentic API key. Defaults to `MOMENTIC_API_KEY`, then the key saved by `login` in `~/.momentic/auth.json`. Path to the Momentic configuration file. When omitted, Momentic searches the current directory and its parents for `momentic.config.yaml` or a workspace configuration. Use this flag to select a project when discovery finds more than one. 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) in the current directory. The command refuses to run if that file already exists. Use the onboarding wizard below when you also want sample tests and modules. ```bash theme={null} npx momentic-mobile init ``` `init` scaffolds new mobile projects 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 you do not need to migrate. 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 command 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 --yes --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 mobile tests need no local browser. 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-mcp Source: https://momentic.ai/docs/cli-reference/momentic-mobile/commands/install-mcp Add the Momentic mobile MCP server to your coding agent config. Writes the Momentic mobile MCP server into the config file of one or more coding agents. You do not need to edit JSON or TOML by hand. See the [MCP guide](/docs/coding-agents/mcp-server) for the tools the server exposes. ```bash theme={null} npx momentic-mobile install-mcp ``` In a terminal, the command asks which agents to configure and where to save the config. It preselects the agents it detects in the project and on your machine. Outside a terminal, or with `--yes`, it writes the project config for every detected agent. The command adds a `momentic-mobile` server entry that runs `npx -y momentic-mobile mcp`. It coexists with the web `momentic` entry. The command keeps other servers in the file and comments in JSON files. ## Supported agents | `--client` | Project config | User config | | - | - | - | | `claude-code` | `.mcp.json` | `~/.claude.json` | | `cursor` | `.cursor/mcp.json` | `~/.cursor/mcp.json` | | `vscode` | `.vscode/mcp.json` | VS Code `User/mcp.json` | | `codex` | `.codex/config.toml` | `~/.codex/config.toml` | | `opencode` | `opencode.json` | `~/.config/opencode/opencode.json` | | `gemini-cli` | `.gemini/settings.json` | `~/.gemini/settings.json` | | `devin` | `.devin/mcp_config.json` | `~/.config/devin/mcp_config.json` | | `windsurf` | | `~/.codeium/windsurf/mcp_config.json` | | `zed` | | `~/.config/zed/settings.json` | | `antigravity` | | `~/.gemini/config/mcp_config.json` | | `claude-desktop` | | Claude Desktop `claude_desktop_config.json` | Agents with no project config get the user config. ## Options One or more agents to configure. Defaults to the agents detected in the project and on your machine. `project` writes a file in the current directory that you can commit. `user` writes the config for your machine only. Path to the Momentic config file to pass to the server. Project configs store it relative to the project root. Write this API key into the config as `MOMENTIC_API_KEY`. Write your saved API key into the config. Do not use this for files that you commit to Git. Without it, the server reads `MOMENTIC_API_KEY` from your environment or from `~/.momentic/auth.json` after `npx momentic-mobile login`. Skip prompts and use the defaults. ## Examples Configure Cursor and Claude Code for the project: ```bash theme={null} npx momentic-mobile install-mcp --client cursor claude-code --scope project ``` Configure Codex for your user account with an explicit project config: ```bash theme={null} npx momentic-mobile install-mcp --client codex --scope user --config ./momentic.config.yaml ``` # momentic-mobile lint Source: https://momentic.ai/docs/cli-reference/momentic-mobile/commands/lint Validate Momentic simplified format mobile test and module YAML files. Validates 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 runs 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. When omitted, Momentic searches the current directory and its parents for `momentic.config.yaml` or a workspace configuration. Use this flag to select a project when discovery finds more than one. ## 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. Pipe the output 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. When omitted, Momentic searches the current directory and its parents for `momentic.config.yaml` or a workspace configuration. Use this flag to select a project when discovery finds more than one. 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 in a folder, then run the same folder: ```bash theme={null} npx momentic-mobile list tests/login npx momentic-mobile run tests/login ``` # momentic-mobile login Source: https://momentic.ai/docs/cli-reference/momentic-mobile/commands/login Sign in with your browser and save an API key on this machine. Prints a one-time code and opens the Momentic sign-in page in your browser. Confirm the code there. If your account belongs to more than one organization, the CLI asks which one to use. It then writes an API key for that organization to `~/.momentic/auth.json`. Every command reads that key when `--api-key` and `MOMENTIC_API_KEY` are not set. ```bash theme={null} npx momentic-mobile login ``` Run [`momentic-mobile whoami`](/docs/cli-reference/momentic-mobile/commands/whoami) to see the saved account and organization. Run `login` again to switch. In CI, or on a machine with no browser, skip `login` and set `MOMENTIC_API_KEY` instead. Create the key in the [dashboard](https://app.momentic.ai/settings/api-keys). `MOMENTIC_API_KEY` and `--api-key` take precedence over the saved file. ## Options Do not open a browser. The CLI still prints the code and the sign-in URL, so you can open the URL on another device. Use this over SSH or in a container. Momentic server URL. Defaults to the server saved in `~/.momentic/auth.json` from an earlier `login`, or `https://api.momentic.ai` when no file exists. Env: `MOMENTIC_SERVER`. # momentic-mobile logout Source: https://momentic.ai/docs/cli-reference/momentic-mobile/commands/logout Remove the API key saved by login. Deletes `~/.momentic/auth.json`. Commands then need `--api-key` or `MOMENTIC_API_KEY` until you run [`momentic-mobile login`](/docs/cli-reference/momentic-mobile/commands/login) again. ```bash theme={null} npx momentic-mobile logout ``` `logout` does not revoke the key on the server. To revoke it, delete the key in the [dashboard](https://app.momentic.ai/settings/api-keys). ## Options This command has no options. # 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`. This does not change the emulator UI. Set `headful` on `momentic_session_start` to override this default for a session. The legacy `headfulBrowser` parameter remains supported; `headful` takes precedence if both are provided. 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`. The server ends sessions idle past the timeout. 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 uses the config file's parent directory as its working directory, 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. ## 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` rewrites legacy mobile tests and modules discovered by the project's `include` and `exclude` settings through the simplified format serializer and sets `fileFormat: v2` on `momentic.config.yaml`. It does not change the rest of the project config (agent versions, `ai.useMemory`, `ai.failureRecovery`) and does not upgrade your installed CLI version. If you want the file rewrite plus a CLI version bump and 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. A migration error stops the command, and some files may already have been rewritten. Revert the local changes made by the command, fix the reported serialization error, and rerun the migration. Requires authentication through `login` or `MOMENTIC_API_KEY`. The migration writes identity snapshots so existing step caches can be reused after step IDs are omitted from YAML. This command has no `--dry-run` option; use the upgrade preview to inspect conversion counts for a legacy-format project. If the config already says v2, that preview skips file discovery and does not report leftover legacy files. Follow the [migration guide](/docs/get-started/migrate-to-simplified-format) for validation and rollback. ## Options Path to the Momentic configuration file. When omitted, Momentic searches the current directory and its parents for `momentic.config.yaml` or a workspace configuration. Use this flag to select a project when discovery finds more than one. Momentic API key. Defaults to `MOMENTIC_API_KEY`, then the key saved by `login` in `~/.momentic/auth.json`. Skip the migration confirmation prompt. Start from a backed-up, clean working tree. ## 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. Manages 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`. Omit this argument when results are in the default folder. ### Options Exit successfully without uploading when the results path does not exist. ## `merge` Merge results from multiple sharded mobile runs into a single folder before uploading. ```bash theme={null} npx momentic-mobile results merge test-results --output-dir merged-results ``` ### 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 with zero runs and skip merging when no run groups exist. Use this in CI when an earlier job may have produced no test results. ## `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, such as `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, the run writes results 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. When omitted, Momentic searches the current directory and its parents for `momentic.config.yaml` or a workspace configuration. Use this flag to select a project when discovery finds more than one. 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. Uses the project's `parallel` setting, then `1`. Pass `AUTO` to run every test in the current shard concurrently. 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. Use `--parallel 1` for local iOS runs to avoid concurrent sessions sharing a device-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 app build selection (e.g. `staging`, `dev`). When omitted, falls back to the test's default channel; if the test has none, no app build is installed during device 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; if the test has no default, the latest uploaded build for the test's platform in the channel applies. ## 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 all selected tests and apply quarantined tests' statuses to the pipeline status and exit code. Use it to verify fixes before unquarantining. ## 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 existing step caches. Saving still follows the normal branch rules; add `--save-cache` to save on protected branches. Use it to refresh 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; the run creates missing goldens 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). Use it for CI logs, which do not render the `list` reporter's in-place redraws. File reporters write post-run output to `--reporter-dir`. Mobile runs support: * `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 CLI prints current results. ## 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 skills Source: https://momentic.ai/docs/cli-reference/momentic-mobile/commands/skills Install the Momentic skills for your coding agent. Installs the Momentic skills into your repository and adds an always-on pointer to your coding agent's instructions file. See [Coding agent skills](/docs/coding-agents/skills) for what the skills contain and how updates work. ```bash theme={null} npx momentic-mobile skills ``` Without flags, the command asks which coding agents you use. It preselects the agents it detects in the repository. `momentic-mobile install-skills` is an alias for `momentic-mobile skills`. The old `--editor ` flag still works and behaves like `--target --yes`. ## Options Coding agents to install for. Skips the agent prompt. One or more of `claude-code`, `cursor`, `codex`, `copilot`, or `opencode`. Skip all prompts. Installs for the agents detected in the repository, or for the agents in `--target`. ## Install location Inside a git repository, the skills install at the repository root. Outside git, they install in the current directory. | Agent | Skills | Pointer | | - | - | - | | `claude-code` | `.claude/skills//` | `CLAUDE.md` | | `cursor` | `.cursor/skills//` | `.cursor/rules/momentic-skills.mdc` | | `codex` | `.agents/skills//` | `AGENTS.md` | | `copilot` | `.github/skills//` | `.github/copilot-instructions.md` | | `opencode` | `.opencode/skills//` | `AGENTS.md` | The command installs the shared skills (`momentic-spec`, `momentic-maintain`, `momentic-triage-quarantined-tests`) and `momentic-mobile-test`. It keeps skills that `momentic skills` or `qa skills` installed. ## Examples Install for Claude Code and Cursor without prompts: ```bash theme={null} npx momentic-mobile skills --target claude-code cursor ``` Install for the detected agents in CI or an agent shell: ```bash theme={null} npx momentic-mobile skills --yes ``` # 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` keeps a Momentic mobile project current in one command. It installs the latest matching CLI release, switches the project to the simplified format, refreshes recommended agent versions, and enables `ai.useMemory` and `ai.failureRecovery`. It converts included legacy mobile tests and modules when the project is still configured for the legacy format. An agent pin is retained if it matches the current recommendation or extends that recommendation with a sub-version (for example, `v5.0` when the recommendation is `v5`). Older pins can be replaced, and disabled memory or failure recovery settings are enabled. Review the dry-run config diff. The command skips files already using the simplified format. When the file format and recommended AI settings are current, it leaves project files unchanged; the CLI package installation can still update the installed version. If the config already has `fileFormat: v2` but legacy files remain, use the explicit migration command to convert them. For the YAML rewrite alone, without 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`. 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. The real upgrade installs the CLI before conversion. A failure can leave package/lockfile changes and partial YAML rewrites. Follow the [migration and validation procedure](/docs/get-started/migrate-to-simplified-format) before retrying or committing the result. ## Options Path to the Momentic configuration file. When omitted, Momentic searches the current directory and its parents for `momentic.config.yaml` or a workspace configuration. Use this flag to select a project when discovery finds more than one. Momentic API key. Defaults to `MOMENTIC_API_KEY`, then the key saved by `login` in `~/.momentic/auth.json`. Skip confirmation prompts. Start from a backed-up, clean working tree. 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. Requires authentication through `login` or `MOMENTIC_API_KEY`; does not run tests. ## 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 whoami Source: https://momentic.ai/docs/cli-reference/momentic-mobile/commands/whoami Show the account and organization for your API key. Prints the account that your API key belongs to: name, email, user ID, organization ID, the Momentic server, and where the key came from (`--api-key`, `MOMENTIC_API_KEY`, or `~/.momentic/auth.json`). Use it to confirm which organization your CLI commands will run in before you run tests. ```bash theme={null} npx momentic-mobile whoami ``` ## Options Momentic API key. Defaults to `MOMENTIC_API_KEY` or the key saved by [`momentic-mobile login`](/docs/cli-reference/momentic-mobile/commands/login). Momentic API server address. Defaults to `MOMENTIC_SERVER` or the server saved with your login. If you override the key with `--api-key` or `MOMENTIC_API_KEY` without setting `--server` or `MOMENTIC_SERVER`, it uses `https://api.momentic.ai` instead of the saved server. # 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 runs mobile tests locally and in CI. Install it as a dev dependency, then invoke commands via `npx momentic-mobile `. ## Install Use Node.js 22.12 or later in the 22.x series, or Node.js 24 or later. Node.js 23 is not supported. ```bash theme={null} npm install --save-dev momentic-mobile ``` Commands that load tests need a `momentic.config.yaml`. Run [`init`](/docs/cli-reference/momentic-mobile/commands/init) in the project directory to create one. Commands such as `login`, `logout`, and `assets` work without a project config. ## Commands Scaffold a new mobile project. Open the local mobile editor. Run mobile tests on local or remote emulators and simulators. 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. Show the account and organization for your API key. Upload and manage APK and `.app` builds. Start the mobile MCP server for coding agents. Install Chromium-based browsers locally (deprecated). Install the Momentic skills for your coding agent. ## Global flags These flags are shared by several commands. Check `npx momentic-mobile --help` for the flags a command accepts; for example, `login` accepts `--server` but does not accept `--api-key`. Momentic API key. Defaults to the value in `~/.momentic/auth.json`. Env: `MOMENTIC_API_KEY`. Momentic server URL. Defaults to the server saved by `momentic-mobile login`, then `https://api.momentic.ai`. Env: `MOMENTIC_SERVER`. Absolute or relative path to a Momentic configuration file. Defaults to the nearest `momentic.config.yaml` in the current directory or a parent directory, or projects listed in a workspace file. When using [workspaces](/docs/configuration/workspace), load the project whose name exactly matches the filter. 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` | API key. Overrides the key saved by `momentic-mobile login`. | | `MOMENTIC_SERVER` | Override the API host. | | `ANDROID_HOME` | Android SDK root. Required for all Android runs, remote included. | | `ANDROID_SDK_ROOT` | Alternative to `ANDROID_HOME`. | | `JAVA_HOME` | Java home directory used by local Android runs. | ## Errors A command that fails on an error such as invalid arguments, a missing credential, an API failure, or a broken local environment exits with a non-zero code, prints the reason, and writes one machine-readable line to stderr that a CI job or coding agent can parse without scraping the human output: ```text theme={null} momentic-mobile-error: {"code":"MOB_AUTH_REQUIRED","group":"auth","retry":"no","attribution":"user-action","message":"..."} ``` `code` is a stable `MOB_*` identifier. `group` is one of `args`, `auth`, `api`, `env`, `run`, or `internal`. `retry` is `yes`, `no`, or `case-by-case`. `attribution` says who owns the fix: `user-action` for input or credentials, `user-env` for the local machine or project configuration, `product` for a Momentic bug, or `unknown`. A run whose tests fail exits non-zero without this line; read the reporter output or results instead. `--help` and `--version` exit `0`. # momentic ai Source: https://momentic.ai/docs/cli-reference/momentic/commands/ai AI-assisted test selection, classification, and repair. AI subcommands for test selection, classification, and repair. Use them 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` Analyzes the current git diff and returns 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. If omitted, no test-count cap applies. Additional selection guidance appended to the built-in AI test selection instructions. Repeatable; values are appended in command-line order. 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. Minimum: 60. The selector reserves time to finalize gathered evidence before the deadline. If it cannot recover a selection, it returns a run-all fallback. Slow billing or telemetry does not discard a completed selection. See [AI test selection](/docs/ai/select) for GitHub Actions setup, code-index caching, fail-open behavior, and benchmark results. ## `classify` Classifies 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`. The command classifies only failed runs and skips passing runs. Provide exactly one selector: a positional run ID or URL, `--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. Multiple runs cannot use `--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. Use it to resume a partially completed batch. Number of runs to classify in parallel when targeting a run group or commit. Defaults to `4`. The run banner shows the effective value. 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, the command saves each run as it finishes. New result-classification cache entries are written only when `--save` is set and `--no-cache` is not 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. Without `--no-cache`, `--save` also allows successful classifications to 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, or related runs) 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 only that turn. ### Output By default, the classification is printed as plain text: ```text theme={null} 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; the command still classifies the remaining runs and reports the errors 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 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 another 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-save` to skip persisting triage metadata and uploading the local archive. 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). 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`, `--git-commit`, or `--from-quarantine`. ### 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 command skips the run-group risk summary for this scope. Triage every failed run recorded at the given git commit SHA, flat across all run groups. The command skips the run-group risk summary for this scope. Heal the active quarantine backlog instead of a specific results set. The command processes 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`, `--skip-quarantined`, or `--ignore-quarantine`. 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-save` to skip persisting triage metadata and uploading the archive. 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 persist triage heal metadata to the local results archive or cloud runs, or automatically upload the local archive. This does not prevent the agent from editing test files or applying the configured repair delivery. Deprecated alias for `--no-save`. It also disables metadata persistence when targeting uploaded runs or run groups. ### Common flags Path to the Momentic configuration file. When omitted, Momentic searches the current directory and its parents for `momentic.config.yaml` or a workspace configuration. Use this flag to select a project when discovery finds more than one. 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. Uses the project's `parallel` setting, then `1`. Pass `auto` to size concurrency from the host's CPU count. 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 so Momentic can help debug your agent's failure. Leave it off unless Momentic asks for it. ### 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 with a visible UI by default. Useful for watching the agent work. Env: `MOMENTIC_HEADFUL_BROWSER`. The legacy `--headful-browser` flag remains an alias. 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 the agent heals failures from scratch. It still saves newly successful heals; step caches are unaffected. ### Quarantine Skip quarantined tests during triage. Disabled by default, so healing includes quarantined failures. Only attempt to heal quarantined tests. The command ignores failed runs outside quarantine. ### Recovery Skip tests that passed via 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. Use it to start 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 command writes the current results. 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 failures or errors remain. * `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; you review and merge the delivered fix (e.g. a pull request). * `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 two 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 for the project defined by `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. When omitted, Momentic searches the current directory and its parents for `momentic.config.yaml` or a workspace configuration. Use this flag to select a project when discovery finds more than one. 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 step cache state for the session. Saving still follows the normal branch rules; add `--save-cache` to save on protected branches. Use it to refresh 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 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. When omitted, Momentic searches the current directory and its parents for `momentic.config.yaml` or a workspace configuration. Use this flag to select a project when discovery finds more than one. When using [workspaces](/docs/configuration/workspace), load the project whose name matches the filter. ### Patch selection Patch name or ID, such as three dash-separated words like `potato-apple-cherry`. Name or ID 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. Runs 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 legacy YAML files to make them unique. Simplified format projects delegate to `lint`, which reports conflicts without fixing them. ## `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 reachable from any test. The check follows module references and finds `.module.yaml` files left unused 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. When omitted, Momentic searches the current directory and its parents for `momentic.config.yaml` or a workspace configuration. Use this flag to select a project when discovery finds more than one. ## 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. * 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. Doctor lists each problem at the end with a suggested fix, and the command exits non-zero when it finds any. Warnings do not affect the exit code. ```bash theme={null} npx momentic doctor ``` If `doctor` reports no problem but a run still fails, see [Common problems](/docs/account/common-problems). ## Options Momentic API key. Defaults to `MOMENTIC_API_KEY`, then the key saved by `login` in `~/.momentic/auth.json`. Path to the Momentic configuration file. When omitted, Momentic searches the current directory and its parents for `momentic.config.yaml` or a workspace configuration. Use this flag to select a project when discovery finds more than one. Remove deprecated options from the project configuration file. Output the report as JSON. Attach it to a support ticket. ## 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 web tests and their referenced modules into the current directory. You can import individual tests by their dashboard path, the tests in a cloud folder and its nested subfolders, or omit arguments to import the workspace, including environments. Imports with explicit paths do not import environments. 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 ``` Run from the directory where imported files should live, usually the web project root. `--config` selects configuration; it does not change the working directory or the destination of new files. Requires an existing project config and authentication with `login` or `MOMENTIC_API_KEY`. The importer uses the project's `fileFormat` setting when writing YAML. Existing files can be overwritten after confirmation; a full workspace import can also overwrite the base URL and variables in environments with matching names. Imported environment variables can contain plaintext secrets: move them to [runtime secrets](/docs/configuration/environments#secrets) before committing. For a validated cloud-to-repository migration, follow [Cloud deprecation](/docs/get-started/cloud-deprecation#after-importing). Unused standalone modules are not included. Check them separately before retiring the cloud project. This command does not import mobile tests. ## 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, the command imports the workspace's web tests, their referenced modules, and environments. ## Options Path to the Momentic configuration file. When omitted, Momentic searches the current directory and its parents for `momentic.config.yaml` or a workspace configuration. Use this flag to select a project when discovery finds more than one. Momentic API key. Defaults to `MOMENTIC_API_KEY`, then the key saved by `login` in `~/.momentic/auth.json`. Skip confirmation prompts, including file and environment overwrite prompts. Keep prompts enabled for the first import into an existing project. ## How folder import works * Folder paths are matched against the dashboard's folder tree case-insensitively. `auth/onboarding` matches the cloud folder named `Onboarding` nested under `Auth`. * Tests inside the folder and its nested subfolders are imported, together with the modules they reference. Referenced modules can live outside that folder; unused modules inside the folder are not included. * The cloud folder hierarchy is recreated on disk. A test in cloud folder `Auth/Onboarding` lands at `auth/onboarding/.test.yaml` relative to the current working directory. Folder names are slugified the same way test names are. * In a simplified-format project, an imported test or module with the same ID as a local file keeps that file's current location. Otherwise, the target path is derived from the dashboard folder and entity name. ## Examples Import the workspace's web tests, referenced modules, and environments: ```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 a cloud folder's tests and their referenced modules, 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) in the current directory. The command refuses to run if that file already exists. Use the onboarding wizard below when you also want sample tests and modules. ```bash theme={null} npx momentic init ``` `init` scaffolds new projects with `fileFormat: v2`. The [onboarding wizard](https://www.npmjs.com/package/@momentic/wizard) emits sample tests and modules 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 command 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 --yes --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 a Momentic-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-mcp Source: https://momentic.ai/docs/cli-reference/momentic/commands/install-mcp Add the Momentic MCP server to your coding agent config. Writes the Momentic MCP server into the config file of one or more coding agents. You do not need to edit JSON or TOML by hand. See the [MCP guide](/docs/coding-agents/mcp-server) for the tools the server exposes. ```bash theme={null} npx momentic install-mcp ``` In a terminal, the command asks which agents to configure and where to save the config. It preselects the agents it detects in the project and on your machine. Outside a terminal, or with `--yes`, it writes the project config for every detected agent. The command adds a `momentic` server entry that runs `npx -y momentic mcp`. It keeps other servers in the file and comments in JSON files. ## Supported agents | `--client` | Project config | User config | | - | - | - | | `claude-code` | `.mcp.json` | `~/.claude.json` | | `cursor` | `.cursor/mcp.json` | `~/.cursor/mcp.json` | | `vscode` | `.vscode/mcp.json` | VS Code `User/mcp.json` | | `codex` | `.codex/config.toml` | `~/.codex/config.toml` | | `opencode` | `opencode.json` | `~/.config/opencode/opencode.json` | | `gemini-cli` | `.gemini/settings.json` | `~/.gemini/settings.json` | | `devin` | `.devin/mcp_config.json` | `~/.config/devin/mcp_config.json` | | `windsurf` | | `~/.codeium/windsurf/mcp_config.json` | | `zed` | | `~/.config/zed/settings.json` | | `antigravity` | | `~/.gemini/config/mcp_config.json` | | `claude-desktop` | | Claude Desktop `claude_desktop_config.json` | Agents with no project config get the user config. ## Options One or more agents to configure. Defaults to the agents detected in the project and on your machine. `project` writes a file in the current directory that you can commit. `user` writes the config for your machine only. Path to the Momentic config file to pass to the server. Project configs store it relative to the project root. Write this API key into the config as `MOMENTIC_API_KEY`. Write your saved API key into the config. Do not use this for files that you commit to Git. Without it, the server reads `MOMENTIC_API_KEY` from your environment or from `~/.momentic/auth.json` after `npx momentic login`. Skip prompts and use the defaults. ## Examples Configure Cursor and Claude Code in the project: ```bash theme={null} npx momentic install-mcp --client cursor claude-code --scope project ``` Write the Codex user config with a specific Momentic config file: ```bash theme={null} npx momentic install-mcp --client codex --scope user --config ./momentic.config.yaml ``` # 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 runs 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. When omitted, Momentic searches the current directory and its parents for `momentic.config.yaml` or a workspace configuration. Use this flag to select a project when discovery finds more than one. ## 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.test.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. Pipe it 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. When omitted, Momentic searches the current directory and its parents for `momentic.config.yaml` or a workspace configuration. Use this flag to select a project when discovery finds more than one. 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 [Permanent healing](/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 run the same selection: ```bash theme={null} npx momentic list --labels smoke npx momentic run --labels smoke ``` Validate a Permanent healing PR by running only the tests it changed. This Bash example preserves spaces in paths and skips `run` when the list is empty; calling `run` without paths would run the whole project: ```bash theme={null} test_paths=$(npx momentic list --changed) || exit $? tests=() while IFS= read -r test; do [[ -n "$test" ]] && tests+=("$test") done <<<"$test_paths" if ((${#tests[@]})); then npx momentic run "${tests[@]}" --upload-results fi ``` # momentic login Source: https://momentic.ai/docs/cli-reference/momentic/commands/login Sign in with your browser and save an API key on this machine. Prints a one-time code and opens the Momentic sign-in page in your browser. Confirm the code there. If your account belongs to more than one organization, the CLI asks which one to use. It then writes an API key for that organization to `~/.momentic/auth.json`. Every command reads that key when `--api-key` and `MOMENTIC_API_KEY` are not set. ```bash theme={null} npx momentic login ``` Run [`momentic whoami`](/docs/cli-reference/momentic/commands/whoami) to see the saved account and organization. Run `login` again to switch. In CI, or on a machine with no browser, skip `login` and set `MOMENTIC_API_KEY` instead. Create the key in the [dashboard](https://app.momentic.ai/settings/api-keys). `MOMENTIC_API_KEY` and `--api-key` take precedence over the saved file. ## Options Do not open a browser. The CLI still prints the code and the sign-in URL, so you can open the URL on another device. Use this over SSH or in a container. Momentic server URL. Defaults to the server saved in `~/.momentic/auth.json` from an earlier `login`, or `https://api.momentic.ai` when no file exists. Env: `MOMENTIC_SERVER`. # momentic logout Source: https://momentic.ai/docs/cli-reference/momentic/commands/logout Remove the API key saved by login. Deletes `~/.momentic/auth.json`. Commands then need `--api-key` or `MOMENTIC_API_KEY` until you run [`momentic login`](/docs/cli-reference/momentic/commands/login) again. ```bash theme={null} npx momentic logout ``` `logout` does not revoke the key on the server. To revoke it, delete the key in the [dashboard](https://app.momentic.ai/settings/api-keys). ## Options This command has no options. # 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`. The legacy `--headful-browser` flag remains an alias. Set `headful` on `momentic_session_start` to override this default for a session. The legacy `headfulBrowser` parameter remains supported; `headful` takes precedence if both are provided. Override the viewport device pixel ratio used for browser rendering. Defaults to `2` on macOS Retina and `1` elsewhere. Record video of browser sessions. 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 save no caches. ## Session Idle timeout for MCP sessions in minutes. Defaults to `5`. The server ends sessions that stay inactive for this duration. 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 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` migrates local test and module files. It rewrites legacy web tests and modules discovered by the project's `include` and `exclude` settings 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. To also update the CLI version and 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. A migration error stops the command, and some files may already have been rewritten. Revert the local changes made by the command, fix the reported serialization error, and rerun the migration. Requires authentication through `login` or `MOMENTIC_API_KEY`. The migration writes identity snapshots so existing step caches can be reused after step IDs are omitted from YAML. This command has no `--dry-run` option; use the upgrade preview to inspect conversion counts for a legacy-format project. If the config already says v2, that preview skips file discovery and does not report leftover legacy files. Follow the [migration guide](/docs/get-started/migrate-to-simplified-format) for validation and rollback. ## Options Path to the Momentic configuration file. When omitted, Momentic searches the current directory and its parents for `momentic.config.yaml` or a workspace configuration. Use this flag to select a project when discovery finds more than one. Momentic API key. Defaults to `MOMENTIC_API_KEY`, then the key saved by `login` in `~/.momentic/auth.json`. Skip the migration confirmation prompt. Start from a backed-up, clean working tree. ## 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 counting toward 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.test.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 the 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 enabled dashboard test in the organization instead of only the named tests. The current CLI still requires a positional test name with this legacy flag; prefer `momentic run` for local and CI execution. 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. Use it to run 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 provides 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 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`; pass a different folder when your results are elsewhere. ### Options Exit successfully without uploading when the results path does not exist. ## `merge` Merge results from multiple sharded runs into a single folder before uploading. ```bash theme={null} npx momentic results merge test-results --output-dir merged-results ``` ### 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 no-op instead of an error. Recommended whenever AI test 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, such as `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 clean 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, such as the `--output-dir` of a preceding `momentic results merge`. ### Options Treat runs that passed via in-run failure recovery as clean (exit `0`). Exit successfully when the results path does not exist. A results archive with zero runs is already accepted without this flag. 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 go 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 ``` The same command runs end-to-end tests on your machine before you push and in CI after you push. Locally, pass a test path or `--ai-select` to run only the tests your change affects, and `--start` to boot the dev server first. See [Run before you push](#run-before-you-push). ## 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. When omitted, Momentic searches the current directory and its parents for `momentic.config.yaml` or a workspace configuration. Use this flag to select a project when discovery finds more than one. 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. Uses the project's `parallel` setting, then `1`. Pass `auto` to size concurrency from the host's CPU count. New projects created by `momentic init` use `auto`. 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. Wait between steps for the selected tests in this run. Accepts `0` to `10000` milliseconds. Overrides project, environment, and per-test `slowMoMs` settings without changing YAML files or organization defaults. Pass `0` to disable inherited slow motion. Without this flag, project settings are overridden by environment settings, then per-test settings. Run only regression-labelled tests with a 500 ms pause between steps: ```bash theme={null} momentic run --labels regression --slow-mo 500 ``` The first executed step in each step list has no delay. A single-step list has no delay. See [Execution timing](/docs/configuration/browser#execution-timing). ## Environment Run every test in this invocation on hosted browsers in one Browser Fleet region: `westus3` or `eastus2`. The flag turns on hosted browsers for the run even when `browser.remoteBrowser` is unset. The run fails instead of falling back when that region cannot serve it, and runs through a private Connector cannot use it. See [Regions](/docs/running-tests/hosted-test-environments#regions). 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. Use it to run 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 provides 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. Repeat to append values 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 and apply their statuses to pipeline status and the exit code. Run every test and apply all statuses to pipeline status and exit code. ## Classification Lets the classification verdict override this run's exit code. Failures that classification routes to heal or warn exit `0`. Takes precedence over `ai.classification.overrideExitCode` in `momentic.config.yaml` 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 the run saves no caches. 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 existing step caches. Saving still follows the normal branch rules; add `--save-cache` to save on protected branches. Use it to refresh caches after a config change. Steps run without cached data, which increases run time. Not recommended for ongoing use. Bust the oldest `n%` of step caches before the run. Use it to regenerate caches gradually 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). Modules, environment data, and step caches come from the zip, and the cache backend is never read from or written to. A Momentic API key and project config are still required. This option cannot be combined with test paths, `--include`, `--exclude`, `--labels`, `--ai-select`, `--input-csv`, or `--only-quarantined`. ## 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 the project's `outputDir` or `./test-results`. The run writes a live `progress.json` to the top of this directory and updates it 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). Use it for CI logs, which do not 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. Use it to boot 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 the limit hits, running tests stop, results flush to disk, and the process exits with code `1`. Emit run diagnostics using standard OpenTelemetry exporter environment variables. Configure exporter endpoints via `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 before you push Commit your changes, then run the end-to-end tests they affect against a local dev server before you open a pull request. `--start` boots the server, `--wait-on` holds the run until it answers, and `--ai-select` picks tests from the committed diff between `origin/main` and `HEAD`, so uncommitted edits do not count: ```bash theme={null} npx momentic run \ --start "pnpm dev" \ --wait-on http-get://localhost:3000 \ --url-override http://localhost:3000 \ --ai-select --ai-select-base origin/main ``` Results stay in `./test-results` unless you pass `--upload-results`. To run one flow instead of a selection, pass its path: ```bash theme={null} npx momentic run tests/checkout --start "pnpm dev" --wait-on http-get://localhost:3000 --url-override http://localhost:3000 ``` See [Common CI setups](/docs/guides/common-setups) for the matching pull request check. 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). Replace the example IDs with the test IDs printed by `snapshot`: ```bash theme={null} npx momentic run --from-snapshot checkout-test-id.snapshot.zip login-test-id.snapshot.zip ``` To validate a [Permanent healing PR](/docs/reliability/auto-maintenance#permanent-healing), use [`momentic list --changed`](/docs/cli-reference/momentic/commands/list#examples) and run the returned paths. The example checks for an empty list before calling `run`. # momentic skills Source: https://momentic.ai/docs/cli-reference/momentic/commands/skills Install the Momentic skills for your coding agent. Installs the Momentic skills into your repository and adds an always-on pointer to your coding agent's instructions file. See [Coding agent skills](/docs/coding-agents/skills) for what the skills contain and how updates work. ```bash theme={null} npx momentic skills ``` Without flags, the command asks which coding agents you use. It preselects the agents it detects in the repository. `momentic install-skills` is an alias for `momentic skills`. The `--editor ` flag still works and behaves like `--target --yes`. ## Options Coding agents to install for. Skips the agent prompt. One or more of `claude-code`, `cursor`, `codex`, `copilot`, or `opencode`. Skip all prompts. Installs for the agents detected in the repository, or for the agents in `--target`. ## Install location Inside a Git repository, the skills install at the repository root. Outside Git, they install in the current directory. | Agent | Skills | Pointer | | - | - | - | | `claude-code` | `.claude/skills//` | `CLAUDE.md` | | `cursor` | `.cursor/skills//` | `.cursor/rules/momentic-skills.mdc` | | `codex` | `.agents/skills//` | `AGENTS.md` | | `copilot` | `.github/skills//` | `.github/copilot-instructions.md` | | `opencode` | `.opencode/skills//` | `AGENTS.md` | The command installs the shared skills (`momentic-spec`, `momentic-maintain`, `momentic-triage-quarantined-tests`) and `momentic-test`. It keeps skills that `momentic-mobile skills` or `qa skills` installed. ## Examples Install for Claude Code and Cursor without prompts: ```bash theme={null} npx momentic skills --target claude-code cursor ``` Install for the detected agents in CI or an agent shell: ```bash theme={null} npx momentic skills --yes ``` # momentic snapshot Source: https://momentic.ai/docs/cli-reference/momentic/commands/snapshot Freeze resolved tests, environments, and caches into snapshot zips for replay. Creates a **test snapshot**: a `.snapshot.zip` with a resolved test, expanded modules, step caches, environment variables, and the relevant project config. Replay it with [`momentic run --from-snapshot`](/docs/cli-reference/momentic/commands/run#snapshots) without the original test files, modules, environment files, or cache backend. Replay still requires a Momentic API key and a `momentic.config.yaml`. Use the CLI version that created the snapshot: another version prints a warning and may replay it differently. ```bash theme={null} npx momentic snapshot checkout.test.yaml login.test.yaml ``` The command writes one zip 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`: an encrypted resolved test, including metadata and the fully expanded before, main, and after steps with step caches inlined. * `metadata.json`: readable fields (`momenticVersion`, `schemaVersion`, `createdAt`, `relativeFilePath`, environment name, base URL, and the frozen project config: `browser`, `ai`, `advanced`, `retries`). Environment variable values and resolved environment data are stored in an encrypted field. 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. When omitted, Momentic searches the current directory and its parents for `momentic.config.yaml` or a workspace configuration. Use this flag to select a project when discovery finds more than one. 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. Use it to capture a snapshot 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 the produced zips. Replace the example IDs with the test IDs printed by `snapshot`; filenames use test IDs, not test names: ```bash theme={null} npx momentic run --from-snapshot ./snapshots/checkout-test-id.snapshot.zip ./snapshots/login-test-id.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` updates the installed CLI and the project configuration. It: * installs the latest matching CLI release, * sets `fileFormat: v2`, * refreshes recommended agent versions and enables `ai.useMemory` and `ai.failureRecovery`, and * converts included legacy test and module files when the project is still configured for the legacy format. An agent pin is retained if it matches the current recommendation or extends that recommendation with a sub-version (for example, `v5.0` when the recommendation is `v5`). Older pins can be replaced, and disabled memory or failure recovery settings are enabled. Review the dry-run config diff. The command skips files already using the simplified format. When the file format and recommended AI settings are current, it leaves project files unchanged; the CLI package installation can still update the installed version. If the config already has `fileFormat: v2` but legacy files remain, use the explicit migration command to convert them. For only 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. The real upgrade installs the CLI before conversion. A failure can leave package/lockfile changes and partial YAML rewrites. Follow the [migration and validation procedure](/docs/get-started/migrate-to-simplified-format) before retrying or committing the result. ## Options Path to the Momentic configuration file. When omitted, Momentic searches the current directory and its parents for `momentic.config.yaml` or a workspace configuration. Use this flag to select a project when discovery finds more than one. Momentic API key. Defaults to `MOMENTIC_API_KEY`, then the key saved by `login` in `~/.momentic/auth.json`. Skip confirmation prompts. Start from a backed-up, clean working tree. 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. Requires [authentication](/docs/cli-reference/momentic/commands/login) with a saved login or an API key; does not run tests. ## 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 whoami Source: https://momentic.ai/docs/cli-reference/momentic/commands/whoami Show the account and organization for your API key. Prints the account that your API key belongs to: name, email, user ID, organization ID, the Momentic server, and where the key came from (`--api-key`, `MOMENTIC_API_KEY`, or `~/.momentic/auth.json`). Use it to confirm which organization your CLI commands run in before you run tests. ```bash theme={null} npx momentic whoami ``` ## Options Momentic API key. Defaults to `MOMENTIC_API_KEY` or the key saved by [`momentic login`](/docs/cli-reference/momentic/commands/login). Momentic API server address. Defaults to `MOMENTIC_SERVER` or the server saved with your login. If you override the key with `--api-key` or `MOMENTIC_API_KEY` without setting `--server` or `MOMENTIC_SERVER`, it uses `https://api.momentic.ai` instead of the saved server. # 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 Use Node.js 22.12 or later in the 22.x series, or Node.js 24 or later. Node.js 23 is not supported. ```bash theme={null} npm install --save-dev momentic ``` Commands that load tests need a `momentic.config.yaml`. Run [`init`](/docs/cli-reference/momentic/commands/init) in the project directory to create one. Commands such as `login`, `logout`, and `install-browsers` work without a project config. ## 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. Show the account and organization for your API key. Import tests from the Momentic dashboard. Apply patch changes to local tests (deprecated). Quarantine or unquarantine tests. Select tests, classify failures, and repair tests. Start the MCP server for coding agents. Install or update headless browsers. Install the Momentic skills for your coding agent. ## Global flags These flags are shared by several commands. Check `npx momentic --help` for the flags a command accepts; for example, `login` accepts `--server` but does not accept `--api-key`. Momentic API key. Defaults to the value in `~/.momentic/auth.json`. Env: `MOMENTIC_API_KEY`. Momentic server URL. Defaults to the server saved by `momentic login`, then `https://api.momentic.ai`. Env: `MOMENTIC_SERVER`. Absolute or relative path to a Momentic configuration file. Defaults to the nearest `momentic.config.yaml` in the current directory or a parent directory, or projects listed in a workspace file. When using [workspaces](/docs/configuration/workspace), load the project whose name exactly matches the filter. Skip all confirmation prompts. Enabled by default when `CI` is set. Enable verbose logging to stderr. ## Environment variables | Variable | Purpose | | - | - | | `MOMENTIC_API_KEY` | API key. Overrides the key saved by `momentic login`. | | `MOMENTIC_SERVER` | Override the API host. | See [Environment variables](/docs/configuration/environment-variables) for the full list. ## Errors A command that fails on an error such as invalid arguments, a missing credential, an API failure, or a broken local environment exits with a non-zero code, prints the reason, and writes one machine-readable line to stderr that a CI job or coding agent can parse without scraping the human output: ```text theme={null} momentic-error: {"code":"MOM_AUTH_REQUIRED","group":"auth","retry":"no","attribution":"user-action","message":"..."} ``` `code` is a stable `MOM_*` identifier. `group` is one of `args`, `auth`, `api`, `env`, `run`, or `internal`. `retry` is `yes`, `no`, or `case-by-case`. `attribution` says who owns the fix: `user-action` for input or credentials, `user-env` for the local machine or project configuration, `product` for a Momentic bug, or `unknown`. A run whose tests fail exits non-zero without this line; read the reporter output or results instead. `--help` and `--version` exit `0`. # Building with AI Source: https://momentic.ai/docs/coding-agents/building-with-ai Start Mo sessions from your coding agent, or install the skills and MCP server to create, run, and maintain repository tests. Use your coding agent to start [Mo](/docs/mo) sessions against a running app or to create and maintain [repository tests](/docs/core-concepts/file-format). Mo produces a session report. Repository tests are YAML files you review and run in CI. ## Test a running app with Mo Install the `qa` CLI and the `mo-qa` skill in your repository: ```bash theme={null} npm install -g qa qa skills --yes ``` Authenticate with `qa login` or `MOMENTIC_API_KEY`, then invoke the skill with your target and scope: ```text theme={null} /mo-qa test the checkout flow on https://staging.example.com. Do not submit payments. ``` The skill asks for missing sign-in steps, test data, and expected behavior, starts a hosted session, and exports the report. Mo does not require an MCP installation or YAML test files. See the [Mo quickstart](/docs/mo/quickstart), [Mo skill](/docs/coding-agents/skills#mo), and [Mo CLI](/docs/mo/cli). ## Create repository tests For web tests, paste this prompt into your coding agent. It checks your existing setup, installs missing tools, writes one test against your app, and runs it. You provide the app URL, test account, and expected behavior when asked. ```text theme={null} Help me set up Momentic web testing in this project. ## What to do 1. Find an API key. If `MOMENTIC_API_KEY` is set or `npx --yes momentic whoami` prints your user and Org ID, use it. If not, ask me to create a key at https://app.momentic.ai/settings/api-keys and run `export MOMENTIC_API_KEY=` — if your shell drops env vars between commands, prefix each `npx` command with `MOMENTIC_API_KEY=` instead. 2. Install the CLI. If `momentic.config.yaml` already exists, skip to step 3. Otherwise run `npx --yes @momentic/wizard@latest -y --platform web` in the project root — it needs a package.json, so run `npm init -y` first if there is none. - It installs `momentic`, writes `momentic.config.yaml`, `web/add-to-cart.test.yaml`, and `AGENTS.md`, ensures Chromium is installed, runs the sample test (which produces `test-results/`), and installs the Momentic skills. npm may print audit warnings during install — expected noise, keep going. It may also print 'Opening this run in your browser' or 'skipping editor validation' — both no-ops on headless agents. - If it fails `MWZ_ARGS_MISSING_CREDENTIALS` even with a key set, the env var didn't reach that shell — prefix the same command with `MOMENTIC_API_KEY=` and re-run. - Pass `--editor-tools` to pick agent integrations — `all`, `none`, or a comma list like `claude-code,cursor` (`skills` forces the skill install). 3. Install the skills and MCP server: the wizard already installed the skills — confirm `.agents/skills/momentic-test/SKILL.md` exists (re-run `npx momentic skills -y --target codex` if not). For MCP, list your tools for names starting with `momentic_` and try calling one — if you cannot list MCP tools, none are configured, or every call fails to initialize, count them absent and do not try to repair a broken server. Then run `npx momentic install-mcp -y` to set it up — 'Error: No coding agent detected' with a non-zero exit means auto-detection missed you, not that your agent is unsupported: if your client is in the supported list (claude-code, cursor, vscode, codex, opencode, windsurf, devin, zed, gemini-cli, antigravity, claude-desktop), re-run with `--client `; if it isn't, skip MCP and drive the Momentic CLI per the skill instead. 4. Confirm the sample test passed and `momentic.config.yaml` + `web/add-to-cart.test.yaml` exist. If you skipped the wizard, confirm `npx --yes momentic whoami` prints my user and Org ID. 5. Ask me which user flow to test first. The scaffolded sample test points at our demo app — don't touch `environments:` in `momentic.config.yaml` or `defaultEnv:` in tests; a new test needs neither of those keys — just set `url:` on it to the app I give you. Create the new test as `web/.test.yaml` alongside `web/add-to-cart.test.yaml` — leave the sample untouched. Assert only what is visible on screen when the action finishes — multi-step flows split fields across screens, so one assert for everything will fail. Load the `momentic-test` skill and write the test — with the Momentic MCP tools if they are wired, otherwise author the `*.test.yaml` directly per the skill and validate with `npx momentic lint`. 6. Run it with `npx momentic run --upload-results` — a single test can take several minutes, allow a long timeout; it prints 'Uploaded to Momentic. ' when it finishes, keep that link. Fixing the test and re-running is the loop, not a violation — only a retry with no changes, or hiding a failure, is off-limits. When a run fails, unzip its `.zip` file under `test-results/runs/` — it has screenshots, the DOM trace, and console output, the fastest way to see what went wrong before editing. If it keeps failing after real fixes, report the failure with the uploaded run link and stop, and show me the result. ## Critical rules - If `MOMENTIC_API_KEY` disappears between shell commands, prefix each `npx` command with it instead of relying on `export`. - Do not edit `momentic.config.yaml` unless I ask. - Do not create an API key for me. Ask me for one when you need it. - Write tests as `*.test.yaml` files. Do not write Playwright or Appium code. - Do not place real orders, send emails, or touch shared data while testing. - Run each new test before you tell me it is done. ## When done, point me to - Building with AI: https://momentic.ai/docs/coding-agents/building-with-ai - Test structure: https://momentic.ai/docs/core-concepts/file-format - Run in CI: https://momentic.ai/docs/running-tests/ci/github-actions ``` For mobile, use the setup prompt in the [iOS](/docs/quickstart/ios#setup-with-coding-agent) or [Android](/docs/quickstart/android#setup-with-coding-agent) quickstart. It also asks for your app build before creating a test. ### Review the first test Review the generated YAML diff and confirm the assertions match the behavior you asked for. Open the run URL the agent returns, check that the run passed, and inspect the screenshot at the assertion step. Resolve a failed or blocked run and rerun the test before [adding it to CI](/docs/running-tests/ci/github-actions). ### Install the tools yourself Use these commands to configure an existing project manually. The setup prompt above checks for these tools and installs them when needed. The MCP server gives the agent a live browser or device and tools to browse, edit, run, and triage tests. `install-mcp` detects the coding agents on your machine and writes the config for each one. ```bash Web theme={null} npx momentic install-mcp ``` ```bash Mobile theme={null} npx momentic-mobile install-mcp ``` Pass `--client` to pick agents and `--scope user` to write your user config instead of the project config. See the [MCP page](/docs/coding-agents/mcp-server) for manual setup per client. Skills are markdown instructions that tell the agent how to use the MCP tools and the Momentic test format. `momentic` ships the web skills, and `momentic-mobile` ships the mobile skills. ```bash Web theme={null} npx momentic skills ``` ```bash Mobile theme={null} npx momentic-mobile skills ``` The command writes the skill files to your agent's skills directory and adds a short pointer to `AGENTS.md` or `CLAUDE.md` so the agent loads the right skill before it writes Momentic code. The CLI asks once after an upgrade whether to refresh them. See [Coding agent skills](/docs/coding-agents/skills) for the directories and flags. ## Skills and the MCP server The skills explain the test format and authoring workflow. The MCP server lets the agent inspect your app and try steps while it writes a test. If MCP is unavailable, the setup prompt uses the CLI to validate and run YAML files. Mo sessions use the `qa` CLI and `mo-qa` skill. | | Skills | MCP server | | - | - | - | | What it is | `SKILL.md` files the agent reads | A local process the agent calls | | What it does | Teaches the test format, the CLI, and the triage steps | Gives the agent a live browser or device and the tools to use | | Installs to | `.claude/skills`, `.cursor/skills`, `.agents/skills`, and others | The MCP config of each client, such as `.mcp.json` | | Updates | The CLI asks once after an upgrade, or run `skills` again | Every start uses the CLI version in your project | | Works offline | Yes | No, it calls the Momentic API | | Best for | Test format and the order of tool calls | Preview, run, and repair steps against your app | Invoke a skill by name in your prompt, for example `/momentic-test write a test for checkout`. See [Use the skills](/docs/coding-agents/skills#use-the-skills) for the skill list and more examples. ## Use repository instructions If you use an agent without the skills or MCP server, add these instructions to `AGENTS.md`, `CLAUDE.md`, or `.cursor/rules`. You still need the Momentic CLI to validate and run the tests: ```md theme={null} ## Momentic This repo uses Momentic for end-to-end tests. Tests are `*.test.yaml` files and shared steps are `*.module.yaml` files under the directory named in `momentic.config.yaml`. Read https://momentic.ai/docs/llms.txt before you change a test. Run `npx momentic run ` to run a test locally. Do not write Playwright or Selenium code for end-to-end tests in this repo. ``` ## Related * [Mo quickstart](/docs/mo/quickstart) * [Mo CLI](/docs/mo/cli) * [MCP server](/docs/coding-agents/mcp-server) * [Coding agent skills](/docs/coding-agents/skills) * [Devin integration](/docs/integrations/devin) * [`momentic install-mcp`](/docs/cli-reference/momentic/commands/install-mcp) # 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 handles autonomous bug finding. [Sign up](https://momentic.ai/mo) for access. To write tests from a code diff, use the MCP server with the [`momentic-spec` skill](/docs/coding-agents/skills#spec-driven-development). Momentic's MCP server is a local process that gives a coding agent a live browser or device and tools to browse, edit, run, and triage tests. The [skills](/docs/coding-agents/skills) teach the agent which tools to call and in what order. Install both. Requires Momentic CLI 2.54.0 or later. ## 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` or an existing Momentic CLI sign-in available to the MCP process. Configure API keys in that process's environment rather than relying on the editor to inherit your shell environment. ## Setup instructions Run `install-mcp` to detect the coding agents on your machine. It writes the server entry into each one's config. Use `momentic-mobile install-mcp` for mobile projects; it registers a separate `momentic-mobile` server, so web and mobile can live in the same config. ```bash theme={null} npx momentic install-mcp ``` See [`momentic install-mcp`](/docs/cli-reference/momentic/commands/install-mcp) for `--client`, `--scope`, and noninteractive use. The tabs below show the command for each client and the manual config it writes. Momentic's MCP is a **local stdio server**. Every client ultimately runs one of these commands: ```bash Web theme={null} npx momentic mcp --config /absolute/path/to/momentic.config.yaml ``` ```bash Mobile theme={null} npx momentic-mobile mcp --config /absolute/path/to/momentic.config.yaml ``` The tabs below show the web command. For a mobile project, replace `momentic` with `momentic-mobile` in the command and use `momentic-mobile` as the server name. 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.). Both servers accept `--headful false`. For web, this launches headless browser sessions. For mobile, it skips the remote-control viewer without changing the emulator UI. Override the server default for one session with `headful` on `momentic_session_start`. Older releases use the names listed in CLI help and the tool schema: `--headful-browser` for web and `headfulBrowser` for session overrides. Those names remain supported.
After the server is registered, 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. ```bash theme={null} npx momentic install-mcp --client claude-code ``` Or register the server with the Claude Code CLI: ```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. Run `/mcp` to confirm the server is active. ```bash theme={null} npx momentic install-mcp --client cursor ``` Or 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" } } } } ``` ```bash theme={null} npx momentic install-mcp --client vscode ``` Or open the command palette, select **MCP: Add Server**, pick **Command (stdio)**, then paste: ```bash theme={null} 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} { "servers": { "momentic": { "type": "stdio", "command": "npx", "args": [ "momentic", "mcp", "--config", "/absolute/path/to/momentic.config.yaml" ], "env": { "MOMENTIC_API_KEY": "your-api-key" } } } } ``` Your org may need to allow MCP. Copilot only exposes MCP in agent mode. ```bash theme={null} npx momentic install-mcp --client codex ``` Or register the server with the Codex CLI: ```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. ```bash theme={null} npx momentic install-mcp --client opencode ``` Or 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 } } } ``` Use the [setup wizard](/docs/integrations/devin#set-up-with-the-wizard) to configure Momentic in Devin. You can also give Devin the [agent setup prompt](/docs/integrations/devin#setup-with-coding-agent). `install-mcp` also supports `gemini-cli`, `windsurf`, `zed`, `antigravity`, and `claude-desktop`. Any other MCP-compatible client can launch the server with: * Command: `npx` * Arguments: `momentic mcp --config /absolute/path/to/momentic.config.yaml` (mobile: `momentic-mobile mcp --config /absolute/path/to/momentic.config.yaml`) * Env: `MOMENTIC_API_KEY=your-api-key` ## Example prompts Choose a task and copy its prompt into your coding agent. Replace the test filenames and run ID with your own. For longer jobs, invoke a [skill](/docs/coding-agents/skills#use-the-skills) by name. The skill tells the agent which tools to call and in what order. ### Check the MCP connection ```text wrap theme={null} List the available Momentic MCP tools and call one to verify the connection. ``` ### Preview a test ```text wrap theme={null} Preview the steps in checkout.test.yaml using Momentic MCP. Show me the screenshots. ``` ### Run and repair a test ```text wrap theme={null} Run login.test.yaml using Momentic MCP. Inspect the failed step and screenshots before fixing the test, then rerun it and show me the result. ``` ### Inspect a past run ```text wrap theme={null} Show me the artifacts for Momentic run . ``` ### Lint test files ```text wrap theme={null} Lint all Momentic test files in this repository and fix the errors. ``` ### Look up documentation ```text wrap theme={null} Search the Momentic docs for how to wait for network idle. ``` ## Write your first test with the agent The agent writes a `.test.yaml`, runs it through the MCP server, reads the structured failure with the failed step, screenshot, and trace, then fixes its own test. Verify the server with `claude mcp list` in Claude Code, or turn it on in Cursor's MCP settings. Start a new chat. This web example uses an email-only login flow. Replace the URL and test account with your app's values, and adapt the steps to your login flow. Ask the agent to write a test with a base URL: ```text wrap theme={null} Use the Momentic MCP server and the `momentic-test` skill to write `login.test.yaml` in YAML. Set the top-level `url` to `https://app.example.com/login` and save the file in this repository. Enter `test@example.com` in the Email field, click Continue, and assert that the dashboard is visible after login. ``` Ask the agent to run the test and fix any failures: ```text wrap theme={null} Run `login.test.yaml` through the Momentic MCP server. Read any structured failure, including the failed step, screenshot, and trace. Fix the failing step in the test file, then run it again. ``` Review the resulting file, then commit it: ```bash theme={null} git add login.test.yaml git commit -m "Add login test" ``` The [`momentic-test` skill](/docs/coding-agents/skills#use-the-skills) covers the authoring flow, and [GitHub Actions](/docs/running-tests/ci/github-actions) runs the test in CI. The test opens the top-level `url` before it runs the steps: ```yaml login.test.yaml theme={null} fileType: momentic/test/v2 id: login-flow url: https://app.example.com/login steps: - type: text: test@example.com into: Email - click: Continue - assert: The dashboard is visible ``` ## Usage tips Choose a model that can call tools and follow the installed skills. Reasoning settings affect latency and decisions; compare them on your own tests before changing the team default. Invoke the relevant [skill](/docs/coding-agents/skills) by name when authoring, maintaining, or changing product behavior. Be specific in prompts, and include a step limit for exploratory runs. Let sessions terminate on their own. The agent calls `momentic_session_terminate` to close the browser; hard-stopping your editor leaks browser processes. Add `.momentic-mcp/` to `.gitignore`. MCP stores screenshots, videos, and traces there. Tell the agent to call `momentic_search_docs` before it writes step options, CLI flags, or configuration keys from memory. The tool searches these docs and returns the matching sections with their links. `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. Both servers expose run history: `momentic_list_runs`, `momentic_get_run`, `momentic_get_test_steps_for_run`, and `momentic_get_step_result` read past runs from the dashboard so an agent can triage a CI failure without leaving the editor. The `momentic-mobile` server lists Android and iOS runs by default; pass `executionType` to pick one platform or include web runs. ## Related * [Building with AI](/docs/coding-agents/building-with-ai) * [Coding agent skills](/docs/coding-agents/skills) * [`momentic install-mcp`](/docs/cli-reference/momentic/commands/install-mcp) * [What is AI-native testing?](/docs/get-started/ai-native-testing#author-with-product-context) # Coding agent skills Source: https://momentic.ai/docs/coding-agents/skills Install the Momentic skills into your repository so Claude Code, Cursor, Codex, Copilot, and other coding agents can start Mo sessions or write, run, and repair Momentic tests. The Momentic skills are `SKILL.md` files that teach a coding agent how to work with Momentic: the test file format, the MCP tools, the CLI, failure triage, and Mo. Each Momentic CLI ships the shared skills plus the skills for its own product. Install them once per repository and commit the files. Skills are text the agent reads. The [MCP server](/docs/coding-agents/mcp-server) is the process the agent calls to act on a live browser or device when working on repository tests. Install both for test authoring and maintenance. [Mo](/docs/mo) sessions use the `qa` CLI and `mo-qa` skill without an MCP installation. See [Building with AI](/docs/coding-agents/building-with-ai#skills-and-the-mcp-server) for how they compare. These skills are for the coding agent in your editor. Skills for Momentic's own runtime agents (triage and result classification) live in `.momentic/skills`. See [Runtime agent skills](/docs/ai/skills). ## Install Run the command for each CLI you use. Each command adds its own skills and leaves the skills installed by other CLIs in place. ```bash momentic theme={null} npx momentic skills ``` ```bash momentic-mobile theme={null} npx momentic-mobile skills ``` ```bash mo theme={null} qa skills ``` The command asks which coding agents you use, preselects the ones it detects in the repository, and writes the skills into each agent's directory: | Agent | Skills directory | Always-on pointer | | - | - | - | | Claude Code | `.claude/skills` | `CLAUDE.md` | | Cursor | `.cursor/skills` | `.cursor/rules/momentic-skills.mdc` | | Codex, Devin, Jules, and other AGENTS.md tools | `.agents/skills` | `AGENTS.md` | | VS Code and GitHub Copilot | `.github/skills` | `.github/copilot-instructions.md` | | OpenCode | `.opencode/skills` | `AGENTS.md` | The pointer is a short block inside the agent's instructions file. It lists the installed skills and tells the agent to read the matching `SKILL.md` before it touches Momentic tests. The block sits between `` and `` markers; the installer rewrites only that block, so your own instructions stay as they are. ### Skip the prompts Pass `--target` to choose agents without a prompt, or `--yes` to install for the agents detected in the repository: ```bash theme={null} npx momentic skills --target claude-code cursor npx momentic skills --yes ``` Both flags work in CI and in agent shells. ## Installed skills Every CLI installs the shared skills: | Skill | Use it to | | - | - | | `momentic-spec` | Write the affected tests before a product change | | `momentic-maintain` | Investigate failures, audit classifications, deflake, reduce retries | | `momentic-triage-quarantined-tests` | Work through the quarantine backlog | Each CLI adds the skill for its product: | CLI | Skill | Use it to | | - | - | - | | `momentic` | `momentic-test` | Create, run, and maintain browser tests and modules | | `momentic-mobile` | `momentic-mobile-test` | Create, run, and maintain iOS and Android tests | | `qa` | `mo-qa` | Start and control Mo sessions with the `qa` CLI | ## Use the skills Some agents load installed skills on their own. Others load a skill only when you name it 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 tools instead of writing framework-specific code. ### 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 ``` Use `momentic-triage-quarantined-tests` to work through the quarantine backlog and produce a PR or report for the tests it repairs. ### 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 and have no live session video option. The agent can still inspect the video attached to a completed mobile run when that artifact exists. ### Spec-driven development In the simplified format, Momentic tests read 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 steps for test data, disabled specifications, and verification. ``` See [Agentic testing](/docs/core-concepts/agentic-testing) for more on `act` and AI action V3. ### Mo Use `mo-qa` to start and control [Mo](/docs/mo) sessions from a coding agent. If the `qa` CLI is installed, `qa skills` writes `mo-qa` and the shared skills into the directory of each agent you pick: ```bash theme={null} qa skills ``` Without the CLI, install the skill on its own: ```bash theme={null} npx skills add https://github.com/momentic-ai/skills --skill mo-qa ``` Claude Code and Cursor can also install the `momentic` plugin from the [Momentic skills repository](https://github.com/momentic-ai/skills); it contains the same skills. ```text theme={null} /mo-qa bug bash my new feature on ``` The skill installs and authenticates the CLI, asks you for the parts of the brief you left out, starts the session, and follows it. It does not invent scope, credentials, or acceptance criteria. See [write a good brief](/docs/mo/brief) and [use the CLI](/docs/mo/cli). ## Keep skills current The skills ship inside the CLI package, so a CLI upgrade can carry new skill content. The first time you run `momentic run`, `momentic app`, `momentic-mobile run`, or `qa start` in a terminal after an upgrade with newer skills, the CLI asks once whether to update the installed files. Answer `y` to rewrite them for the agents you chose before. Answer `n` and it does not ask again for that skill version. Each CLI tracks its own skills, so an update from `momentic` leaves the files `qa` installed as they are. The prompt appears only in an interactive terminal. It does not run in CI, in non-TTY shells, or when `MOMENTIC_SKIP_SKILLS_PROMPT` is set. To update without the prompt, run the install command again: ```bash theme={null} npx momentic skills --yes ``` Install state lives in `~/.momentic/skills.json`. Delete the file to see the first-run prompt again. Each installed `SKILL.md` ends with a footer such as `Generated for momentic 3.53.0 (skills 1788291203)`. Read it to see which CLI version wrote the file, and compare it with `npx momentic --version` in a code review to spot a stale skill. ## Related * [Mo quickstart](/docs/mo/quickstart) * [Mo CLI](/docs/mo/cli) * [Building with AI](/docs/coding-agents/building-with-ai) * [MCP server](/docs/coding-agents/mcp-server) * [Runtime agent skills](/docs/ai/skills) # Advanced configuration Source: https://momentic.ai/docs/configuration/advanced Reference for the `advanced` block in `momentic.config.yaml`. Niche settings for testing edge cases. The `advanced` block holds project-level settings for edge cases. Most projects do not need them. ```yaml momentic.config.yaml theme={null} advanced: aiActionShorthand: true fakerConstantSeed: true isolateCachesByEnvironment: true saveCacheOnCancel: true ``` Write eligible AI action V3 goals as bare strings when Momentic saves simplified YAML. New projects created by the setup wizard, `momentic init`, and `momentic-mobile init` enable this setting. Existing projects without the setting write `act:`. Only multi-word goals without additional step options use the bare form. One-word goals remain under `act:` so names such as `refresh` and `killApp` cannot be confused with registered bare commands. ```yaml momentic.config.yaml theme={null} advanced: aiActionShorthand: true ``` Use a constant seed for [Faker](https://fakerjs.dev) so randomly-generated data is reproducible across runs. Useful for debugging. Default: `false`. ```yaml momentic.config.yaml theme={null} advanced: fakerConstantSeed: true ``` Store separate [step cache](/docs/reliability/step-cache) entries for each selected environment. Default: `false` (caches are shared across environments). Enable this when environments have different DOM structures, mobile screens, feature flags, or randomized element IDs that cause frequent cache misses when shared. With isolation enabled, a cache learned with `--env staging` will not replay for `--env production`. ```yaml momentic.config.yaml theme={null} advanced: isolateCachesByEnvironment: true ``` Save partial [step caches](/docs/reliability/step-cache) when a test run is cancelled or times out. Default: `false` (caches are discarded on cancellation). Without this flag, an interrupted run (via `Ctrl+C`, `SIGTERM`, or `--timeout-minutes`) loses all cache progress from steps that already completed successfully. Enable it to preserve that work so the next run can replay from cache instead of starting from scratch. ```yaml momentic.config.yaml theme={null} advanced: saveCacheOnCancel: true ``` # AI configuration Source: https://momentic.ai/docs/configuration/ai Reference for the `ai` block in `momentic.config.yaml`. Per-agent version controls and local AI feature toggles. Momentic uses several specialized AI agents, each versioned independently. See [Agents](/docs/ai/agents) for the available versions and what every agent does. Turn [results classification](/docs/reliability/auto-maintenance#permanent-healing) on or off in `momentic.config.yaml` with `ai.classification`. The failure categories and their actions, along with post-classification healing behavior, stay cloud-managed in [Settings > Classification](https://app.momentic.ai/settings/classification). ## Options Choose which version of prompts and models to use for each AI task. Use the latest version for new projects. Omit an agent to inherit the organization default. See [Agents](/docs/ai/agents) for available versions per agent. ```yaml momentic.config.yaml theme={null} ai: agentConfig: locator: v5 assertion: v5 visual-assertion: v5 text-extraction: v3 failure-recovery: v2 ``` Mobile projects also set the platform locator agents: ```yaml momentic.config.yaml theme={null} ai: agentConfig: android-locator: v2 ios-locator: v2 ``` Classification's on/off toggle and exit-code override are configured here in `momentic.config.yaml`, so they live alongside your tests and apply to local and CI runs. Failure categories and their actions stay cloud-managed. Default: `false`. Enable [results classification](/docs/reliability/auto-maintenance#permanent-healing) for failed CLI runs. Use the `true` shorthand to enable with defaults, or an object for finer control: ```yaml momentic.config.yaml theme={null} ai: classification: enabled: true overrideExitCode: true ``` * `enabled` (boolean, default `false`): run the classifier on failed runs. * `overrideExitCode` (boolean, default `false`): let the classification verdict decide the exit code. Override is opt-in: by default the classifier runs and records a category, but every failed test still fails CI. Set it to `true` so failures routed to `heal` or `warn` exit `0`. Opt in per run with [`--classify-override-exit-code`](/docs/cli-reference/momentic/commands/run). We recommend enabling classification. Beyond triaging failed runs, it also affects [transient failure recovery](/docs/reliability/auto-maintenance#failure-recovery): when recovery is eligible (its config is on and the run is in CI), the classifier runs while the run is still executing and decides whether a failed step is recovered. Only failures whose category action is **Heal** and that the classifier judges recoverable are retried. With classification off, a built-in recovery planner makes that decision instead. Default: `true`. Allow AI agents to use data from past test runs to keep element locators and assertions consistent across runs. It sets the project default and can be overridden per test. See [Memory](/docs/ai/memory) for details. ```yaml momentic.config.yaml theme={null} ai: useMemory: true ``` Default: `false`. Enable [Failure recovery](/docs/reliability/auto-maintenance#failure-recovery). Momentic proposes and executes step changes to recover from certain test failures. ```yaml momentic.config.yaml theme={null} ai: failureRecovery: true ``` Deprecated and kept only for backwards compatibility. Page filtering is always enabled for large browser pages and cannot be customized after CLI version 2.94.0. Safe to remove from existing config files. Default: `true`. # Browser configuration Source: https://momentic.ai/docs/configuration/browser Reference for the `browser` block in `momentic.config.yaml`. Controls defaults for all browser-based tests in a project. These defaults apply to every browser-based test in the project. Individual tests can override any of these values. ```yaml momentic.config.yaml theme={null} browser: defaultBrowserType: Chromium smartWaitingTimeoutMs: 5000 pageLoadTimeoutMs: 8000 slowMoMs: 250 ``` ## Identity Default browser used by all tests in the project. ```yaml momentic.config.yaml theme={null} browser: defaultBrowserType: Chromium ``` * `Chromium`: lightweight, open-source browser with a basic feature set. The same engine Playwright and Cypress use. * `Google Chrome`: full Google Chrome build with PDF rendering and WebGL. * `Chrome for Testing`: a versioned Chrome build for test automation, without auto-update. User agent string sent on every request. Defaults to the current Chrome desktop UA. Set to `null` to disable the default override and use the browser's native user agent (which then matches the runner's OS). ```yaml momentic.config.yaml theme={null} browser: userAgent: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" ``` ```yaml momentic.config.yaml theme={null} browser: userAgent: null # use the browser's native user agent ``` Default [IANA timezone](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones). Defaults to `America/Los_Angeles`. Per-test settings override this. ```yaml momentic.config.yaml theme={null} browser: timezone: America/New_York ``` Use the host machine's timezone instead. When `true`, all `timezone` settings (project- and test-level) are ignored. Default: `false`. ```yaml momentic.config.yaml theme={null} browser: useHostTimezone: true ``` ## Timeouts Maximum wait time for a page to load, in milliseconds. Applies to new tabs and navigation events. Default: `8000`. ```yaml momentic.config.yaml theme={null} browser: pageLoadTimeoutMs: 20000 ``` Continue after page-load timeouts instead of failing the test. Default: `false`. Enable this for applications that render usable content even though the browser does not report that the page finished loading. Momentic waits up to `pageLoadTimeoutMs` for each new document. If that wait times out, later page-state collections for the same document skip it. A new document or tab receives its own full wait. This setting does not shorten the initial timeout or mark the page as fully loaded. Momentic may collect page state while the page is still loading. ```yaml momentic.config.yaml theme={null} browser: ignorePageLoadTimeouts: true ``` Maximum wait time for [smart waiting](/docs/reliability/auto-maintenance#locator-auto-healing) between steps, in milliseconds. Default: `5000`. ```yaml momentic.config.yaml theme={null} browser: smartWaitingTimeoutMs: 10000 ``` Default maximum wait time for [element check](/docs/reference/commands/check-element) assertions to become true, in seconds. Element check steps with an explicit timeout are unaffected. Default: `5`. ```yaml momentic.config.yaml theme={null} browser: elementCheckTimeoutSeconds: 10 ``` Default delay between keystrokes for type steps, in milliseconds. Type steps with an explicit delay are unaffected. Increase this if your app needs more time to react to each keystroke. Default: `25`. ```yaml momentic.config.yaml theme={null} browser: typeDelayMs: 60 ``` How long each key stays held between keydown and keyup for press steps, in milliseconds. Press steps with an explicit delay are unaffected. Default: `0`. ```yaml momentic.config.yaml theme={null} browser: pressDelayMs: 60 ``` ## Execution timing Wait between steps in a step list, in milliseconds. The first executed step has no delay, including when earlier steps are skipped. A single-step list has no delay. Values range from `0` to `10000`. Default: `0`. ```yaml momentic.config.yaml theme={null} browser: slowMoMs: 250 ``` Environment browser settings override this value, and the test-level `slowMoMs` setting overrides both. For a single run, pass [`--slow-mo `](/docs/cli-reference/momentic/commands/run#slow-mo-milliseconds) to override all three without changing your configuration files. ## Headers, storage, and permissions ### Extra headers Set `browser.extraHeaders` to add HTTP headers to browser requests. Headers apply to every requested host, including third-party hosts. Load credentials from [environment variables](/docs/configuration/environment-variables) instead of writing tokens into your config: ```yaml momentic.config.yaml theme={null} name: browser-header-tests browser: extraHeaders: Authorization: "Bearer {{ env.AUTH_TOKEN }}" X-Test-Run: momentic environments: - name: staging baseUrl: https://staging.example.com inheritFromShell: true ``` Set `AUTH_TOKEN` in your shell or CI secrets, then select this environment with `npx momentic run --env staging`. See [Secrets](/docs/configuration/environments#secrets) for `.env` files and other variable-loading options. Local storage values to seed per origin before the test starts. Origin must include scheme, host, and (if non-default) port. Useful for feature flags or cached auth. ```yaml momentic.config.yaml theme={null} browser: initialLocalStorage: https://momentic.ai: momenticTestKey1: momenticTestValue1 momenticTestKey2: momenticTestValue2 ``` Paths to unpacked Chrome extension directories. Each directory must contain `manifest.json`. Momentic loads the extensions before the test starts. Use `Chromium` with `remoteBrowser: false`. Hosted browsers and the cloud dashboard don't support extensions. Google Chrome 137 and later no longer support this extension-loading mechanism, and Momentic doesn't support loading extensions in `Chrome for Testing`. Relative paths resolve from the directory where you launch Momentic. The directories must exist on the machine running the test, including in CI. Configure one or more extensions in `momentic.config.yaml`: ```yaml momentic.config.yaml theme={null} browser: defaultBrowserType: Chromium remoteBrowser: false localChromeExtensionPaths: - ./extensions/checkout-helper ``` See [Load Chrome extensions](/docs/guides/use-cases/load-chrome-extensions) for project setup, local editor steps, and troubleshooting. Browser permissions to auto-grant during the run. When omitted, all permissions are granted. ```yaml momentic.config.yaml theme={null} browser: grantedPermissions: - clipboard-read - clipboard-write - microphone - camera - geolocation ``` Ignore HTTPS errors like self-signed certificates. Useful for internal or development environments. Default: `false`. ```yaml momentic.config.yaml theme={null} browser: ignoreHttpsErrors: true ``` ## Performance and stability Run tests on Momentic hosted browsers instead of a local Chromium. Applies to `momentic run` only; the editor and the MCP server always use a local browser. See [hosted test environments](/docs/running-tests/hosted-test-environments). Default: `false`. ```yaml momentic.config.yaml theme={null} browser: remoteBrowser: true ``` Disable intensive graphical operations (WebGL, hardware-accelerated raster). Speeds up runs on machines without a dedicated GPU. May break sites that rely on WebGL. Default: `false`. ```yaml momentic.config.yaml theme={null} browser: disableGpu: true ``` Disable Chrome's zygote process. Can reduce process overhead but may break features that depend on the zygote. Default: `false`. ```yaml momentic.config.yaml theme={null} browser: disableZygote: true ``` Block FullStory scripts from mounting during the run. FullStory's high-volume DOM scanning can crash automated pages. ```yaml momentic.config.yaml theme={null} browser: disableFullStory: true ``` ## Run-data capture Disable Momentic's default recording of console logs, network requests, HTML snapshots, and element screenshots. The recordings feed the run viewer's debug tabs. Disabling can improve performance on sites with high log volume. Default: `false`. ```yaml momentic.config.yaml theme={null} browser: disableBrowserMonitoring: true ``` Disable console log recording during runs. Default: `false`. ```yaml momentic.config.yaml theme={null} browser: disableConsoleLogs: true ``` Disable network request recording during runs. Default: `false`. ```yaml momentic.config.yaml theme={null} browser: disableNetworkLogs: true ``` ## Page handling Automatically expand iframes so Momentic can interact with elements inside them without configuring **Act within iframe** per step. Default: `false`. ```yaml momentic.config.yaml theme={null} browser: autoExpandIframes: true ``` Deprecated. Waiting for new tabs is inherently racy; use **Switch tab** steps instead. Automatically switch to new tabs opened during the run. Default: `false`. ```yaml momentic.config.yaml theme={null} browser: autoFollowNewTabs: true ``` Default: `true`. Momentic reads the browser's already-computed accessibility data. This is fast and stable, but can be incomplete on pages that never finish loading. Set to `false` to force the browser to rebuild the tree from scratch on every read (more complete on slow pages, but slower, and can crash the browser on very large pages). ```yaml momentic.config.yaml theme={null} browser: allowPartialAccessibilityTree: false ``` Default: `true`. Controls whether zero-opacity elements are exposed to the AI locator agent and available to interactive steps. Use `hover` steps to reveal hidden elements before interacting with them. * `true`: show all elements regardless of opacity. * `false`: filter zero-opacity elements out of the page context and block interactions on them. More closely mimics a human user. * `inputs-only`: still show zero-opacity `` elements (useful for UI frameworks that style hidden inputs). ```yaml momentic.config.yaml theme={null} browser: showZeroOpacityElements: inputs-only ``` ## Locator and cache tuning Default: `false`. Make the V5 locator respect Momentic's element eligibility markers during positive [visibility checks](/docs/reference/commands/check-element). This helps it select a visible target instead of a matching wrapper that has no rendered box, such as an element styled with `display: contents`. Enable it in `momentic.config.yaml` with a V5 locator: ```yaml momentic.config.yaml theme={null} browser: markIneligibleElementsInChecks: true ai: agentConfig: locator: v5 ``` Without valid [Memory](/docs/ai/memory), the locator uses its existing eligibility guidance to find a matching target. Memory-backed checks keep their existing behavior. The browser still validates visibility after locating the element. This setting does not change other element checks, interactive steps, or older locator agents. Set it to `false` or omit it to keep the default behavior. It does not invalidate existing step caches. Default: `always`. Use Momentic's algorithm to find the top-most interactable element when a target is covered by another element. Other frameworks throw or require a forced click; this redirects to the covering element instead. * `false`: disabled. * `true`: only redirects on `CLICK` steps (backward compatibility). * `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 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 reliably 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 weigh 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 invalidate 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. Select a configured environment with `--env ` or the test's `defaultEnv`. The `--env` flag chooses the environment; it does not assign variable values. Within that environment, Momentic loads variables in this order. Later sources override earlier values with the same name: 1. [`envVariables`](/docs/configuration/environments#environments-envvariables), including values loaded with `fromFile`. 2. The [`envFile`](/docs/configuration/environments#environments-envfile). 3. The enclosing shell, when `inheritFromShell: true`. See [`environments`](/docs/configuration/environments) for the full schema. ## Secrets For passwords, API tokens, and other secrets, prefer a `.env` file or shell or CI environment variables over inlining values in `momentic.config.yaml`. See [Secrets](/docs/configuration/environments#secrets) for the recommended patterns. ## Reserved variables Momentic sets these at runtime. Access them 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 | `BASE_URL` and `CURRENT_URL` apply to web tests. Mobile tests use an app artifact rather than a browser URL. ## Access variables in tests Use the templating syntax anywhere a step accepts a string: ```yaml theme={null} - type: text: "{{ env.USERNAME }}" into: Email field ``` Access `env.VARIABLE` directly inside a **JavaScript** step. ## Set variables at runtime Use `setVariable` inside a **JavaScript** step to write a variable: ```javascript theme={null} setVariable("OTP_CODE", "123456"); ``` 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 description: 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; tests read the resolved values 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 local or remote mobile emulators used by the local editor and `momentic-mobile` CLI. It applies only to mobile test runs. ```yaml momentic.config.yaml theme={null} emulator: region: us autoGrantPermissions: true ``` Set `local` to use an [Android emulator](/docs/platforms/android/emulators) or [iOS simulator](/docs/platforms/ios/simulators) on your machine. Region where the emulator runs. Momentic recommends continent values (`us`, `eu`, `as`) 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 prefer a particular data center. `as` is Android-only. When unset, Momentic picks the region closest to your 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. Momentic rejects a `region` outside the jurisdiction 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 the jurisdiction's closest data center. 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. Do not combine it 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. Do not combine it 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 because continuous log streaming can slow the emulator, 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 because continuous log streaming can slow the simulator, 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 ``` Route selected traffic from remote iOS simulators and Android emulators through the machine running Momentic. Set `capture: true` to record HTTP(S) requests and responses during CLI test runs. View captured traffic in the run's **Network** tab. Tunneling and capture are off by default. ```yaml momentic.config.yaml theme={null} emulator: tunnel: selectors: - example.com - "*.example.com" capture: true ``` `selectors` is required. Use domains (`api.example.com`), quoted wildcard subdomains (`"*.example.com"`), or IP/localhost ports (`127.0.0.1:8080`). Wildcards exclude the root domain, so the example selects both `example.com` and its subdomains. URLs, domain:port destinations, and catch-all wildcards (`*`, `*.*`) are not supported. You can select up to 64 domains and 10 exact ports, with no duplicates. Omit `capture` or set it to `false` to tunnel without network logs or HTTPS inspection. Set `tunnel: false` in a test to disable the project-level tunnel: ```yaml theme={null} emulator: tunnel: false ``` A test-level tunnel object overrides the whole project-level tunnel object. The local editor uses the same tunnel selectors without capturing traffic or inspecting HTTPS. Capture applies only to CLI test runs. Tunneling is skipped on local emulators and simulators. Selected traffic uses the network and source IP of the machine running Momentic. Enabling capture adds HTTPS inspection, which may fail for apps with certificate pinning. Capture includes matching traffic from any app on the device. Capture startup failures warn and let the test continue without the tunnel or network logs. Routing-only startup failures fail the attempt. Only requests that complete during capture appear in the network logs. 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 up 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 Momentic retries a cached element until `smartWaitingTimeoutMs` elapses either way, so leaving this off does not make targeting less reliable. This setting only controls whether the run waits on a step's effects 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 ``` Limit the emulator's Wi-Fi bandwidth for the whole run, in kilobits per second, to test your app on a slow connection. Set `downloadKbps`, `uploadKbps`, or both. Omit a direction to leave it unlimited. Hosted Android emulators support this; local emulators and iOS ignore this setting. ```yaml momentic.config.yaml theme={null} emulator: networkConditions: downloadKbps: 1600 uploadKbps: 750 ``` 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 may be 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: v5 assertion: v5 visual-assertion: v5 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. Momentic picks up matching files automatically when you start the local editor or run tests. ```yaml momentic.config.yaml theme={null} include: - "**/*.test.yaml" - "**/*.module.yaml" ``` Globs for files to exclude. Momentic always excludes `node_modules`, `.git`, and `.venv`. ```yaml momentic.config.yaml theme={null} exclude: - "out/**/*" ``` Default number of retries per test on failure. A per-test `retries` value overrides this. Default: `1`. ```yaml momentic.config.yaml theme={null} retries: 2 ``` Number of tests to run in parallel. Default for `momentic run`: `1`. 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 for **Visual diff** golden files. ```yaml momentic.config.yaml theme={null} goldenFileDir: golden/visual-diff ``` Directory for local run artifacts and result archives. Defaults to `./test-results`. The `--output-dir` run flag overrides this setting. ```yaml momentic.config.yaml theme={null} outputDir: test-results ``` 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 local editor. 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. Momentic uses globs throughout `momentic.config.yaml` (e.g. `include`, `exclude`) to choose which `.test.yaml` and `.module.yaml` files it 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. ## Create 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. Momentic tests can mix **preset steps** and **AI actions**. A preset step names an operation, such as clicking **Sign in** or checking that a dashboard loads. It can still use AI to locate an element or evaluate an assertion. An AI action gives a runtime agent a goal and lets it choose the steps. Use one when the path depends on the current application state. Review its trace and assert the expected outcome. ## 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**: investigate flows outside your existing tests. Use [Mo](/docs/mo/index) when you want a session with a coverage report and bug evidence. * **End-to-end smoke tests** after deploys ("complete an order") with the agent handling whatever the current UX looks like Prefer preset steps for critical paths where you need an explicit sequence and specific 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 url: https://app.example.com/signup 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 activity, and handles modal dialogs on its own. When the agent reaches the goal, 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. Momentic keeps V2 available as a fallback for flows where V3 does not yet work well. The V3 AI action is in beta and may change. V3 is available for web and mobile. New AI action steps default to V3; you can keep existing V2 steps, but the editor does not offer V2 for new steps. ## 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 [locator auto-healing](/docs/reliability/auto-maintenance#locator-auto-healing) and [step cache](/docs/reliability/step-cache). V3 caches the resolved steps after a successful run and replays them deterministically on later runs. ## Related * [AI action guide](/docs/guides/ai-actions/guide) * [Finding elements](/docs/core-concepts/finding-elements) * [Writing assertions](/docs/core-concepts/writing-assertions) * [Locator auto-healing](/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 with SSO. Providers like Google, Facebook, and GitHub use CAPTCHAs and bot detection to 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 basic 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**: Momentic must provision an email address. Add a **JavaScript** step with the following content: Set `INBOX_PREFIX` to your provisioned inbox name, such as `qa+login`. ```javascript theme={null} const msg = await email.fetchLatest({ inbox: env.INBOX_PREFIX, }); const [link] = msg.text.match(/https?:\/\/[^\s]+/) ?? []; if (!link) throw new Error("No sign-in link found in email"); return link; ``` Use the step's **Save to environment variable** option to save the link, e.g. as `MAGIC_LINK`. Then use a **Navigate** step with `{{ env.MAGIC_LINK }}` to finish logging in. ## Email one-time password (OTP) **Prerequisites**: Momentic must provision an email address. Add a **JavaScript** step with the following content: ```javascript theme={null} const msg = await email.fetchLatest({ inbox: env.INBOX_PREFIX, }); const [code] = msg.text.match(/\b\d{6}\b/) ?? []; if (!code) throw new Error("No OTP code found in email"); return code; ``` Use the step's **Save to environment variable** option to save the code, e.g. as `OTP_CODE`. Then use a **Type** step with `{{ env.OTP_CODE }}` to enter the code and finish logging in. ## SMS one-time password (OTP) **Prerequisites**: Momentic must provision an SMS number. Set `QA_PHONE_NUMBER` to the provisioned number in E.164 format, such as `+14151234567`. Add a **JavaScript** step with the following content: ```javascript theme={null} const msg = await sms.fetchLatest({ to: env.QA_PHONE_NUMBER, }); const [code] = msg.body.match(/\b\d{6}\b/) ?? []; if (!code) throw new Error("No OTP code found in SMS"); return code; ``` Use the step's **Save to environment variable** option to save the code, e.g. as `OTP_CODE`. Then use a **Type** step with `{{ env.OTP_CODE }}` to enter the code and finish logging in. ## 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 allowlist If your test environment restricts inbound traffic by IP, allowlist Momentic's fixed egress IP for hosted runs: `34.106.239.183`. On Azure-hosted deployments, allowlist 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, and 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" } } ``` This setup 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 YAML 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`. Mobile tests also require a `description` and `platform`. A module uses the module `fileType` and can add 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. Momentic ignores a `name` key in a test file. 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 description: Check checkout confirmation 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: parameterNames: [USERNAME, PASSWORD] defaultParameters: USERNAME: '"test@example.com"' 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. Web modules declare parameters as `{ name, default?, enum? }` entries. `default` is a value object (`{ string }` or `{ javascript }`) used when an invocation omits the input. Mobile modules use `parameterNames`, `defaultParameters`, and `parameterEnums` inside a `parameters` object; default values are JavaScript expressions. See [Modules](/docs/core-concepts/modules) for examples. ## IDs Every test and module ID must be unique across your Momentic organization. When Momentic creates a file, including through [MCP](/docs/coding-agents/mcp-server), 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. UUIDs 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 hard `before` step fails, the run skips the main steps and marks the test as a setup failure. A failed browser [soft assertion](/docs/guides/use-cases/collect-independent-assertion-failures) allows main steps to run but still fails the test. Keep required setup hard. * `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. ## 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 can locate elements from natural-language descriptions. 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. Detail that can change makes a target less reliable. Accessible roles and names are 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, but always preserves common testing attributes such as `aria-label` and `data-test-id`. 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, so it can drive drawing tools, visual editors, games, maps, and other canvas-heavy UI. Natural-language targets in preset steps such as **Click** and **Type** 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 confirmed on its own before the test proceeds. It also covers visual appearance, page position, relationships between elements, and 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 a test on the same platform with a **Module** step. This example uses a web module; mobile parameter declarations differ as shown under [Parameters](#parameters). ```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://shop.example.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. Web modules declare a list under `parameters`, then reference the values 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 # provide this input when calling the module steps: - type: text: "{{ env.USERNAME }}" into: Email input ``` Mobile modules use a `parameters` object. `parameterNames` declares the inputs, `defaultParameters` maps names to JavaScript expressions, and `parameterEnums` maps names to allowed string values. Quote a literal string inside the expression: ```yaml log-in.module.yaml theme={null} fileType: momentic/mobile-module/v2 id: calm-sparrow-garden name: Log in platform: android parameters: parameterNames: [USERNAME, PASSWORD, ROLE] defaultParameters: USERNAME: '"test@example.com"' parameterEnums: ROLE: [admin, member] steps: - type: text: "{{ env.USERNAME }}" into: the Email field - type: text: "{{ env.PASSWORD }}" into: the Password field - tap: the Log in button ``` ### 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: ... }`: an explicit JavaScript expression, equivalent to the shorthand. The runtime adds `return`; do not add a return statement yourself. ```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 For web modules, 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 Web modules are uncached by default and always execute. Enable caching to skip a module when its cache key and inputs are unchanged. Momentic also caches the module's return value (the return value of its last step). Mobile module calls execute their steps; the module caching fields below apply to web modules. 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: - type: text: "{{ env.QA_EMAIL }}" into: Email input - type: text: "{{ env.QA_PASSWORD }}" into: Password input - click: Log in - checkElementVisible: Account menu ``` 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. This applies to web tests; mobile modules do not have `autoAuth`. Momentic persists: * [Cookies](https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/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: - type: text: "{{ env.QA_EMAIL }}" into: Email input - type: text: "{{ env.QA_PASSWORD }}" into: Password input - click: Log in - checkElementVisible: Account menu ``` 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 setup. # 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 a device-level script 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 device-level scripts 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. Momentic caches successful resolutions 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 interactions such as `click` accept natural language, CSS or XPath selectors, and absolute coordinates. Other steps support fewer target types; check the step's reference before using 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, depending on the command. For example, `"50%, 50%"` targets the center of the screen. Element checks require natural-language targets. Mobile targets 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 needs its primary value. Use the detailed form when it needs more options: ```yaml theme={null} - click: Submit - click: on: Submit 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 ``` An `if` has 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`. Momentic evaluates the condition 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: "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 an expression. Do not add a `return` statement; the runtime adds it. 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 cover the work. Use them for test data, backend 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. This shell example requires Android: ```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 JavaScript source and authentication-state 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 ``` File uploads follow a different path contract: ordinary local paths resolve from the CLI working directory, while paths beginning with `./`, `../`, or `momentic://` identify uploaded user files. See [File upload](/docs/reference/commands/file-upload). ### Durations Durations in the simplified YAML format use milliseconds: ```yaml theme={null} - assert: that: The chart is visible timeout: 10000 # 10 seconds ``` ## Authoring references For browser checks that record assertion failures and continue, use the soft aliases described in [Collect independent assertion failures](/docs/guides/use-cases/collect-independent-assertion-failures). These aliases aren't available as conditional or loop predicates. Use the generated [YAML format reference](https://static.momentic.ai/v2-format-reference.md) when you or a coding agent needs 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** the MCP server returns at 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 writes its return value 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. A variable set in one step is readable by any subsequent step in the same test. ### 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 | ## 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. ## Soft assertions In browser tests, enable **Soft assertion** on an AI check or element check to continue after a negative verdict. The step still shows **FAIL**, and the test fails when execution finishes. A hard failure stops execution as usual. Keep login, navigation, and other prerequisites hard. Use soft assertions for independent expectations that remain meaningful if another check fails. Soft assertions aren't available in mobile tests. See [Collect independent assertion failures](/docs/guides/use-cases/collect-independent-assertion-failures) for supported versions, editor setup, YAML examples, and failure reporting. ## 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. The CLI records video for tests that define them. Run assertions are 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 Mo for exploratory testing and AI agents to author, run, and maintain repository tests. Momentic uses AI agents to explore an app, author tests, select tests for a code change, execute steps, and investigate failures. You can start an exploratory session with [Mo](/docs/mo) or keep repeatable tests as YAML files in your repository. Repository tests connect authoring, execution, and maintenance through files you review in Git. Run data provides context for later agents and records the product journeys your suite covers. ## Explore with Mo Give Mo a running web URL or an uploaded mobile build and a brief. Its hosted agents plan test cases, execute them, and reproduce suspected bugs. The session report contains cases, verdicts, reproduced bugs, and coverage gaps. Use Mo to check a preview build or a product area before you have a test suite. It does not write YAML test files. After a session, use a coding agent to turn cases you want to check in CI into repository tests. See the [Mo quickstart](/docs/mo/quickstart) and [accepted bug follow-up](/docs/mo/triage#what-to-do-with-an-accepted-bug). ## 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 [coding agent skills](/docs/coding-agents/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. [Building with AI](/docs/coding-agents/building-with-ai) covers both in two commands. With the [`momentic-spec` skill](/docs/coding-agents/skills#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 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 tolerate routine UI variation. Deterministic replay and step caching keep successful paths fast, while AI resolves described elements and evaluates AI checks. 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 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` Check Node.js before running the CLI or onboarding wizard: ```bash theme={null} node --version ``` Both require Node.js 22.12.0 or later in the 22.x line, or 24.0.0 or later. Update unsupported versions, including Node.js 20 and 23, in your local runtime and CI. Import into the web project's directory containing `momentic.config.yaml`. If you do not have a project yet, the onboarding wizard installs the CLI, logs you in, and scaffolds the configuration: ```bash theme={null} npx @momentic/wizard@latest ``` For an existing project, commit or stash local changes first and confirm that the CLI is authenticated to the workspace you want to export. Run [`momentic login`](/docs/cli-reference/momentic/commands/login) to select an account, or set `MOMENTIC_API_KEY` for that workspace. Then run: ```bash theme={null} npx momentic import ``` This imports the workspace's web tests, their referenced modules, and environments. Unused standalone modules are not included; check them separately before retiring the cloud project. Review the overwrite prompts: the importer can replace existing test files and both the base URL and variables in environments with matching names. Keep prompts enabled for the first import. An interrupted import can leave some files written; review the diff before retrying or restoring your saved state. Imported environment variables can include plaintext secrets. Move them to an ignored `.env` file or your CI secrets before staging files. Follow [Secrets](/docs/configuration/environments#secrets) to retain the same variable names at runtime. 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 that folder's tests and their referenced modules. The folder hierarchy is recreated on disk. Imports with explicit paths bring in tests and modules; they do **not** import environments. Configure the required [environments](/docs/configuration/environments) before running that selection. In a workspace repository, change into the selected project's directory before importing. Pass `--config` if needed to select its configuration; that flag does not change where newly imported files are written. ## 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) still handles repository test results and configuration: * [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 This deprecation applies to the legacy cloud test editor and queue commands. [Mo sessions](/docs/mo/index) still run from the web app or `qa` CLI. [Hosted browsers](/docs/running-tests/hosted-test-environments) still work with `momentic run`; your CLI or CI runner controls the test execution. ## After importing The import moves test definitions. It does not configure CI jobs or recreate cloud suite schedules. Record the old suite's test selection, environment, parameters, browser settings, concurrency, and schedule before replacing it. Run lint and check that every expected test appears in the local selection: ```bash theme={null} npx momentic lint npx momentic list ``` The importer writes the format selected by `fileFormat` in your project config. For a legacy project, use the [simplified format migration](/docs/get-started/migrate-to-simplified-format) before editing YAML with a coding agent. Use an actual path from `momentic list` and the environment used by the cloud run. For example, if your imported environment is named `staging`: ```bash theme={null} npx momentic run tests/checkout/happy-path.test.yaml --env staging --upload-results ``` Confirm the starting URL, test data, assertions, and setup/cleanup behavior. Review recovery and failure classifications as well as the final status. The test's own `url` takes precedence over the selected environment's base URL; see [environment selection](/docs/configuration/environments#select-an-environment) if the run targets the wrong deployment. 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). Translate each suite into explicit paths, directories, or labels, then use `momentic list` with the same selection to check its membership. Recreate environment variables, parameters, and schedules in your CI provider using the [CI templates](/docs/running-tests/ci/github-actions). Run the imported selection in CI and compare it with the previous suite before removing the old queue job. Confirm the expected tests and parameterized cases actually ran; account for disabled or skipped tests, quarantine, recovered passes, and failure classifications. Exit code `0` alone does not prove coverage parity. Check an expected failed assertion so the new job's exit status blocks the pipeline as intended. Pass `--upload-results` so runs appear in [the dashboard](https://app.momentic.ai). Open the uploaded run and verify its test count, environment, and results before switching the suite over. ## Why CLI-first CLI-first means tests are versioned with your application code, run the same way on a laptop and in CI, and connect to 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. Momentic tests combine exact, reviewable steps with goal-driven AI execution in one YAML file. This page covers how a test is assembled, where it runs, and how runs provide context for later tests. For exploratory testing, [Mo](/docs/mo) starts from a brief and a running app instead of a YAML test. A session plans cases and records verdicts, coverage gaps, and reproduced bugs in a [report](/docs/mo/reports). Use a Mo session to investigate a product area, then turn selected cases into repository tests for repeatable checks. See [when to use Mo](/docs/mo/why-mo). ## Anatomy of a test A Momentic test is a sequence of steps. Three step types mix in one test: preset steps, AI actions, and modules. 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 AI actions 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 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 an Appium script on 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 The web CLI exposes these AI commands 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 development loop. # 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 sets `fileFormat: v2` on the selected 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. ## Migrate with a coding agent Paste this prompt into your coding agent. It checks the working tree, runs the migration, reinstalls the skills, and reviews the diff with you. ```text theme={null} Help me migrate this project's Momentic tests to the simplified format. ## What to do 1. Run `git status --short`. If there are uncommitted changes, stop and ask me. Then create a backup branch: `git branch backup/momentic-v1-format`. 2. Find every `momentic.config.yaml` in the repo. Each one is a project root. Read the nearest `package.json`: `momentic` in its dependencies means a web project, `momentic-mobile` means a mobile project. If it lists both, or neither, stop and ask me. Repeat the steps below in each project root. 3. Run `npx momentic@latest upgrade --dry-run` and show me the plan. Then run `npx momentic@latest upgrade --yes`. If I ask for a file-only diff with no config default changes, run `npx momentic@latest migrate simplified-format --yes` instead. 4. If a file fails to migrate, the run stops. Show me the error, revert changes made by that failed attempt, fix the cause, and rerun the same command. 5. Run `npx momentic skills --yes` so the coding agent skills describe the simplified format. 6. Confirm the result: `momentic.config.yaml` has `fileFormat: v2`, and each test starts with `fileType: momentic/test/v2` (web) or `fileType: momentic/mobile-test/v2` (mobile). 7. Run one migrated test with `npx momentic run ` to confirm it passes. Then stage the config change and all rewritten YAML files in one commit. ## Critical rules - In mobile projects, replace `momentic` with `momentic-mobile` in every command, including `skills`. - Do not use `npx` to detect the project type. It downloads a missing CLI. - One CLI never touches the other CLI's files. - Show me the diff before you commit. ## When done, report - How many files were rewritten. - How many were already in the simplified format. - Anything you could not fix. ``` ## 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 ``` Check Node.js before running the CLI: ```bash theme={null} node --version ``` The current web and mobile CLIs require Node.js 22.12.0 or later in the 22.x line, or 24.0.0 or later. Update unsupported versions, including Node.js 20 and 23, in your local runtime and CI before upgrading. ## 1. Update Momentic Invoke the full upgrade 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. Read the CLI version in the project's `package.json` and lockfile. Also check explicit versions in CI install commands and MCP editor configs. Run only the version command for the CLI already installed in that project: ```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 Authenticate with [`momentic login`](/docs/cli-reference/momentic/commands/login) (or `momentic-mobile login` for mobile), or provide `MOMENTIC_API_KEY` for the workspace. The migration writes identity snapshots to retain existing step caches. Upgrade previews also authenticate, although they do not write snapshots. You have two entry points, depending on how much of the project you want to change: * `momentic@latest upgrade` / `momentic-mobile@latest upgrade`: the full upgrade. 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 included legacy test and module files when the project's format is still legacy. It can replace older agent pins and explicitly enables memory and failure recovery, including when those settings were disabled. Review the dry-run diff before applying it. * `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 serializer and use the project's `include` and `exclude` configuration to discover files. Explicit migration skips files that already use the simplified format. If the config already says `fileFormat: v2` but legacy files remain, use `migrate simplified-format`; `upgrade` skips the file conversion for projects already configured for v2. The migration can fail after writing some files. The full upgrade also installs the CLI before converting YAML, so package and lockfile changes can remain after a failure. Restore the changes from that attempt, fix the reported problem, and rerun. Some legacy constructs, such as section steps or conditionals with multiple branches or `else` steps, cannot be serialized directly. Refactor those tests while preserving their behavior before retrying. ### Preview with `--dry-run` Both upgrade commands accept `--dry-run` to preview config changes and file counts without installing a new project dependency, rewriting project files, or pushing snapshots. This is a conversion preview; it does not execute tests or prove that their behavior is equivalent: ```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. Conversion counts are shown for legacy-format projects. If the config already says v2, the preview skips file discovery and does not report leftover legacy files. ### 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 # rewrite only 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 # rewrite only 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. ### Web and mobile sharing one config The first upgrade sets the shared `fileFormat` to `v2`. The second CLI's upgrade then skips file conversion, even if that platform's files are still legacy. After upgrading both packages, explicitly migrate the remaining platform. For example, when upgrading web first: ```bash theme={null} npx momentic@latest upgrade npx momentic-mobile@latest upgrade npx momentic-mobile migrate simplified-format ``` If mobile was upgraded first, run `npx momentic migrate simplified-format` after the web upgrade instead. For a file-only migration, run both CLIs' `migrate simplified-format` commands; those commands inspect the files even when the shared config already says v2. ### What to expect The migration preserves existing step caches across the conversion. Duration depends on the number of files and the snapshot writes. Review the renamed fields, command options, and relative file references in the diff. A few changes to check: | Legacy YAML | Simplified YAML | Review | | - | - | - | | `beforeSteps` / `afterSteps` | `before` / `after` | Setup and cleanup retain their order. | | Test `baseUrl` | Test `url` | The starting URL stays the same. | | Test `advanced` settings | Top-level settings | Browser and per-test recovery settings are retained. | | Module invocation by `moduleId` | Relative `module` path | Resolve the path from the file containing the invocation. | | Module metadata `moduleId` | Module metadata `id` | Keep the existing identifier value. | | Step and command IDs | Omitted | Test and module identifier values remain stable; do not assign new IDs. | | Second-based command durations | Milliseconds | A legacy `WAIT` with `delay: 2` becomes `wait: 2000`. | Do not convert durations by hand across the suite: some legacy fields already use milliseconds. Let the CLI perform the conversion, then compare the timing of representative tests. Validate the files and runs below before committing. Include the config, rewritten YAML, updated skills, and any package manifest and lockfile changes in the same migration commit. Align explicit CI and MCP pins with the installed CLI so teammates and CI can load the new format. If your repo already uses the simplified format and the agent config is current, the project config and YAML do not need rewriting. The upgrade command can still update the installed CLI package. ## 3. Reinstall Momentic skills The Momentic skills teach coding agents and the MCP server how to author and edit simplified format files, including which MCP tools to reach for when making small 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 momentic skills --yes ``` Use `npx momentic-mobile skills --yes` for mobile projects. The command detects `.claude/`, `.cursor/`, `.agents/`, `.opencode/`, and `.github/` directories and rewrites the installed skill files in place. Run it once after the migration, then restart your editor so it loads the new skill content. ## 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 the local app and test runs already block invalid YAML. Use the `lint` command when a coding agent or direct YAML edit changes Momentic test files and you want 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 check 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 ``` ### Verify migrated behavior If you upgraded the web CLI and run local browsers, reinstall the browser builds used by your tests with [`momentic install-browsers`](/docs/cli-reference/momentic/commands/install-browsers). The upgrade does not download them. A file-only migration does not change browser builds. Use `list` to confirm the expected suite is discovered, then run an actual test path from that output. Replace the example paths and retain the environment, browser, and app build options from your previous run: ```bash theme={null} npx momentic list npx momentic run tests/checkout.test.yaml --upload-results ``` ```bash theme={null} npx momentic-mobile list npx momentic-mobile run mobile-tests/login.test.yaml --upload-results ``` Compare the starting state, setup and cleanup, assertions, retries, and recovery activity with the legacy run. Then run the affected suite in CI using the committed lockfile and the same selection. Confirm that the expected tests actually ran, including parameterized cases. Review disabled or skipped tests, quarantine, recovered passes, and failure classifications. Exit code `0` alone does not prove equivalent behavior. Lint validates file structure and references; it cannot prove behavioral equivalence. For rollback, restore the migration's YAML, config, and package changes together and reinstall dependencies from the restored lockfile. For a committed migration, revert the migration commit. Reverting only `fileFormat` leaves the project's files and CLI version inconsistent. ## 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 supported way to create, preview, and execute steps against a live browser. For lightweight changes, simplified format files are also fine 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 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 process that uses Momentic tests as product specs, see [Spec-driven development](/docs/coding-agents/skills#spec-driven-development) on the Skills page. # 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. For dashboard-managed web tests, [`momentic import`](/docs/cli-reference/momentic/commands/import) pulls them down to disk with their referenced modules and recreates the folder hierarchy. Mobile tests use the separate `momentic-mobile` CLI; it has no cloud import command. 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 [coding agent skills](/docs/coding-agents/skills) to write the YAML from an existing spec. This is the recommended way to port a suite. Momentic ships no automatic converter from Playwright, Cypress, or Selenium. Keep your existing suite and CI gate while you port one bounded flow. Preserve its setup, authentication, data, assertions, waits, and cleanup. Label the new test, lint it, and inspect the selection with `momentic list --labels migrated` (or `momentic-mobile list --labels migrated` for mobile) before running it. Compare both runners on the same build and starting state, including an expected failure. Review recovery and classification as well as the pass status. Retire an old spec only after its replacement preserves the coverage and CI failure behavior you require. Keep unsupported browser, device, fixture, or component coverage in its existing runner. Follow the guide for your source framework: * [Playwright](/docs/guides/migrate/from-playwright): fixtures, storage state, browser projects, and network checks. * [Cypress](/docs/guides/migrate/from-cypress): session validation, intercepts, command chains, and plugins. * [Selenium and Appium](/docs/guides/migrate/from-selenium-appium): page objects, waits, capabilities, and device support. * [Maestro](/docs/guides/migrate/from-maestro): subflows, launch/reset behavior, selectors, and variables. Reuse seed endpoints and setup logic in a [JavaScript step](/docs/reference/commands/javascript) with the documented [Node sandbox globals](/docs/integrations/javascript). Helpers that depend on a framework's driver, fixtures, or imported packages need adaptation or an external setup script. `authLoad` reads cookies and local storage from a Playwright storage-state file; keep the auth bootstrap and validate any IndexedDB-dependent authentication separately. ## Migrate out of Momentic Momentic ships no exporter. 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. * [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 single call in a code-first framework. A preset step that resolves a target in plain English, evaluates an assertion, or extracts data with AI does not. Results already export in standard formats. Use `--reporter junit`, `--reporter json`, or `--reporter playwright-json` so your dashboards and CI gates do not depend on Momentic's. 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. When they share a configuration, follow the [simplified-format guide](/docs/get-started/migrate-to-simplified-format) to rewrite both platforms' files; one upgrade does not convert the other platform. ## Migrate with a coding agent Paste this prompt into your coding agent. It runs the upgrade and checks the result against an existing mobile test. ```text theme={null} Help me upgrade this project to momentic-mobile 1.x. ## What to do 1. Run `git status --short`. If there are uncommitted changes, stop and ask me. 2. Check `node -v`. Supported versions are 22.12.0 or later in the 22 line, and 24.0.0 or later. If the version is outside that range (for example 20 or 23), stop and tell me. Also update `.nvmrc`, the `engines` field in `package.json`, and the Node version in CI config if they pin an unsupported version. 3. Run `npx momentic-mobile@latest upgrade --dry-run` from the project root and show me the plan. Then run `npx momentic-mobile@latest upgrade --yes`. 4. Fix the breaking change. Search CI config, `package.json` scripts, and shell scripts for `--record-video`. It kept every recording, so replace it with `--video true` to keep that behavior. Ask me before you pick `--video false` or the new default `on-fail`. 5. Run `npx momentic-mobile skills --yes` so the coding agent skills match the new CLI. 6. Run one existing test with `npx momentic-mobile run ` to confirm it passes. ## Critical rules - Follow the steps in order. - Show me the diff before you commit. - Do not change test behavior. The upgrade updates the CLI, the file format, and the recommended config defaults. Do not edit test steps by hand. ## When done, report - What changed in `momentic.config.yaml`. - Which test files were rewritten. - Anything you could not fix. ``` ## 1. Use a supported Node.js version momentic-mobile 1.0 requires Node.js 22.12.0 or later in the 22.x line, or 24.0.0 or later. Node.js 20 and 23 are unsupported. Check your version: ```bash theme={null} node --version ``` Update the Node version in your CI images and any `.nvmrc` / `engines` field before upgrading. ## 2. Run the upgrade Save your current configuration, tests, `package.json`, and lockfile before upgrading. Check `git status --short` and keep unrelated changes separate so you can recover from a partial rewrite. If the upgrade changes the file format, coordinate with collaborators and have them rebase after it lands. From your mobile project root, preview the changes first: ```bash theme={null} npx momentic-mobile@latest upgrade --dry-run ``` The preview needs a valid saved login or `MOMENTIC_API_KEY`. Check it with `npx momentic-mobile@latest whoami`; see [authentication](/docs/cli-reference/momentic-mobile/commands/login) if it fails. `--dry-run` skips the package installation, project file writes, and snapshot uploads. Review the preview, then apply the upgrade: ```bash theme={null} npx momentic-mobile@latest upgrade ``` Invoke `momentic-mobile@latest` so the rewrite uses the current serializer. Updating the package during a command does not replace that command's running process. Use `--config ` if project discovery finds more than one configuration. The command installs the CLI as a development dependency and updates the project configuration. For a legacy-format project, it rewrites mobile tests and modules and sets `fileFormat: v2`. It also updates `ai.agentConfig`: entries that match the recommendation or start with it followed by `.` stay unchanged. Other versions, including older exact pins, change to the recommendation. It sets `ai.useMemory: true` and `ai.failureRecovery: true`, even if you previously disabled them. Review those changes before running tests. When the config already says `fileFormat: v2`, upgrade skips the YAML rewrite. If legacy files remain, first recover from any partial migration, then use [`momentic-mobile migrate simplified-format`](/docs/cli-reference/momentic-mobile/commands/migrate). If the format and AI settings are already current, project files stay unchanged; the package installation can still update the CLI. See [`momentic-mobile upgrade`](/docs/cli-reference/momentic-mobile/commands/upgrade). The upgrade is not atomic. It installs the CLI before rewriting project files. If serialization fails, some files may already have changed. Revert the changes made by that upgrade attempt, fix the reported error, and rerun. Preserve unrelated work; reinstall the previous dependency version if you need to restore the pre-upgrade installation. ## 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. An explicit `recordVideo` setting or `--video` flag overrides this default. ## Other changes These need no action: * AI action steps default to the V3 agent. Existing steps continue to run unchanged. * `momentic-mobile init` writes recommended AI agent versions for new projects. It does not rewrite an existing configuration. Current agent defaults can use a major version; pin an exact supported sub-version when you need that revision to stay fixed. See [AI configuration](/docs/configuration/ai). ## 3. Validate and update CI Validate the rewritten files, then run an existing test with the same app build, device settings, environment, and test data as before upgrading. Replace the example path with your test: ```bash theme={null} npx momentic-mobile lint npx momentic-mobile list npx momentic-mobile run mobile-tests/login.test.yaml --upload-results ``` Inspect the run result, recovery activity, and failure classifications before changing the test. Then run the affected suite and confirm the expected tests and parameterized cases actually ran. Account for disabled or skipped tests and quarantine; exit code `0` alone does not prove equivalent behavior. Once the checks pass, review and commit `momentic.config.yaml`, rewritten tests and modules, `package.json`, and the lockfile together. Update explicit Momentic Mobile version pins in CI, then install from the committed lockfile and invoke the project CLI. Mobile tests do not need a browser reinstallation; retain the [iOS](/docs/platforms/ios/simulators) or [Android](/docs/platforms/android/app-setup) toolchain required by your tests. ## 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. When they share a configuration, follow the [simplified-format guide](/docs/get-started/migrate-to-simplified-format) to rewrite both platforms' files; one upgrade does not convert the other platform. ## Migrate with a coding agent Paste this prompt into your coding agent. It runs the upgrade, reinstalls the browsers, and checks the result against an existing test. ```text theme={null} Help me upgrade this project to momentic 3.x. ## What to do 1. Run `git status --short`. If there are uncommitted changes, stop and ask me. 2. Check `node -v`. Supported versions are 22.12.0 or later in the 22 line, and 24.0.0 or later. If the version is outside that range (for example 20 or 23), stop and tell me. Also update `.nvmrc`, the `engines` field in `package.json`, and the Node version in CI config if they pin an unsupported version. 3. Run `npx momentic@latest upgrade --dry-run` from the project root and show me the plan. Then run `npx momentic@latest upgrade --yes`. 4. Reinstall the browsers the tests use. Check `momentic.config.yaml` and CI config for `chrome` or `chrome-for-testing`. If in doubt, run `npx momentic install-browsers --all`. 5. Fix the breaking changes: - In `momentic.config.yaml`, remove `browser.bustCacheOnBoundingBoxChange` and change any `v1` agent in `ai.agentConfig` to a current version. See https://momentic.ai/docs/configuration/ai. - Search CI config, `package.json` scripts, and shell scripts for `--record-video`. It kept every recording, so replace it with `--video true` to keep that behavior. Ask me before you pick `--video false` or the new default `on-fail`. 6. Run `npx momentic skills --yes` so the coding agent skills match the new CLI. 7. Run one existing test with `npx momentic run ` to confirm it passes. ## Critical rules - Follow the steps in order. - Show me the diff before you commit. - Do not change test behavior. The upgrade updates the CLI, the file format, and the recommended config defaults. Do not edit test steps by hand. ## When done, report - What changed in `momentic.config.yaml`. - Which test files were rewritten. - Anything you could not fix. ``` ## 1. Use a supported Node.js version momentic 3.0 requires Node.js 22.12.0 or later in the 22.x line, or 24.0.0 or later. Node.js 20 and 23 are unsupported. Check your version: ```bash theme={null} node --version ``` Update the Node version in your CI images and any `.nvmrc` / `engines` field before upgrading. ## 2. Run the upgrade Save your current configuration, tests, `package.json`, and lockfile before upgrading. Check `git status --short` and keep unrelated changes separate so you can recover from a partial rewrite. If the upgrade changes the file format, coordinate with collaborators and have them rebase after it lands. From your web project root, preview the changes first: ```bash theme={null} npx momentic@latest upgrade --dry-run ``` The preview requires authentication with a saved login or an API key. Check it with `npx momentic@latest whoami`; see [authentication](/docs/cli-reference/momentic/commands/login) if it fails. `--dry-run` skips the package installation, project file writes, and snapshot uploads. Review the preview, then apply the upgrade: ```bash theme={null} npx momentic@latest upgrade ``` Invoke `momentic@latest` so the rewrite uses the current serializer. Updating the package during a command does not replace that command's running process. Use `--config ` if project discovery finds more than one configuration. The command installs the CLI as a development dependency and updates the project configuration. For a legacy-format project, it rewrites web tests and modules and sets `fileFormat: v2`. It also updates `ai.agentConfig`: entries that match the recommendation or start with it followed by `.` stay unchanged. Other versions, including older exact pins, change to the recommendation. It sets `ai.useMemory: true` and `ai.failureRecovery: true`, even if you previously disabled them. Review those changes before running tests. Browser settings are not part of this AI refresh. When the config already says `fileFormat: v2`, upgrade skips the YAML rewrite. If legacy files remain, first recover from any partial migration, then use [`momentic migrate simplified-format`](/docs/cli-reference/momentic/commands/migrate). If the format and AI settings are already current, project files stay unchanged; the package installation can still update the CLI. See [`momentic upgrade`](/docs/cli-reference/momentic/commands/upgrade). The upgrade is not atomic. It installs the CLI before rewriting project files. If serialization fails, some files may already have changed. Revert the changes made by that upgrade attempt, fix the reported error, and rerun. Preserve unrelated work; reinstall the previous dependency version if you need to restore the pre-upgrade installation. ## 3. Reinstall your browsers momentic 3.0 pins newer browser builds than earlier releases. `momentic upgrade` does not download them. If your tests launch browsers locally, binaries installed for the previous build can fail to launch, so reinstall them after upgrading: ```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. ## 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.** Momentic validates cached locators without this option. 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. An explicit `recordVideo` setting or `--video` flag overrides this default. * **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. ## Browser and agent defaults Hybrid selectors default to `prefer` when `browser.hybridSelectorMode` is unset, including in existing projects. Set it explicitly to override that default. `momentic init` also writes `browser.disableSecondaryCacheResolution: true` and recommended `ai.agentConfig` versions for new projects. It does not rewrite an existing configuration. Current agent defaults can use a major version; pin an exact supported sub-version when you need that revision to stay fixed. See [AI configuration](/docs/configuration/ai). ## 4. Validate and update CI Validate the rewritten files, then run an existing test against the same target and test data used before upgrading. Replace the example path with your test: ```bash theme={null} npx momentic lint npx momentic list npx momentic run tests/checkout.test.yaml --upload-results ``` Inspect the run result, recovery activity, and failure classifications before changing the test. Then run the affected suite and confirm the expected tests and parameterized cases actually ran. Account for disabled or skipped tests and quarantine; exit code `0` alone does not prove equivalent behavior. Once the checks pass, review and commit `momentic.config.yaml`, rewritten tests and modules, `package.json`, and the lockfile together. Update explicit Momentic version pins in CI, then install from the committed lockfile and invoke the project CLI. If CI launches browsers locally, reinstall the selected browsers with that version too. ## 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 common Momentic tasks, like auth, file uploads, network assertions, and data-driven runs. Use these recipes to configure and run repository tests. For exploratory QA sessions and bug reports, see [Mo](/docs/mo). Classify failures during a run, control CI gating, and route failures into AI test maintenance. Write bounded goals, split flows at checkpoints, and verify their outcomes. 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. Pull request checks, regression passes, and deploy gates. Complete recipes: PR gates, preview smoke tests, nightly suites, SSO apps, third-party monitors. Setup guides for Next.js on Vercel, Expo, React Native, and Flutter. Move a suite from Playwright, Cypress, Selenium, or Maestro, and keep your tests portable. Run QA sessions against a preview or user flow and review the reported bugs. Version upgrades, format migrations, and the cloud deprecation path. # Writing AI actions Source: https://momentic.ai/docs/guides/ai-actions/guide Write bounded AI action goals, split flows at checkpoints, and use preconditions and postconditions to verify outcomes. An [AI action](/docs/core-concepts/agentic-testing) takes a natural-language goal instead of a click-by-click series of steps. Read that page first for how the agent plans, caches, and self-heals. This page covers the patterns: when to use each one and what it costs. ## 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 the AI action step. 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. The imperative version below spells out every click and keystroke. The intent, a flight search between two cities on 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: flight-search-preset 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 ``` The same flow as a single declarative goal: ```yaml flight-search.test.yaml theme={null} fileType: momentic/test/v2 id: flight-search-goal 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. ``` Both versions locate controls by description. Preset steps preserve the interaction sequence; an AI action lets the agent choose the sequence needed to reach the goal. Changes to the UI may require a new resolution or a test update in either form. ### 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 happened. You write an explicit `postcondition` when the goal alone does not tell the reviewer what "done" should look like. For a flight search, require rendered results for the requested cities and dates. 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: flight-search-verified 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. ``` A `postcondition` spells out what "done" means for that `act`. When you chain steps, each one 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 flip side: do not collapse an *entire* test into one giant goal either. Aim for 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: browse-products 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. ``` Keep each goal focused on one checkpoint, such as logging in, sorting, or opening a product. This makes the generated trace and failures easier to review. Split goals that contain several independent outcomes. ## Guardrails with preconditions and postconditions Use `precondition` and `postcondition` as guardrails for the start and end states of a V3 AI action. The agent cannot edit or skip these assertions. A failed precondition prevents the generated flow from running. If the postcondition is unmet, the agent keeps working toward it or fails the step. ```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 retry without a plan. Add an explicit `postcondition` whenever the goal itself does not pin down the end state of a state-changing flow. These guards check state; they do not prescribe every intermediate interaction the agent chooses. Use [preset steps](/docs/core-concepts/steps#preset-steps) when you need to control the interaction sequence. 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"). Use deterministic element or JavaScript checks for exact counts, prices, timestamps, or IDs. ## Feeding the agent context it cannot infer Supply test-specific data the agent cannot infer, such as an invite code, a specific record, or credentials, 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 in only some runs: cookie banners, "what's new" modals, A/B interstitials. When the agent resolves 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). ## Limits An AI action has an execution budget. State a finite stopping point so the agent can complete or report a failure within that budget. ### No unbounded loops The agent will not "keep clicking Next until the list is empty" forever. It runs a bounded plan with a retry budget, then stops instead of repeating an ineffective interaction. If your intent is to repeat until a condition holds, 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 Cache browser authentication state to reuse it across tests and runs. 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. an **Element check** for the dashboard heading). 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 saves and restores the state 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: log-in 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 - checkElementVisible: the Dashboard heading ``` 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. ## What gets cached 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. Your app emails a magic login link to the provisioned inbox, and a **JavaScript** step in the test fetches the latest message and pulls the link out. Use this recipe when login arrives as a URL instead of a code. **Prerequisite**: A Momentic-provisioned inbox. [Request one](mailto:support@momentic.ai). ## Fetch and navigate Add a **JavaScript** step that fetches the latest email, extracts the verification link, and saves it to the environment. ```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, up to 600 seconds. ## 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. Your app emails a one-time passcode to the provisioned inbox, and a **JavaScript** step in the test fetches the latest message and pulls the code out. Use this recipe when login arrives as a code instead of a link. **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, up to 600 seconds. ## 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). Generate a time-based 2FA code inside a **JavaScript** step with the [`otpauth`](https://www.npmjs.com/package/otpauth) library, which Momentic preloads in the step sandbox. Reach for this when a login flow asks for an authenticator-app code. ## 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/configuration/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 performs the login on every run, so each test starts with newly captured authentication state. ```yaml log-in.module.yaml theme={null} fileType: momentic/module/v2 id: log-in name: Log in steps: - type: text: "{{ env.USERNAME }}" into: Email input - type: text: "{{ env.PASSWORD }}" into: Password input - click: Log in - checkElementVisible: the Dashboard heading ``` ```yaml checkout.test.yaml theme={null} fileType: momentic/test/v2 id: checkout 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 ``` Move to one of the options below 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 can be generated in a setup step and reused by compatible tools. It contains authentication credentials; keep it out of version control and 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: log-in 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 - checkElementVisible: the Dashboard heading ``` Call it from the `before` section exactly like the live-login module. Momentic handles capture, storage, expiry, and per-key isolation. Tests sharing a cache key can reuse the saved session while it remains valid. 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) | Fresh login each run; adds login time and can hit provider rate limits. | | `authSave` / `authLoad` state file | Whenever you place the steps | Portable JSON, like Playwright's `storageState`. You own refreshing it when it expires. | | Cached auth module (`autoAuth` + caching) | On a cache miss or after expiry | Reuses saved state; needs an appropriate 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. Your app texts a one-time passcode to the provisioned number, and a **JavaScript** step in the test fetches the latest message and pulls the code out. Use a single number for serial runs; lease numbers from a pool when tests run in parallel. **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, up to 600 seconds. ## 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). Send the bypass secret in headers or in query parameters. CORS blocks the headers on some apps; the query parameters still work there. ## 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**: ```text theme={null} 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`, when 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 CLI writes the verdict 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`. The job passes 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: * The in-flow setup needs no separate CI command or run selector. The verdict is part of the run result when `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. * The CLI saves the verdict 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`. # Common CI setups Source: https://momentic.ai/docs/guides/common-setups Run the same tests as a pull request check, a full regression pass, and a deploy gate, with the CI config for each. One Momentic test suite does three jobs. Run a subset on each pull request, the full suite on every merge, and the critical flows around each deploy. The tests are the same. The trigger, the target URL, and the size of the run differ. | Job | When it runs | What it runs | Target | | - | - | - | - | | Pull request check | On every pull request | Tests for the changed flows | The branch's preview deployment | | Regression pass | On every merge or on a schedule | The whole test suite | Staging or production | | Deploy gate | Before or after each deploy | The critical flows | The deployed URL | Every job is one `momentic run` command in CI. The examples below use GitHub Actions. See [GitLab CI](/docs/running-tests/ci/gitlab-ci) or [custom setups](/docs/running-tests/ci/custom-setups) for other providers. Each job needs `MOMENTIC_API_KEY` as a secret; see [GitHub Actions](/docs/running-tests/ci/github-actions#authentication) for how to create it. A failed run exits non-zero, so CI blocks the merge or the release. Quarantined tests are the exception and do not affect the exit code by default. ## Pull request check Run the tests against the pull request's preview deployment, so the change runs in a real browser before review. This job starts when Vercel (or any provider that posts a GitHub deployment) marks the preview as ready. It runs only the tests that AI test selection picks from the diff: ```yaml .github/workflows/pr-tests.yml theme={null} name: PR tests on: deployment_status: jobs: test: if: >- github.event.deployment_status.state == 'success' && github.event.deployment.environment == 'Preview' runs-on: ubuntu-latest timeout-minutes: 20 env: MOMENTIC_API_KEY: ${{ secrets.MOMENTIC_API_KEY }} steps: - uses: actions/checkout@v4 with: fetch-depth: 0 - uses: actions/setup-node@v4 with: node-version: 22.12.0 cache: "npm" - run: npm install - run: npx momentic install-browsers --all - name: Run the tests for this diff run: | npx momentic run \ --url-override "${{ github.event.deployment_status.environment_url }}" \ --custom-headers \ "x-vercel-protection-bypass=${{ secrets.VERCEL_BYPASS_SECRET }}" \ "x-vercel-set-bypass-cookie=true" \ --ai-select --ai-select-base origin/main \ --reporter steps --reporter junit \ --upload-results - uses: actions/upload-artifact@v4 if: always() with: name: junit path: reports ``` What each part does: * `deployment_status` fires when the provider reports a deployment. The `if` guard runs the job only for a ready `Preview` deployment. Match the environment name your provider posts; `environment_url` is its target URL. * `fetch-depth: 0` gives `--ai-select` the full history to diff against `origin/main`. The `deployment_status` event carries no pull request base, so `--ai-select-base` sets it. On a `pull_request` event you can omit it. See [AI test selection](/docs/ai/select). * `--url-override` points every test at the preview URL. It also replaces a test's own `url`. * The two `--custom-headers` values pass Vercel's protection bypass. Skip them if the preview is public. See [Vercel preview auth](/docs/guides/auth/vercel-previews). * `--reporter steps` prints one line per step to the CI log. `--reporter junit` writes a JUnit XML file to `reports/` for your CI's test summary. See [JUnit outputs](/docs/guides/reporting/junit-outputs). Make the job a required status check on the branch so a failing run blocks the merge. Decide how the check treats flaky tests: quarantined tests run but do not fail the check by default. Pass `--skip-quarantined` to skip them, or `--ignore-quarantine` to count every status. See [quarantine](/docs/reliability/auto-maintenance#quarantine). ### Add tests in the same pull request The existing suite only catches regressions in flows it already covers. To cover what the pull request changes, ask your coding agent with the [`momentic-spec` skill](/docs/coding-agents/skills#spec-driven-development): ```text theme={null} /momentic-spec cover the user journeys changed by this pull request ``` The agent writes `.test.yaml` files into your working tree, so the new tests land in the same review as the change and run in the same CI job. ### Review test changes in the pull request A Momentic test is a YAML file, so a reviewer reads it in the diff like any other code. For a test an agent wrote, check three things: * Each step states what a user does or sees. A `click`, `type`, or `assert` step names one element or one condition. An `act` step states its `goal`, and adds a `postcondition` when the goal leaves the end state open, so the run fails when the outcome is missing rather than passing on any path. See [agentic testing](/docs/core-concepts/agentic-testing). * The test ends in an assertion. A test that only clicks through a flow passes as long as the elements exist, and does not catch a broken result. * Shared setup such as login comes from a [module](/docs/core-concepts/modules) instead of repeated steps, and credentials come from [environment variables](/docs/configuration/environment-variables), not literals in the file. Then read the run, not only the file. The pull request check above uploads the results, and the [GitHub integration](/docs/integrations/github) posts a status comment on the pull request with a link to each run. Open the run to read the screenshots and the trace for every step in [results](/docs/running-tests/results). To rerun the changed tests on your own machine before approving, check out the branch and run: ```bash theme={null} npx momentic list --changed | xargs -r npx momentic run --upload-results ``` `momentic list --changed` lists the test files the branch changed plus the tests that use a changed module. `momentic lint ` validates one file's schema and file references without a run; see [`momentic lint`](/docs/cli-reference/momentic/commands/lint). ## Regression pass Run the whole test suite on every merge to `main` and on a nightly schedule. This job shards the suite across four runners and merges the results into one run group in the dashboard: ```yaml .github/workflows/regression.yml theme={null} name: Regression on: push: branches: ["main"] schedule: - cron: "0 6 * * *" jobs: test: runs-on: ubuntu-latest timeout-minutes: 30 env: MOMENTIC_API_KEY: ${{ secrets.MOMENTIC_API_KEY }} strategy: fail-fast: false matrix: shard: [1, 2, 3, 4] steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: 22.12.0 cache: "npm" - run: npm install - run: npx momentic install-browsers --all - name: Run shard ${{ matrix.shard }} run: | npx momentic run \ --env staging \ --shard-index ${{ matrix.shard }} \ --shard-count 4 \ --output-dir test-results/shard-${{ matrix.shard }} - uses: actions/upload-artifact@v4 if: always() with: name: test-results-${{ matrix.shard }} path: test-results retention-days: 1 upload: runs-on: ubuntu-latest if: always() needs: test env: MOMENTIC_API_KEY: ${{ secrets.MOMENTIC_API_KEY }} steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: 22.12.0 cache: "npm" - run: npm install - uses: actions/download-artifact@v4 with: path: test-results pattern: test-results-* merge-multiple: true - run: npx momentic results merge --output-dir test-results/merged test-results - run: npx momentic results upload test-results/merged ``` * `--env staging` selects the `staging` environment from `momentic.config.yaml`, so the same tests run against its `baseUrl` and credentials. See [environments](/docs/configuration/environments). * Each shard writes to its own `--output-dir`. The `upload` job merges them so the dashboard shows one run group instead of four. See [GitHub Actions](/docs/running-tests/ci/github-actions#sharding). Cover flows in order of the damage a regression causes, not in order of how hard they are to automate: * Revenue and retention paths first: sign-up, checkout, the primary action your product exists to do. * Flows that have regressed before. * Flows that exercise shared code that other features depend on. The suite is useful only if the team trusts a failure: * [Locator auto-healing](/docs/reliability/auto-maintenance#locator-auto-healing) can re-resolve a target during a run when the UI changed. It does not edit the test YAML. * Quarantine flaky tests instead of disabling them. They still run, so you keep the signal while you fix the test. * Reuse shared setup such as login with [modules](/docs/core-concepts/modules) so one change updates every test that depends on it. * Read the trace and screenshots for a failure in [results](/docs/running-tests/results). Give each flow an owner, so the person who triages a failure knows the flow. If your core flows still change every week, start with the deploy gate below and grow coverage as flows settle. ## Deploy gate Run a small set of critical flows against the new production deployment, and roll back if a flow fails. Use test accounts and a payment integration in test mode for the checkout below. Tag the flows with a `smoke` label: ```yaml tests/checkout.test.yaml theme={null} fileType: momentic/test/v2 id: checkout-smoke labels: [smoke, owner:payments] steps: - module: ../modules/log-in.module.yaml - click: Checkout - type: text: 4242 4242 4242 4242 into: Card number input - click: Pay now - assert: An order confirmation is visible ``` Run the labeled tests after the production deploy, and roll back when the run fails: ```yaml .github/workflows/deploy.yml theme={null} name: Deploy on: push: branches: ["main"] jobs: deploy: runs-on: ubuntu-latest outputs: url: ${{ steps.deploy.outputs.url }} steps: - uses: actions/checkout@v4 - id: deploy run: ./scripts/deploy.sh production # writes url=https://... to $GITHUB_OUTPUT smoke: runs-on: ubuntu-latest needs: deploy timeout-minutes: 10 env: MOMENTIC_API_KEY: ${{ secrets.MOMENTIC_API_KEY }} steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: 22.12.0 cache: "npm" - run: npm install - run: npx momentic install-browsers --all - name: Smoke test production run: | npx momentic run \ --labels smoke \ --url-override "${{ needs.deploy.outputs.url }}" \ --retries 1 \ --upload-results - name: Roll back if: failure() run: ./scripts/rollback.sh production ``` * `--labels smoke` runs only tests that carry the label. A path (`npx momentic run tests/smoke`) or `--include` and `--exclude` also work. The `include` and `exclude` globs in `momentic.config.yaml` control discovery, not one run. * `--retries 1` reruns a failed test once before the job fails, so one transient network error does not trigger a rollback. * Run the same job before the deploy against staging with `--url-override "$STAGING_URL"` if you want a gate in front of the release too. Keep the set small so it finishes in minutes and does not grow into a second regression suite: * Flows whose failure is an incident: login, checkout, the primary create or submit action. * One happy path per flow. Leave edge cases to the regression pass. * End-to-end paths, so one test runs against the real stack. For a flow whose steps differ by environment or feature flag, use an AI action with a goal and a postcondition instead of a fixed sequence of preset steps: ```yaml tests/signup.test.yaml theme={null} fileType: momentic/test/v2 id: signup-smoke labels: [smoke] steps: - act: goal: Complete the new-user signup flow using a fresh email. postcondition: The welcome screen is visible. ``` See [agentic testing](/docs/core-concepts/agentic-testing) for when to use an AI action. ## Related Authentication, sharding, and result upload in detail. Pick the tests to run from a git diff. Isolate unstable tests without blocking the rest of the suite. Point the same tests at staging or production. # 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. 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 ``` 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 ``` ```bash theme={null} npx momentic run --input-csv inputs.csv inputs-test.test.yaml ``` Momentic runs the test once per CSV row. It substitutes the column values into `env`. ## Related * [Variables](/docs/core-concepts/variables) * [`momentic run`](/docs/cli-reference/momentic/commands/run) # Expo Source: https://momentic.ai/docs/guides/frameworks/expo Build an Expo app into a testable APK or simulator bundle and run Momentic mobile tests against it, locally and in CI. Momentic tests the **native build** of an Expo app, not the JS bundle. The pipeline is: produce an APK (Android) or simulator `.app` (iOS), upload it to a channel/tag, and run `momentic-mobile` against it. Both EAS Build and `expo prebuild` with local toolchains work. ## Produce a testable build **Option A: EAS (recommended if you already use it)** ```bash theme={null} eas build --platform android --profile preview --local ``` A `preview` profile with `"buildType": "apk"` (or `"distribution": "internal"`) in `eas.json` produces an installable `.apk`. Without `--local`, the build runs in EAS cloud and you download the artifact URL. **Option B: prebuild + Gradle (no EAS account)** ```bash theme={null} npx expo prebuild --platform android # generates android/ cd android && ./gradlew assembleRelease # APK in android/app/build/outputs/apk/release/ ``` Momentic runs simulator builds, not device `.ipa` files. ```bash theme={null} npx expo prebuild --platform ios # generates ios/ xcodebuild \ -workspace ios/MyApp.xcworkspace \ -scheme MyApp \ -sdk iphonesimulator \ -configuration Debug \ -derivedDataPath build \ build-for-testing # .app in build/Build/Products/Debug-iphonesimulator/ ``` Or with EAS, using a simulator profile: ```bash theme={null} eas build --platform ios --profile preview --local ``` where `preview` sets `"ios": { "simulator": true }` in `eas.json`. ## Upload and run Remote emulators and simulators install the app from an uploaded asset. Add the CLI as a dev dependency so the lockfile pins the version in CI: ```bash theme={null} npm install --save-dev momentic-mobile ``` Upload the artifact: ```bash theme={null} npx momentic-mobile assets upload ./android/app/build/outputs/apk/release/app-release.apk \ --channel dev --tag 1.0.0 ``` Run a test against it: ```yaml smoke.test.yaml theme={null} fileType: momentic/mobile-test/v2 id: expo-smoke description: Open the app and verify the home screen platform: android labels: [smoke] defaultChannel: dev defaultTag: "1.0.0" steps: - openApp: com.example.myapp - assert: The home screen is visible ``` ```bash theme={null} npx momentic-mobile run smoke.test.yaml ``` `defaultChannel`/`defaultTag` on the test pick the uploaded asset. In the editor, the same selection appears as the **Channel**/**Tag** pickers next to the **Region** dropdown; choose any Momentic region for a remote instance. ## Expo-specific pitfalls * **Expo Go is not testable.** Momentic installs your standalone build, not Expo Go. Use a `prebuild` or EAS artifact. Builds configured with [EAS Update](https://docs.expo.dev/eas-update/introduction/) can receive compatible JavaScript and asset updates. Confirm the update channel and runtime version before testing; changes to native code or dependencies require a new build. * **Dev-client builds work.** An `expo-dev-client` build is a normal APK; test it the same way. Point it at a reachable Metro/dev server or a published update channel. * **Deep links and app links** resolve through the installed app id; use an `appium` step (`mobile: deepLink`) to open them. * **`expo-router` headers and safe areas** appear as native elements to Momentic. Describe them as the user sees them ("the back chevron", "the Settings tab"), not by testID. * **WebView content** on Android needs `WebView.setWebContentsDebuggingEnabled(true)`; add it in `MainApplication` or a small config plugin if your app renders web content. ## In CI Run an EAS build, upload the artifact to a channel, then run your suite against that same upload. This workflow uses an EAS `preview` profile that produces an APK and authenticates through `EXPO_TOKEN`: ```yaml .github/workflows/mobile.yml theme={null} name: Mobile tests on: [pull_request] jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: 22.12.0 - uses: actions/setup-java@v4 with: distribution: temurin java-version: "17" - run: npm install - name: EAS build (Android preview) run: npx eas-cli build --platform android --profile preview --local --non-interactive --output ./build/app.apk env: EXPO_TOKEN: ${{ secrets.EXPO_TOKEN }} - name: Upload APK to Momentic run: | npx momentic-mobile assets upload ./build/app.apk \ --channel dev --tag ${{ github.sha }}-${{ github.run_id }}-${{ github.run_attempt }} env: MOMENTIC_API_KEY: ${{ secrets.MOMENTIC_API_KEY }} - name: Run mobile tests run: | npx momentic-mobile run --labels smoke \ --channel dev --tag ${{ github.sha }}-${{ github.run_id }}-${{ github.run_attempt }} -y env: MOMENTIC_API_KEY: ${{ secrets.MOMENTIC_API_KEY }} ``` The unique tag selects the APK this job uploaded and avoids collisions when a rerun builds different bytes for the same commit. Without `--channel` and `--tag`, tests fall back to their `defaultChannel` and `defaultTag`. The runner also needs the Android SDK and `ANDROID_HOME`; GitHub-hosted Ubuntu runners include them. See [Android app setup](/docs/platforms/android/app-setup). ## Related * [Android app setup](/docs/platforms/android/app-setup) * [iOS app setup](/docs/platforms/ios/app-setup) * [Emulators](/docs/platforms/android/emulators) and [simulators](/docs/platforms/ios/simulators) * [React Native guide](/docs/guides/frameworks/react-native) # Flutter Source: https://momentic.ai/docs/guides/frameworks/flutter Build a Flutter app into a testable APK or simulator bundle and run Momentic mobile tests against it, locally and in CI. Momentic tests the **native build** of a Flutter app. The pipeline is: produce an APK (Android) or simulator `.app` (iOS), upload it to a channel/tag, and run `momentic-mobile`. Momentic drives the compiled app through the platform driver rather than Flutter-specific test APIs. ## Produce a testable build ```bash theme={null} flutter build apk --release # APK in build/app/outputs/flutter-apk/app-release.apk ``` `flutter build apk --debug` also works for local iteration. ```bash theme={null} flutter build ios --simulator # .app in build/ios/iphonesimulator/ ``` Builds must target the simulator. A device `.ipa` cannot run on a simulator and Momentic does not support physical devices. ## Upload and run Add the CLI as a dev dependency so the lockfile pins the version in CI: ```bash theme={null} npm install --save-dev momentic-mobile ``` Then upload and run: ```bash theme={null} npx momentic-mobile assets upload ./build/app/outputs/flutter-apk/app-release.apk \ --channel dev --tag 1.0.0 ``` ```yaml smoke.test.yaml theme={null} fileType: momentic/mobile-test/v2 id: flutter-smoke description: Open the app and verify the home screen platform: android labels: [smoke] defaultChannel: dev defaultTag: "1.0.0" steps: - openApp: com.example.myapp - assert: The home screen is visible ``` ```bash theme={null} npx momentic-mobile run smoke.test.yaml ``` ## Flutter pitfalls * **Semantics help identify controls.** Momentic uses screenshots and the native accessibility tree. Flutter semantics expose named controls to that tree. Most Material and Cupertino widgets provide semantics; custom `CustomPainter` content may need `Semantics` wrappers. If a visible control cannot be resolved, inspect its semantics along with the screenshot. * **`Key` values do not reach the accessibility tree.** `ValueKey('login-button')` is invisible to Momentic; keys exist for Flutter's own finder APIs. For a stable hook, wrap the widget in `Semantics(label:)` or give it a `tooltip`. Prefer natural-language targets that describe the control and its purpose. * **Splash and async init.** A Flutter app often shows a splash while `main()` awaits. Rather than a fixed `wait`, assert on the first application screen: `assert: The home screen is visible` with a `timeout`. * **Build-time configuration.** Pass test configuration through `--dart-define` when building. Changes made only in a running DevTools session do not update the uploaded artifact. * **Impeller vs. Skia rendering** does not change what the accessibility tree exposes; either engine works. * **WebView content** on Android needs `WebView.setWebContentsDebuggingEnabled(true)`. ## In CI ```yaml .github/workflows/mobile.yml theme={null} name: Mobile tests on: [pull_request] jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: 22.12.0 - uses: actions/setup-java@v4 with: distribution: temurin java-version: "17" - name: Set up Flutter uses: subosito/flutter-action@v2 with: channel: stable - name: Build APK run: flutter build apk --release - name: Upload APK to Momentic run: | npm install npx momentic-mobile assets upload ./build/app/outputs/flutter-apk/app-release.apk \ --channel dev --tag ${{ github.sha }}-${{ github.run_id }}-${{ github.run_attempt }} env: MOMENTIC_API_KEY: ${{ secrets.MOMENTIC_API_KEY }} - name: Run mobile tests run: | npx momentic-mobile run --labels smoke \ --channel dev --tag ${{ github.sha }}-${{ github.run_id }}-${{ github.run_attempt }} -y env: MOMENTIC_API_KEY: ${{ secrets.MOMENTIC_API_KEY }} ``` `--channel`/`--tag` on `run` select the asset this job just uploaded. iOS builds need `runs-on: macos-latest` with `flutter build ios --simulator` before the upload step. ## Related * [Android app setup](/docs/platforms/android/app-setup) * [iOS app setup](/docs/platforms/ios/app-setup) * [Emulators](/docs/platforms/android/emulators) and [simulators](/docs/platforms/ios/simulators) # Next.js on Vercel Source: https://momentic.ai/docs/guides/frameworks/nextjs-vercel Test a Next.js app on every Vercel preview deploy, including protection-bypassed previews. On Vercel, each pull request gets a preview deployment, CI runs Momentic against the preview URL, and a required status check can gate the merge. The only Vercel-specific piece is deployment protection. Every other step is generic Momentic web testing. ## Test against a local dev server ```bash theme={null} npm create next-app@latest my-app && cd my-app npm run dev # http://localhost:3000 ``` ```bash theme={null} npx @momentic/wizard@latest # or: npm i -D momentic && npx momentic init ``` ```yaml home.test.yaml theme={null} fileType: momentic/test/v2 id: home-renders url: http://localhost:3000 labels: [smoke] steps: - assert: The page finishes loading and shows the main heading ``` ```bash theme={null} npx momentic run home.test.yaml ``` ## Test a preview deployment Get the preview URL in CI. The `wait-for-vercel-preview` action in the workflow below resolves it, or use the Vercel CLI's `vercel inspect`. URL resolution is ordered: `--url-override` overrides a test's `url:` field, which takes precedence over the environment's `baseUrl`. The sample test pins `url:` for local runs, so point the run at the preview explicitly: ```bash theme={null} npx momentic run --url-override https://my-app-git-feat.vercel.app --labels smoke ``` Tests that have no `url:` fall through to the environment, so you can instead keep `url` off the test and select `environments[].baseUrl` with `--env preview`. Use one convention per repo. Mixed pinning makes `--env` a base URL ineffective for tests that set `url:`. The environment still supplies its variables and browser settings. ## Bypass deployment protection Vercel's standard protection blocks unauthenticated requests, including test browsers. Two options, both covered in [Test Vercel protected preview environments](/docs/guides/auth/vercel-previews): * Send `x-vercel-protection-bypass` + `x-vercel-set-bypass-cookie` headers on every request (fast; can hit CORS limits). * Append `?x-vercel-protection-bypass=&x-vercel-set-bypass-cookie=true` to the base URL (works through CORS; Vercel converts it to a cookie). Create the secret in Vercel project settings under **Deployment Protection > Protection Bypass for Automation**, store it as `VERCEL_AUTOMATION_BYPASS_SECRET`, and pass it through `envVariables` or the shell environment. Never commit it. ## In CI A complete GitHub Actions job that waits for the preview, then runs the suite with the bypass header: ```yaml .github/workflows/preview-tests.yml theme={null} name: Test Vercel preview on: pull_request jobs: test: if: github.event.pull_request.head.repo.full_name == github.repository runs-on: ubuntu-latest permissions: contents: read deployments: read steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: 22.12.0 - run: npm install - name: Wait for Vercel preview uses: patrickedqvist/wait-for-vercel-preview@v1.3.2 id: vercel with: token: ${{ secrets.GITHUB_TOKEN }} max_timeout: 600 - name: Install browsers run: npx momentic install-browsers chromium - name: Run Momentic run: | npx momentic run --labels smoke -y \ --url-override "${{ steps.vercel.outputs.url }}" \ --custom-headers x-vercel-protection-bypass=${{ secrets.VERCEL_AUTOMATION_BYPASS_SECRET }} \ x-vercel-set-bypass-cookie=true env: MOMENTIC_API_KEY: ${{ secrets.MOMENTIC_API_KEY }} ``` `--custom-headers` adds the bypass to every request the test makes. If your app sends cross-origin fetches that reject the header, switch to the query-param form from [Option B](/docs/guides/auth/vercel-previews) instead. ## Next.js pitfalls * **Hydration timing.** `next dev` and React transitions can leave elements visible-but-inert briefly. Assert on the post-hydration state ("the Sign in button is clickable") rather than adding fixed waits. * **`next/image` and visual assertions.** Placeholder blur and lazy images make pixel-level checks racy; keep visual assertions on stable regions. * Vercel's deployment-protection bypass does not sign in to your app. Include the app's login or session setup even when the deployment accepts the bypass header or query parameters. * **Preview vs production data.** Point `NEXT_PUBLIC_*` env vars at staging backends for previews so tests exercise realistic data without touching production. * **`VERCEL_AUTOMATION_BYPASS_SECRET` in forks.** GitHub does not pass secrets to workflows from forks; gate the test job with `if:` on same-repo PRs. Do not switch to `pull_request_target`: it runs with your repo's secrets while checking out fork-controlled code, which exposes those secrets. ## Related * [Test Vercel protected preview environments](/docs/guides/auth/vercel-previews) * [Run in CI](/docs/running-tests/ci/github-actions) * [Environments](/docs/configuration/environments) # React Native Source: https://momentic.ai/docs/guides/frameworks/react-native Build a React Native app into a testable APK or simulator bundle and run Momentic mobile tests against it, locally and in CI. Momentic tests the **native build** of a React Native app. The pipeline is: produce an APK (Android) or simulator `.app` (iOS), upload it to a channel/tag, run `momentic-mobile`. ## Produce a testable build The Gradle project lives in `android/`: ```bash theme={null} cd android && ./gradlew assembleRelease # APK in android/app/build/outputs/apk/release/ ``` For a faster debug build during authoring, `./gradlew assembleDebug` works too: debug builds are `debuggable=true` and need no extra configuration. Momentic runs simulator builds, not device `.ipa` files. Build for testing against the simulator SDK: ```bash theme={null} xcodebuild \ -workspace ios/MyApp.xcworkspace \ -scheme MyApp \ -sdk iphonesimulator \ -configuration Debug \ -derivedDataPath build \ build-for-testing # .app in build/Build/Products/Debug-iphonesimulator/ ``` Use the `.xcworkspace` (CocoaPods), not `.xcodeproj`. Simulator builds skip code signing and need no provisioning profile. ## Upload and run Add the CLI as a dev dependency so the lockfile pins the version in CI: ```bash theme={null} npm install --save-dev momentic-mobile ``` Then upload and run: ```bash theme={null} npx momentic-mobile assets upload ./android/app/build/outputs/apk/release/app-release.apk \ --channel dev --tag 1.0.0 ``` ```yaml smoke.test.yaml theme={null} fileType: momentic/mobile-test/v2 id: rn-smoke description: Open the app and verify the home screen platform: android labels: [smoke] defaultChannel: dev defaultTag: "1.0.0" steps: - openApp: com.example.myapp - assert: The home screen is visible ``` ```bash theme={null} npx momentic-mobile run smoke.test.yaml ``` In the editor, pick the channel/tag and a Momentic **Region** for a remote emulator or simulator, or `Local` for a local instance. ## React Native pitfalls * **Hermes and release-mode JS.** The tested build is the compiled native app. Changes to an embedded JavaScript bundle require a new build. Dev builds can load changes from Metro; apps with an update system may load a compatible published bundle. Confirm which bundle the uploaded app uses. * **Metro is optional.** A release APK embeds the JS bundle, so it needs no Metro server. A dev build that looks for Metro will hang at the loading screen if Metro is not running; test release/preview builds unless you specifically want dev-server coverage. * **`testID` becomes an accessibility identifier.** React Native `testID` props reach the native layer, so `tap: the element with testID login` works. Prefer describing what the user sees so the target captures the intended control. * **Third-party native modules** (maps, cameras, Bluetooth) behave as they do on any emulator. Simulated camera/microphone input is available through `setCamera` and `setMicrophone` on hosted iOS simulators; some hardware-backed features have no emulator equivalent. * **WebView content** on Android needs `WebView.setWebContentsDebuggingEnabled(true)`. * **Deep links** open via an `appium` step (`mobile: deepLink`). ## In CI ```yaml .github/workflows/mobile.yml theme={null} name: Mobile tests on: [pull_request] jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: 22.12.0 - run: npm install - name: Set up Android toolchain uses: actions/setup-java@v4 with: distribution: temurin java-version: "17" - name: Build APK run: cd android && ./gradlew assembleRelease - name: Upload APK to Momentic run: | npx momentic-mobile assets upload ./android/app/build/outputs/apk/release/app-release.apk \ --channel dev --tag ${{ github.sha }}-${{ github.run_id }}-${{ github.run_attempt }} env: MOMENTIC_API_KEY: ${{ secrets.MOMENTIC_API_KEY }} - name: Run mobile tests run: | npx momentic-mobile run --labels smoke \ --channel dev --tag ${{ github.sha }}-${{ github.run_id }}-${{ github.run_attempt }} -y env: MOMENTIC_API_KEY: ${{ secrets.MOMENTIC_API_KEY }} ``` `--channel`/`--tag` on `run` select the asset this job just uploaded; tests' `defaultChannel`/`defaultTag` only apply when the flags are absent. iOS builds need a macOS runner (`runs-on: macos-latest`) and an `xcodebuild build-for-testing` step before upload. ## Related * [Android app setup](/docs/platforms/android/app-setup) * [iOS app setup](/docs/platforms/ios/app-setup) * [Expo guide](/docs/guides/frameworks/expo) for the Expo-managed workflow * [Emulators](/docs/platforms/android/emulators) and [simulators](/docs/platforms/ios/simulators) # From Cypress Source: https://momentic.ai/docs/guides/migrate/from-cypress Port a Cypress suite to Momentic, including custom commands, fixtures, intercepts, and session caching. Move one Cypress flow at a time, preserving its authentication, mocked responses, actions, assertions, and cleanup. Momentic tests are YAML steps rather than `cy` command chains. A coding agent with the [MCP server](/docs/coding-agents/mcp-server) and [coding agent skills](/docs/coding-agents/skills) can draft the port; review the result against the spec before changing your CI gate. ## Before and after This example assumes `baseUrl: https://shop.example.com`, an existing `cy.loginByApi` custom command, and this cart fixture: ```json cypress/fixtures/cart.json theme={null} [{ "id": 1, "title": "Gravity Blanket", "qty": 1 }] ``` Both tests use a signed-in test account and create an order. Isolate or reset that account's server-side data between runs. ```js checkout.cy.js theme={null} describe("checkout", () => { beforeEach(() => { cy.session("user", () => cy.loginByApi()); cy.intercept("GET", "/api/cart", { fixture: "cart.json" }).as("cart"); cy.visit("/products/42"); }); it("lets a signed-in shopper buy a blanket", () => { cy.get('[data-testid="add-to-cart"]').click(); cy.get('[data-testid="cart-icon"]').click(); cy.wait("@cart"); cy.contains("Gravity Blanket").should("be.visible"); cy.contains("button", "Checkout").click(); cy.get("#email").type("jeff@example.com"); cy.contains("button", "Place order").click(); cy.location("pathname").should("match", /^\/orders\/\w+/); cy.contains("Order confirmed").should("be.visible"); }); }); ``` The same user-flow checks in Momentic. Before running it, create `tests/modules/log-in.module.yaml` by porting `cy.loginByApi`; it must establish and validate the same signed-in identity. See [session and fixture scope](#session-and-fixture-scope) below. ```yaml tests/checkout/checkout.test.yaml theme={null} fileType: momentic/test/v2 id: signed-in-checkout url: https://shop.example.com labels: [checkout] before: - module: ../modules/log-in.module.yaml - mock: regex: /api/cart$ method: get responseGenerator: |- return new Response( JSON.stringify([{ id: 1, title: "Gravity Blanket", qty: 1 }]), { status: 200, headers: { "content-type": "application/json" } } ); - registerRequestListener: key: cart regex: /api/cart$ method: get - navigate: https://shop.example.com/products/42 steps: - click: Add to cart - click: the cart icon - awaitListener: cart - checkElementVisible: the text "Gravity Blanket" - click: Checkout - type: text: jeff@example.com into: the Email field clear: never - click: Place order - waitForUrl: regex: ^https://shop\.example\.com/orders/\w+ - checkElementVisible: the text "Order confirmed" ``` The mock and listener are registered before navigating to the product page. This preserves the request wait, including a request made during page load. Adapt the matcher if your endpoint has query parameters. The response body matches `cart.json`; copying the filename alone would not load a fixture into a mock. YAML `regex` values omit JavaScript's surrounding `/.../` delimiters. Lint and run the new file alone, with whole-test retries disabled: ```bash theme={null} npx momentic lint tests/checkout/checkout.test.yaml npx momentic run tests/checkout/checkout.test.yaml --parallel 1 --retries 0 --upload-results ``` ## API mapping | Cypress | Momentic | | - | - | | `cy.visit(url)` | `navigate: ` or the test's top-level `url` | | `cy.get(sel).click()` | `click: ` or `click: { css: sel }` | | `cy.contains(text)` | `click` with a target to interact; `checkElementVisible` or `checkPageContains` to assert | | `.type(value)` | `type: { text: ..., into: , clear: never }` to append; `fill` replaces a value | | `.should("be.visible")` / assertions | `checkElementVisible` for visibility; `assert` for semantic conditions | | `cy.location().should(match)` | `waitForUrl: { regex }` | | `cy.intercept(...)` | [`mock`](/docs/reference/commands/mock) with `substring`, `glob`, `regex`, or `domain` | | `cy.wait("@alias")` | `registerRequestListener` before the trigger, then `awaitListener` to inspect the request/response | | `cy.wait(ms)` | `wait: `; prefer a preset condition with a timeout when a signal exists | | `cy.getCookie` / `cy.setCookie` | `cookie` sets cookies; browser `javascript` reads non-HttpOnly cookies | | `cy.clearLocalStorage` | Browser `javascript` calling `localStorage.clear()`; `localStorage` writes keys | | `cy.go("back")` / `"forward"` | `goBack` / `goForward` | | `cy.select(...)` | `select` for a native select; `click` or an `act` goal for a styled dropdown | | `cy.on("window:alert"/"confirm")` | `dialog: ACCEPT` or `DISMISS`, before the step that raises it | | `cy.screenshot()` | Per-step screenshots; `assertVisually` / `visualDiff` for visual checks | | `cy.fixture("cart.json")` | Inline JSON into the mock, or load it in Node `javascript` and pass the parsed value | | `cy.request(...)` | `request`, `graphqlRequest`, or Node `javascript` with `fetch`; handle browser cookies explicitly | | `cy.session(...)` | Explicit auth bootstrap with `authLoad`/`authSave`, a live login module, or a configured cached auth module | | `Cypress.Commands.add(...)` | A [module](/docs/core-concepts/modules) for reusable test steps | | `cy.viewport(...)` | Test `viewport` for initial size; no preset step to resize mid-test | | `it.skip` / `it.only` | `disabled: true` skips a test; pass a test path or `--labels` to select tests | | `cypress.config.ts` `baseUrl` | `environments[].baseUrl`, selected with `--env` or `defaultEnv` | | `Cypress.env(...)` | `env.` variables from `environments[].envVariables` | | Retry-ability of queries/assertions | Use the matching preset check and timeout; preserve the condition rather than the command queue | | Test retries | Test/config `retries` or `--retries` reruns the whole test; step `retries` repeats only that step | | `cy.origin(...)` | Browser steps can navigate across origins; callback code and storage assumptions still need adaptation | ## Fixture and plugin mapping | Cypress | Momentic | | - | - | | `cypress/fixtures/*.json` | Keep the payload. Read it with `child_process` in a Node `javascript` step and `setVariable`/`saveAs`, or inline it in a mock. Files must exist on the runner; check the working directory. | | `cypress/support/commands.js` | Port reusable browser actions into modules. Parameters become module `parameters`; calls use `module` with `inputs`. Commands that call modules need restructuring: modules cannot call other modules. | | `cypress.config.ts` plugins / `task()` | Port calls into the documented [JavaScript globals](/docs/integrations/javascript), or keep plugin-dependent helpers in a script before the CLI run. | | `e2e` folder structure | Keep directories; configure `include` globs to discover the new `*.test.yaml` and `*.module.yaml` files. | | Component testing | Keep Cypress or another component runner. Momentic tests the running app end to end. | ## Session and fixture scope [`cy.session`](https://docs.cypress.io/api/commands/session) caches browser state by an ID and can validate a restored session before rerunning login. A live login module in Momentic's `before` runs on each whole-test attempt. For reuse, configure a [cached auth module](/docs/guides/auth/cached-session) with an explicit cache key and expiry; this does not port Cypress's session callback or validation function. `authLoad` restores state without testing whether a server-side session is still valid. Add an authenticated-page or API check, and regenerate expired state in your bootstrap. Port a login helper's API call with `request` or Node `javascript`. Browser cookies are not established merely by calling `fetch` in Node: use `extractCookiesFromResponse`, then `authLoad` with the resulting state, or authenticate through the browser. See [cookie extraction](/docs/integrations/javascript#extractcookiesfromresponse-response) and [saved state](/docs/guides/auth/overview). Cypress's internal session cache is not a Playwright storage-state JSON file you can give to `authLoad`. Momentic initializes a browser for each whole-test attempt. Tests that rely on Cypress [`testIsolation: false`](https://docs.cypress.io/app/core-concepts/test-isolation) need explicit per-test setup or one combined flow. Browser isolation does not reset shared database records. Use unique accounts or records before enabling parallel runs. Map `beforeEach` and `afterEach` to `before` and `after`. Keep suite-level `before`/`after` scripts outside the test unless repeating them per attempt is intentional. Momentic teardown runs after setup or main-step failures and can itself fail the test; initial navigation failure or process interruption can prevent cleanup. Make cleanup idempotent and retain an external cleanup path. Separate Cypress [whole-test retries](https://docs.cypress.io/app/guides/test-retries) from query retry behavior. Preset conditions can wait; step retries repeat the step and may repeat side effects. Use checks or JavaScript that throws for exact response values, counts, and text. Returning a value from JavaScript alone does not assert it. Review AI assertions against the original expected state rather than replacing them with a broad page-success check. Carry forward CSS constraints, text matching rules, and scope from `cy.get`/`cy.contains`; keep an explicit CSS target when a description cannot preserve them. ## What does not map * There is no `cy` object or command queue. Port `cy.wrap` subjects into values passed through `saveAs`/`env`, and rewrite custom queue manipulation; a JavaScript step cannot execute a Cypress command chain. * There is no preset equivalent of `cy.spy`/`cy.stub`. `mock` covers network interception; browser `javascript` can inspect the current page. It is not a drop-in replacement for stubs installed before app initialization. * `cypress-real-events` and raw Chrome DevTools Protocol calls have no direct equivalent. Keep tests that require those behaviors in their existing runner. * Cypress's time-travel snapshots UI has no scrubbable equivalent. Momentic's editor and run viewer expose screenshots, logs, and available recordings. Compare the evidence you rely on before retiring the original job. * Keep Firefox/WebKit runs and component-test jobs in their existing runner. Momentic's web browser targets are Chromium-based; `--env` does not change that support boundary. ## Incremental strategy 1. Keep Cypress and its CI gate. Follow [web setup](/docs/quickstart/web) to add Momentic, preserving existing config. Commit the dependency lockfile and confirm the config includes your new test/module directories. 2. Inventory each flow's login helper, session validation, fixtures, intercepts, assertions, plugin tasks, and cleanup. Port authentication first and run it independently. Test both fresh login and expired saved state. 3. Port one critical flow and label it `migrated`. Lint it and run it alone with `--parallel 1 --retries 0`. In a test environment, confirm a deliberate response or assertion mismatch fails the replacement, then restore it. 4. Run a separate Momentic CI job with its own output directory and test data. Keep Cypress required while comparing the same critical paths. Preserve the request wait and response checks from every intercept; review any recovery, classification, or quarantine before accepting a passing result. 5. Switch the gate one flow at a time after repeated passes and a reviewed expected failure. Preserve the Cypress specs and CI config in Git so you can restore the old gate. Remove Cypress only after its remaining plugin, browser, and component coverage has a replacement. Inspect the selected paths before running the overlap job: ```bash theme={null} npx momentic lint npx momentic list --labels migrated npx momentic run --labels migrated --parallel 1 --retries 0 --ignore-quarantine --output-dir ./momentic-migration-results --upload-results --reporter junit npx momentic results check ./momentic-migration-results ``` By default, `results check` rejects non-quarantined runs that failed, were cancelled, recovered, or had a failure classification. It ignores quarantined runs and accepts an archive with zero tests. The recipe uses `--ignore-quarantine` so quarantine does not mask the selected tests' statuses; confirm the list and run totals contain the enabled tests you intend to port. `--filter` selects a workspace project, not a Cypress spec. See [results checks](/docs/cli-reference/momentic/commands/results#check) and [GitHub Actions](/docs/running-tests/ci/github-actions) for CI setup. ## Porting at scale with a coding agent Point your coding agent at the spec files and the [`momentic-test` skill](/docs/coding-agents/skills). Use a prompt that names the behavior to preserve: ```text theme={null} Port cypress/e2e/checkout.cy.js to Momentic tests under tests/checkout/. Read the momentic-test skill first. Convert each it() to a *.test.yaml, each custom command to a *.module.yaml under tests/modules/, and stubbed cy.intercept calls to mock steps. Use registerRequestListener and awaitListener for spy-only intercepts and alias waits. Reuse cypress/fixtures JSON payloads, loading or inlining them explicitly. Run each ported test with npx momentic run . ``` ## Related * [Test portability](/docs/get-started/test-portability) * [Web steps reference](/docs/reference/commands/index) * [Modules](/docs/core-concepts/modules) * [Mock network routes](/docs/reference/commands/mock) # From Maestro Source: https://momentic.ai/docs/guides/migrate/from-maestro Port Maestro flows to momentic-mobile, including flows, subflows, scripts, and environment variables. Translate Maestro flows into `momentic-mobile` tests while preserving the behavior each flow checks. Both use YAML, but launch behavior, selectors, variables, subflows, and assertions need review rather than a key rename. ## Prepare the project Complete the [iOS](/docs/quickstart/ios) or [Android](/docs/quickstart/android) setup and keep your Maestro files and CI job. Momentic uses a separate CLI and `momentic.config.yaml`; it does not execute Maestro flow files. * Android needs an APK, `adb`, and `ANDROID_HOME` or `ANDROID_SDK_ROOT`, even for remote emulators. Local emulators also need an installed AVD. See [Android app setup](/docs/platforms/android/app-setup). * iOS needs a simulator `.app` build, not a device `.ipa`. Local simulators require macOS, Xcode, and idb. Remote simulators use an uploaded build. See [iOS app setup](/docs/platforms/ios/app-setup). * Momentic supports emulators and simulators, not physical devices. Keep Maestro coverage that requires device hardware or an unsupported OS version. * Record the selected flow's build, initial app state, permissions, test data, assertions, and hooks. Use the same conditions when comparing results. ## Before and after A representative Maestro flow: ```yaml checkout.yaml theme={null} appId: com.example.shop env: EMAIL: jeff@example.com --- - launchApp - tapOn: "Add to cart" - tapOn: id: "cart-icon" - assertVisible: "Gravity Blanket" - tapOn: "Checkout" - tapOn: "Email" - inputText: ${EMAIL} - tapOn: "Place order" - assertVisible: "Order confirmed" ``` The Android version force-stops the named package before opening it and keeps the expected text in its visibility checks: ```yaml checkout.test.yaml theme={null} fileType: momentic/mobile-test/v2 id: guest-checkout description: Complete guest checkout and verify confirmation platform: android defaultEnv: staging steps: - adb: command: shell args: '["am", "force-stop", "com.example.shop"]' - openApp: com.example.shop - tap: the Add to cart button - tap: the cart icon - checkElementVisible: the text 'Gravity Blanket' in the cart - tap: Checkout - type: text: "{{ env.EMAIL }}" into: the Email field clearContent: false - tap: Place order - checkElementVisible: the text 'Order confirmed' ``` Replace the package ID and targets with your app's values. The example assumes the app's starting state has an empty cart and a guest checkout flow. Add `EMAIL` to the existing `staging` environment in `momentic.config.yaml`. Do not replace other environments or settings: ```yaml momentic.config.yaml theme={null} environments: - name: staging envVariables: EMAIL: jeff@example.com ``` `defaultEnv: staging` selects that environment. A shell variable only becomes available through an explicit variable reference or `inheritFromShell: true`; shell inheritance defaults to `false`. Put secrets in an ignored environment file or your CI secret store. See [environment variables](/docs/configuration/environment-variables). For remote Android execution, upload the APK to a channel and pin the build tag when running the file: ```bash theme={null} npx momentic-mobile assets upload ./build/app.apk --channel staging --tag migration-1 npx momentic-mobile lint mobile-tests/checkout.test.yaml npx momentic-mobile run mobile-tests/checkout.test.yaml \ --channel staging --tag migration-1 --upload-results ``` Save the example as `mobile-tests/checkout.test.yaml` under the project's configured `include` paths, and replace the APK path with your build. Without a channel or an explicit installation step, `openApp` assumes the app is already installed. For local execution, pass an AVD and APK, or an iOS simulator type and `.app` path. See [mobile run options](/docs/cli-reference/momentic-mobile/commands/run). ## Command mapping | Maestro | Momentic | | - | - | | `appId: com.x` + `launchApp` | Restart the intended app, then `openApp: com.x`. Use the named-package Android restart above; translate reset options separately. | | `killApp` / `stopApp` | `killApp` stops the foreground app. Translate stops that target a different package separately. | | `tapOn: ` / `tapOn: {id:}` | `tap: `; prefer visible text over test IDs | | `tapOn: {point: "x%,y%"}` | `tap: "50%, 50%"` percent-pair target | | `longPressOn` | `tap: { on: ..., longPress: true }` | | `doubleTapOn` | `tap: { on: ..., iterations: 2 }` | | `inputText` / `inputRandomText` | `type: { text: ..., into: }`; use `faker` in `javascript` for random data | | `eraseText` | `type: { text: "", into: , clearContent: true }`; check the resulting value | | `assertVisible` / `assertNotVisible` | `checkElementVisible` / `checkElementNotVisible` for element visibility; preserve selector constraints | | `assertTrue` | `javascript` step with `assert` | | `scroll` / `swipe` | `swipe` for a gesture; `scrollTo` to reach a named target | | `scrollUntilVisible` | `scrollTo: { on: , in: }` | | `back` / `pressKey` | `press` / `pressKey` | | `runFlow: path` | `module: ./path.module.yaml` with `inputs`; flatten nested subflow calls because modules cannot call modules | | `runScript` | `javascript` step (Node sandbox) or `appium` step for `mobile:` calls | | `evalScript` | `javascript` step | | `setLocation` | Use an `appium` script supported by the target platform; `toggleSettings: location` toggles Android location services, not coordinates | | `setAirplaneMode` / `toggleAirplaneMode` | `toggleSettings: airplane_mode` on Android toggles the setting; explicitly setting a known value needs a state check | | `openLink` / deep links | `appium` step (`mobile: deepLink` with `url`) | | `startRecording` / `stopRecording` | `--video true` or `recordVideo: true` records the test run; custom start/stop boundaries do not transfer | | `waitForAnimationToEnd` | Review whether auto-waiting covers the transition; retain a readiness condition when an animation or asynchronous operation matters | | `extendedWaitUntil` | any condition step with `timeout:` | | `takeScreenshot` | automatic per-step screenshots; `assertVisually` for visual checks | | `retry` | `retries` on the step payload or test; preserve the retried sequence and make its side effects safe to repeat | | `when:` conditions | `if:` with nested `then:` steps | | `repeat` / `while` | `while:` with `do:` and a condition or `maxIterations` | | `env:` block + `${VAR}` | `envVariables` in config, `{{ env.VAR }}` in strings, `env.VAR` in JS | | `labels:` | `labels:` (same name) | | `onFlowStart` / `onFlowComplete` hooks | `before:` / `after:` sections | ## Preserve selectors, checks, and waits Maestro's [text and ID selectors](https://docs.maestro.dev/maestro-flows/flow-control-and-logic/how-to-use-selectors) use regular expressions. Momentic target descriptions are natural language, not regular expressions or Maestro selector objects. Translate the intended target, including any parent, position, index, or state constraint. Do not paste an ID regex into `tap` and assume it keeps the original match. Use [element visibility checks](/docs/reference/mobile-commands/check-element) for visible or hidden elements. Use [element content checks](/docs/reference/mobile-commands/check-element-content) for exact text. `checkScreenContains` searches the screen hierarchy or WebView content and can match offscreen content; it does not replace `assertVisible`. Use [AI assertions](/docs/reference/mobile-commands/assert) when the intended check is semantic, and review whether that changes the original contract. Preserve `extendedWaitUntil` timeouts on a condition step in milliseconds. For example, wait up to 30 seconds for the confirmation to become visible: ```yaml theme={null} - checkElementVisible: on: the text 'Order confirmed' timeout: 30000 ``` Auto-waiting handles target readiness, but it does not establish that a background save or network request has finished. Keep those checks explicit. Retries rerun actions; timeouts wait for a condition. Do not replace a wait with a retry when repeating the action creates duplicate data. ## Subflows, variables, and hooks Extract a reusable sequence into a mobile module. Map `runFlow.env` values to module inputs instead of putting every flow's variables in the global project environment. Keep defaults local to the module, and use `setVariable` or `saveAs` for values created during a test. See [module parameters](/docs/core-concepts/modules#parameters) and [variable scope](/docs/core-concepts/variables#scope). This module takes one input and has no nested module calls: ```yaml modules/enter-email.module.yaml theme={null} fileType: momentic/mobile-module/v2 id: migrated-enter-email name: Enter email platform: android parameters: parameterNames: [EMAIL] steps: - type: text: "{{ env.EMAIL }}" into: the Email field clearContent: false ``` Replace the inline email-entry step in the checkout test with this invocation: ```yaml theme={null} - module: path: ../modules/enter-email.module.yaml inputs: EMAIL: env.EMAIL ``` `env.EMAIL` is an expression; use `{ string: "jeff@example.com" }` to pass a literal. Flatten nested `runFlow` calls into the module's steps, or invoke each module from the test. A module cannot call another module. Module paths are relative to the calling file, so `mobile-tests/checkout.test.yaml` uses `../modules/enter-email.module.yaml` for the module shown above. Translate `when` conditions to an assertion-based `if` where possible. Split platform-specific behavior into iOS and Android tests or modules; the mobile `if` condition is not a Maestro `platform` selector. Check loop bounds and retry boundaries rather than renaming `repeat` or `retry` mechanically. Move each top-level flow's `onFlowStart` and `onFlowComplete` behavior into `before` and `after`. Modules do not have Maestro flow hooks. Inline a subflow's setup at its original call site. Put cleanup that must survive a subflow failure in the test's `after`, and check that its ordering and scope still match the original flow. A failed `before` skips the main steps; `after` still runs, so cleanup must tolerate incomplete setup. Running one step in the editor skips test hooks. Validate them with a whole-test run. See [before and after sections](/docs/core-concepts/file-format#before-and-after-sections). Check [Maestro launch options](https://docs.maestro.dev/reference/commands-available/launchapp) separately. Its default `launchApp` restarts the app, and options can clear app data or the iOS keychain and set permissions. Momentic's `killApp` stops the current foreground app. Use it before `openApp` only when the intended app is already in the foreground; it does not target the identifier passed to a later `openApp`. The Android example uses `shell am force-stop` to stop that package regardless of which app is active. Neither method clears app data. To reset app data on Android, use an [`adb`](/docs/reference/mobile-commands/adb) step: ```yaml theme={null} - adb: command: shell args: '["pm", "clear", "com.example.shop"]' ``` Preserve iOS keychain, permissions, and other reset behavior using a verified setup method, or retain the Maestro test until you have one. Use independent backend records for each test and clean up only the records it created. A new emulator session does not clear your application's backend. ## What does not map * Momentic has no separate inspector app like Maestro Studio: the local editor's element picker plus `debugState` cover element inspection. * Maestro `runScript` and `evalScript` code needs adaptation. Momentic's `javascript` step runs in a Node sandbox with its own globals; Maestro's `output` object and UI commands do not become Momentic APIs. Use `env`, `setVariable`, and `saveAs` for data, and preset or AI steps for UI actions. * Physical devices are not supported: remote execution is emulators and simulators only. * Maestro's tolerance and optional-element flags have no equivalent: Momentic resolves target descriptions rather than Maestro selector flags. For an optional action, use an `if` step with an element check and nested `then` steps. Mobile `if` has no `else` branch. See [mobile conditionals](/docs/reference/mobile-commands/if). * A `maestro cloud` command and its workspace configuration do not transfer to Momentic. Configure build upload, test selection, parallelism, reporting, and scheduling explicitly in your CI provider. ## Incremental strategy 1. Port one bounded flow end to end, including its hooks, subflows, inputs, waits, and cleanup. Start with a flow whose repeated locator failures you can compare. Keep Maestro installed and preserve the `.maestro` directory. 2. Lint and run the file on the intended target. Compare both runners on the same build and starting state. Inspect screenshots at assertions, including a case where the expected outcome is absent. 3. Separate environment values from module parameters. Pin the app build tag and check the OS version, permissions, and reset behavior before comparing stability. 4. Add a separate Momentic CI job with its own test data. Do not run both runners concurrently on the same local emulator. Remote Momentic tests use independent emulator sessions; local Android parallel tests need distinct AVDs, and local iOS runs should use `--parallel 1`. 5. Replace gates flow by flow after reviewing equivalent coverage and repeated results. Retain legacy flows for hardware, OS, selectors, or reset behavior you have not migrated. Remove their CI jobs and files only after that coverage is accounted for. In CI, install `momentic-mobile` from the lockfile, set `MOMENTIC_API_KEY` from the CI secret store, and provide the platform prerequisites. Upload the build with a unique tag, then use that same tag when running tests. Add `--reporter junit` to generate reports under `./reports`, and preserve the run command's exit status as the job result. See [GitHub Actions](/docs/running-tests/ci/github-actions) or the [other CI guides](/docs/guides). ## Porting at scale with a coding agent Paste this prompt into your coding agent after installing Momentic and providing the app build: ```text theme={null} Port every flow under .maestro/ to momentic-mobile tests under mobile-tests/. Read the momentic-mobile-test skill first. Convert runFlow targets to *.module.yaml files, keep the directory structure, move shared env: values into environments[].envVariables, preserve flow-local values with setVariable, pass runFlow.env as module inputs, and run each ported test with npx momentic-mobile run on an emulator. ``` ## Related * [Test portability](/docs/get-started/test-portability) * [Mobile steps reference](/docs/reference/mobile-commands/index) * [Emulators and simulators](/docs/running-tests/hosted-test-environments) * [Modules](/docs/core-concepts/modules) # From Playwright Source: https://momentic.ai/docs/guides/migrate/from-playwright Port a Playwright suite to Momentic, including page objects, fixtures, storage state, network mocks, and reporters. Move one Playwright flow at a time, preserving its setup, actions, assertions, and cleanup. Momentic tests are YAML files with natural-language or CSS targets. Use a coding agent with the [MCP server](/docs/coding-agents/mcp-server) and [coding agent skills](/docs/coding-agents/skills) to draft the files, then review them against the source spec before changing your CI gate. ## Before and after This example assumes a test shop, an empty cart, and a fresh authenticated state file generated by your existing Playwright setup. Both tests create an order; use a test account and isolate or reset its server-side data between runs. ```ts checkout.spec.ts theme={null} import { expect, test } from "@playwright/test"; test.use({ storageState: "playwright/.auth/user.json" }); test.describe("checkout", () => { test.beforeEach(async ({ page }) => { await page.goto("https://shop.example.com/products/42"); }); test("signed-in shopper can buy a blanket", async ({ page }) => { await page.getByRole("button", { name: "Add to cart" }).click(); await page.getByTestId("cart-icon").click(); await expect(page.getByText("Gravity Blanket")).toBeVisible(); await page.getByRole("button", { name: "Checkout" }).click(); await page.getByLabel("Email").fill("jeff@example.com"); await page.getByRole("button", { name: "Place order" }).click(); await expect(page).toHaveURL(/^https:\/\/shop\.example\.com\/orders\/\w+/); await expect(page.getByText("Order confirmed")).toBeVisible(); }); }); ``` The same user-flow checks in Momentic. This file sits at the repository root, so the auth path resolves to `playwright/.auth/user.json`: ```yaml checkout.test.yaml theme={null} fileType: momentic/test/v2 id: signed-in-checkout url: https://shop.example.com/products/42 labels: [checkout] before: - authLoad: ./playwright/.auth/user.json - navigate: https://shop.example.com/products/42 steps: - click: Add to cart - click: the cart icon - checkElementVisible: the text "Gravity Blanket" - click: Checkout - fill: text: jeff@example.com into: the Email field - click: Place order - waitForUrl: regex: ^https://shop\.example\.com/orders/\w+ - checkElementVisible: the text "Order confirmed" ``` Lint and run the new file alone. Start with whole-test retries disabled so a second attempt does not hide a setup or assertion mismatch: ```bash theme={null} npx momentic lint checkout.test.yaml npx momentic run checkout.test.yaml --parallel 1 --retries 0 --upload-results ``` `authLoad` refreshes the current page after restoring state. The following `navigate` makes the starting page explicit if unauthenticated navigation redirected to login. If you move the YAML under `tests/`, adjust the auth path relative to that file. YAML `regex` values are pattern strings, without JavaScript's surrounding `/.../` delimiters. ## API mapping | Playwright | Momentic | | - | - | | `page.goto(url)` | `navigate: ` | | `getByRole/getByText/getByTestId` + `.click()` | `click: ` or `click: { css: "..." }` | | `.fill(value)` / `.pressSequentially(value)` | `fill` replaces a value; `type` emits keystrokes. Set `clear: never` to append. | | `.press("Enter")` | `press: Enter` | | `.hover()` / `.dblclick()` | `hover` / `doubleClick` | | `selectOption` | `select` step, `click` the option, or an `act` goal for styled dropdowns | | `expect(locator).toBeVisible()` | `checkElementVisible: ` or `assert:` for semantic checks | | `expect(page).toHaveURL()` | `waitForUrl: { substring/glob/regex }` | | `expect(page).toHaveTitle()` | Browser `javascript` that checks `document.title` and throws on a mismatch | | `waitForSelector` / `waitFor` | `checkElementVisible` with `timeout`; use `wait: ` only for a fixed delay | | `page.route()` interception | [`mock`](/docs/reference/commands/mock) with `substring`/`glob`/`regex`/`method` | | `page.waitForRequest`/`waitForResponse` | `registerRequestListener` + `awaitListener` (captures request and response) | | `request`/`response` event log | `recordRequests` + `getRecordedRequests` | | `page.on('dialog')` | `dialog: ACCEPT` or `DISMISS`, placed before the step that raises it | | `page.screenshot()` | automatic per-step screenshots; video needs `recordVideo` in the config | | `context.addCookies()` | `cookie` for individual cookies, or `authLoad` for a storage-state object | | `localStorage` read/write | `localStorage` step writes a key; browser `javascript` for reads or clears | | `context.setExtraHTTPHeaders` | `header` step or `--custom-headers` on the CLI | | `context.setOffline()` | `offline` / `online` steps | | `storageState` / `context.storageState()` | `authLoad: ` imports cookies and local storage; verify other storage separately | | `page.evaluate()` | `javascript` step with `environment: browser` | | Screenshot comparisons | `assertVisually` / `visualDiff`; compare baselines rather than copying them | | `page.waitForLoadState` | steps wait for their targets; keep explicit waits for other readiness conditions | ## Fixture and helper mapping | Playwright construct | Momentic | | - | - | | `test.beforeEach` | `before:` steps on the test | | `test.afterEach` | `after:` steps (run even when main steps fail) | | `test.beforeAll` / worker fixtures | Keep shared setup in a CI script; an ordinary module in `before` runs per test attempt | | Custom fixtures / page object | [Modules](/docs/core-concepts/modules) reuse browser steps; preserve fixture scope and teardown separately | | `test.describe` grouping | Directory layout plus `labels:` | | `test.only` / `test.skip` | Pass a test path or `--labels` to select tests; `disabled: true` skips a test | | `use.baseURL` | `environments[].baseUrl` in `momentic.config.yaml` | | `projects:` matrix | `--env` for deployments; browser/viewport settings and separate CI jobs for supported variants | | `retries` config | Test/config `retries` or `--retries` reruns the whole test; step `retries` has narrower scope | | `test.use({ viewport })` | top-level test `viewport`, such as `{ width: 1280, height: 720 }` | | Reporters (`html`, `junit`) | Local report/dashboard plus `--reporter junit`, `json`, `allure`, or `playwright-json` | ## What keeps working unchanged * `authLoad` imports cookies and local storage from Playwright storage-state JSON. Keep your [auth bootstrap](https://playwright.dev/docs/auth) running before the Momentic job and regenerate expired state. Keep state files out of Git. Playwright's per-origin IndexedDB snapshot fields are not imported; validate any auth that depends on them separately. * A Node `javascript` step provides `fetch`, `faker`, and the documented [JavaScript globals](/docs/integrations/javascript). Port seed endpoint calls into those steps. Existing helpers with imports or fixture dependencies need adaptation; you can keep them in a separate script before the CLI run. * Momentic installs and runs in the same GitHub Actions job; see [Run in CI](/docs/running-tests/ci/github-actions). * `--reporter junit` emits JUnit XML. Check the suite names, test names, and artifact paths expected by your existing analytics. ## Preserve isolation and failure behavior Momentic initializes a browser for each whole-test attempt. Put per-test setup in `before` and cleanup in `after`; teardown runs after setup or main-step failures, and a teardown failure fails the run. It cannot clean up a run that never reached setup, such as an initial navigation failure. Keep cleanup idempotent and use a separate cleanup job for shared server-side resources. Playwright [worker fixtures](https://playwright.dev/docs/test-fixtures#worker-scoped-fixtures) and `beforeAll` are not equivalent to a Momentic module. Moving their contents into `before` repeats them on each test attempt. Keep shared services and seed data outside the test, or make per-test setup safe to repeat. Use separate accounts or unique records for concurrent tests that mutate server state. Preserve exact checks for URL, text, counts, and response fields. Use preset checks or JavaScript that throws when the condition fails; returning a value alone is not an assertion. Review any replacement AI assertion against the original expected state. Carry forward the role, accessible name, text matching rules, and scope of `getByRole`/`getByText`. Keep an explicit CSS target when a description cannot preserve those constraints. A visibility check does not replace an assertion about how many elements match. Compare [whole-test retries](https://playwright.dev/docs/test-retries), step retries, and [failure recovery](/docs/reliability/auto-maintenance#failure-recovery) separately; passing after recovery does not establish first-attempt parity. ## What does not map * Momentic re-resolves a target from its description each run (with a [step cache](/docs/reliability/step-cache) to skip the model call when the page has not changed). Element handles and locator chains do not port: express the intent in the target text instead. * Firefox and WebKit projects have no equivalent browser target. Momentic web tests support Chromium-based browsers. Keep those existing browser jobs; `--env` selects deployment variables, not a browser engine or a project dependency graph. * Momentic manages the browser context, so `browserContext` control does not port. `newTab`, `closeTab`, and `navigate` cover tab workflows, but you do not create isolated contexts mid-test. Use separate tests or `authLoad` per test for different identities. * Custom `page.on("console")` event handlers do not port. Replace assertions that depend on them with explicit observable checks, or retain that coverage in Playwright. * The local editor and AI authoring cover what Codegen records; there is no recorder that emits Playwright-API code to copy back. ## Incremental strategy 1. Keep Playwright and its CI gate. Use the [web setup](/docs/quickstart/web) to add Momentic, preserving an existing `momentic.config.yaml`. Commit the dependency lockfile and include globs that discover the new test files. 2. Record each flow's fixtures, test account, mocks, expected outcomes, browser variants, and cleanup. Port one critical flow and label it `migrated`. 3. Lint it, then run it alone with `--parallel 1 --retries 0`. Confirm its assertions fail for a deliberate mismatch in your test environment, then restore the expected state. Review screenshots and any recovery or classification before accepting parity. 4. Add a separate Momentic CI job with its own output directory and test data. Keep the Playwright job required while you compare results. Generate the auth file before the new job and make it available at the path the YAML expects. `--filter` selects a workspace project; it does not select a spec. 5. Switch the gate flow by flow after repeated passes and a reviewed expected failure. Preserve the original specs and CI configuration in Git so you can restore the previous gate. Remove Playwright only after its remaining browser, fixture, and reporter coverage has a replacement. Inspect the selected paths before running the overlap job: ```bash theme={null} npx momentic lint npx momentic list --labels migrated npx momentic run --labels migrated --parallel 1 --retries 0 --ignore-quarantine --output-dir ./momentic-migration-results --upload-results --reporter junit npx momentic results check ./momentic-migration-results ``` By default, `results check` rejects non-quarantined runs that failed, were cancelled, recovered, or had a failure classification. It ignores quarantined runs and accepts an archive with zero tests. The recipe uses `--ignore-quarantine` so quarantine does not mask the selected tests' statuses; confirm the list and run totals contain the enabled tests you intend to port. See [results checks](/docs/cli-reference/momentic/commands/results#check) and [GitHub Actions](/docs/running-tests/ci/github-actions) for CI setup. ## Porting at scale with a coding agent Point your coding agent at the spec files and the [`momentic-test` skill](/docs/coding-agents/skills). A prompt that works well: ```text theme={null} Port the Playwright specs in e2e/checkout.spec.ts to Momentic tests. Read the momentic-test skill first. Write one *.test.yaml per Playwright test() under tests/, keep the describe names as directory structure, reuse playwright/.auth/user.json via authLoad, and run each new test with npx momentic run before moving on. ``` Review the generated targets and assertions against the source spec, lint the YAML, and run each ported flow before replacing its existing CI gate. ## Related * [Test portability](/docs/get-started/test-portability) * [Web steps reference](/docs/reference/commands/index) * [JavaScript integration](/docs/integrations/javascript) * [Authentication guides](/docs/guides/auth/overview) # From Selenium and Appium Source: https://momentic.ai/docs/guides/migrate/from-selenium-appium Port WebDriver and Appium suites to Momentic, including page objects, explicit waits, capabilities, and driver escapes. Port the user flows from your Selenium or Appium suite into `*.test.yaml` files. Move reusable page-object behavior into modules, configure browser or device settings in `momentic.config.yaml`, and retain explicit readiness checks where the app requires them. This is a manual translation of the test contract, not an import of WebDriver code or capabilities. ## Prepare the project * Complete the [web](/docs/quickstart/web), [iOS](/docs/quickstart/ios), or [Android](/docs/quickstart/android) setup for the target you are migrating. Keep your existing runner and CI job while you verify the new tests. * Web tests run on Chromium, Google Chrome, or Chrome for Testing. Keep Selenium coverage for Firefox, Safari, or other required browser targets. * Mobile tests need an Android APK or an iOS simulator `.app` build. A device-signed `.ipa` is not a simulator build. Momentic supports emulators and simulators, not physical devices. Android runs require `adb` and an SDK path even when using remote emulators; local iOS runs require macOS, Xcode, and idb. See [Android app setup](/docs/platforms/android/app-setup) and [iOS app setup](/docs/platforms/ios/app-setup). * Pick one test and record its starting state, inputs, expected results, and cleanup. Include setup hidden in base classes, fixtures, and page-object constructors. Use the same app build and test data when comparing runners. ## Before and after A representative Selenium test (Java/TestNG, but the shape is the same in Python or JavaScript): ```java CheckoutTest.java theme={null} @Test public void guestCanBuyBlanket() { WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10)); driver.get("https://shop.example.com/products/42"); wait.until(ExpectedConditions.elementToBeClickable( By.cssSelector("[data-testid='add-to-cart']"))).click(); driver.findElement(By.id("cart-icon")).click(); wait.until(ExpectedConditions.textToBePresentInElementLocated( By.cssSelector(".cart-items"), "Gravity Blanket")); driver.findElement(By.xpath("//button[contains(.,'Checkout')]")).click(); WebElement email = wait.until(ExpectedConditions.visibilityOfElementLocated( By.name("email"))); email.sendKeys("jeff@example.com"); driver.findElement(By.cssSelector("button[type='submit']")).click(); wait.until(ExpectedConditions.urlMatches("/orders/\\w+")); Assert.assertTrue( driver.findElement(By.tagName("body")).getText().contains("Order confirmed")); } ``` The Momentic version keeps the CSS targets and URL pattern. Browser JavaScript checks rendered text, and the Checkout button uses a natural-language target: ```yaml checkout.test.yaml theme={null} fileType: momentic/test/v2 id: guest-checkout url: https://shop.example.com/products/42 steps: - checkElementVisible: css: "[data-testid='add-to-cart']" timeout: 10000 - checkElementEnabled: css: "[data-testid='add-to-cart']" timeout: 10000 - click: css: "[data-testid='add-to-cart']" - click: css: "#cart-icon" - javascript: environment: browser code: | const deadline = Date.now() + 10000; while (Date.now() < deadline) { const cart = document.querySelector(".cart-items"); if (cart instanceof HTMLElement && cart.innerText.includes("Gravity Blanket")) return; await new Promise(resolve => setTimeout(resolve, 200)); } throw new Error("Cart does not show Gravity Blanket"); timeout: 15000 - click: Checkout - checkElementVisible: css: "[name='email']" timeout: 10000 - type: text: jeff@example.com css: "[name='email']" clear: never - click: css: "button[type='submit']" - waitForUrl: regex: /orders/\w+ timeout: 10000 - javascript: environment: browser code: | if (!document.body.innerText.includes("Order confirmed")) { throw new Error("Order confirmation is not visible"); } ``` Web interaction steps wait for their target using the browser's smart-waiting setting. Condition steps accept their own `timeout`. Preserve explicit waits when a transition can outlast the interaction's default: the checks above wait for visibility and enabled state before clicking. Each check has its own deadline. A Selenium `Duration.ofSeconds(10)` becomes `timeout: 10000`, not `timeout: 10`. See [auto-waiting](/docs/core-concepts/finding-elements#auto-waiting). Keep readiness checks for conditions that finding a target does not establish, such as a completed background save. The JavaScript loop above preserves the cart's rendered-text wait; its step timeout allows the polling loop to finish. An AI `assert` checks meaning; it does not preserve a literal text equality or substring assertion. Web [element content checks](/docs/reference/commands/check-element-content) compare DOM `textContent`, which can include hidden text. Selenium `getText()` reads rendered text. Use a browser JavaScript check, as above, when that distinction affects coverage; review whitespace and visibility behavior for your app. ### Appium example An Appium Java test might enter an email, continue, and compare the welcome message exactly: ```java theme={null} driver.activateApp("com.example.shop"); driver.findElement(AppiumBy.accessibilityId("Email")).sendKeys("jeff@example.com"); driver.findElement(AppiumBy.accessibilityId("Continue")).click(); Assert.assertEquals( driver.findElement(AppiumBy.accessibilityId("welcome-message")).getText(), "Welcome back"); ``` In Momentic, describe the intended controls and retain the exact text check. Install the same APK through the run command's build options before this test runs: ```yaml mobile-tests/welcome.test.yaml theme={null} fileType: momentic/mobile-test/v2 id: migrated-welcome description: Enter an email and verify the welcome message platform: android steps: - openApp: com.example.shop - type: text: jeff@example.com into: the Email field clearContent: false - tap: Continue - checkElementContentEquals: on: the welcome message value: Welcome back ``` The accessibility ID is no longer a selector object. Confirm that the description identifies the same element, especially when multiple controls have the same text. Keep the original wait and reset behavior if the test's fixtures add it outside this excerpt. ## API mapping | Selenium / WebDriver | Momentic | | - | - | | `driver.get(url)` | `navigate: ` or the test's top-level `url` | | `findElement(By.*)` + `click()` | `click: ` or `click: { css: "..." }` | | `sendKeys(value)` | `type: { text: ..., into: }` | | `WebDriverWait` + `ExpectedConditions.*` | the step's own waiting, or `assert`/`checkElement*` with `timeout` | | `Thread.sleep(ms)` | `wait: ` (prefer a condition) | | `Assert.assertEquals` etc. | `checkElementContentEquals` compares DOM text; browser JavaScript checks rendered text; Node JavaScript has `assert` for values | | `Actions` chains (hover, drag) | `hover`, `dragAndDrop`, `mouseDrag` | | `driver.navigate().back()` / `forward()` | `goBack` / `goForward` | | Open or close a tab | `newTab` opens a URL and switches to it; `closeTab` closes an active or matching tab. Rewrite window-handle logic separately. | | `switchTo().alert().accept()`/dismiss | `dialog: ACCEPT` or `DISMISS`, placed before the step that raises it | | `driver.manage().cookies()` | `cookie` step; `localStorage` step for storage | | `JavascriptExecutor` | `javascript` step with `environment: browser` | | Screenshots on failure | automatic per-step screenshots; video needs `recordVideo` | | `DesiredCapabilities` / `ChromeOptions` | Map supported settings to `browser` and `environments` in `momentic.config.yaml`; capability objects are not accepted. | | Selenium Grid / BrowserStack / Sauce | Hosted browsers use `browser.remoteBrowser: true`; provider-specific capabilities and device matrices do not carry over. | | JUnit/TestNG/pytest reports | `--reporter junit` | | Appium | Momentic (`momentic-mobile`) | | - | - | | `driver.activateApp(bundleId)` | `openApp: ` | | `driver.terminateApp` | `killApp` | | `findElement` + `click()` | `tap: ` | | `sendKeys` | `type: { text: ..., into: }` | | `TouchAction` / W3C gestures | `swipe`, `dragAndDrop`, `scrollTo` | | `driver.pressKey` | `press` / `pressKey` | | `driver.execute("mobile: ...")` | `appium` with `script` and JSON-string `args`; verify the command on the target platform | | `adb` shell commands | `adb` step (Android only) | | Desired/app capabilities (`platformName`, ...) | `platform:` on the test plus `momentic.config.yaml` | | Local emulator/device farm | remote emulators and simulators hosted by Momentic | ## Page objects and helpers Extract reusable page-object actions into [modules](/docs/core-concepts/modules). You do not need a module for every page class. Keep assertions that define a test's result in the calling test. This web module accepts credentials: ```yaml modules/log-in.module.yaml theme={null} fileType: momentic/module/v2 id: log-in name: Log in parameters: - name: USERNAME - name: PASSWORD steps: - type: text: "{{ env.USERNAME }}" into: the Username field - type: text: "{{ env.PASSWORD }}" into: the Password field - click: the Submit button ``` Call it from `before:` or `steps:` with `inputs`. Callers pass concrete values or `env` references. For example, a web test can call the module during setup: ```yaml account.test.yaml theme={null} fileType: momentic/test/v2 id: migrated-account url: https://shop.example.com/login defaultEnv: staging before: - module: path: ./modules/log-in.module.yaml inputs: USERNAME: string: test@example.com PASSWORD: env.TEST_PASSWORD steps: - checkElementVisible: Account menu ``` Declare `TEST_PASSWORD` in the selected environment's [secret configuration](/docs/configuration/environments#secrets). A module input such as `env.TEST_PASSWORD` is a JavaScript expression; `{ string: ... }` is a literal. Mobile modules use `fileType: momentic/mobile-module/v2`, a `platform`, and a different parameter declaration. See [module parameters](/docs/core-concepts/modules#parameters). Modules cannot call other modules. Flatten page-object methods that call other helpers into a single module, or call the modules in sequence from the test. ## Setup, teardown, and state Move per-test fixtures such as `@BeforeMethod`, `@AfterMethod`, or pytest fixtures into `before` and `after`. A failed setup skips the main steps. Teardown runs after setup or main-step failures; make cleanup tolerate data that setup never created. Run the whole test when validating hooks: running an individual editor step skips them. See [before and after sections](/docs/core-concepts/file-format#before-and-after-sections). Suite-wide build commands and external service startup belong in your CI job. Keep test data independent: allocate unique accounts or records per test, and clean up only those records. A new browser or device session does not reset shared backend data. Configure credentials through [environments](/docs/configuration/environments), rather than copying secrets from driver setup into YAML. For Appium, check the old reset, permissions, app installation, and launch behavior separately. `openApp` launches the installed app; it does not express all the behavior of an Appium capabilities object. `killApp` stops the current foreground app. Use it before `openApp` only when the intended app is already in the foreground. For an Android restart that targets a package regardless of foreground state, use the [named-package restart example](/docs/guides/migrate/from-maestro#before-and-after). Preserve any required data reset explicitly; stopping an app does not clear its data. ## Reuse setup and custom code * `javascript` steps provide `axios`, `pg`, `faker`, and `child_process` in a Node sandbox. Reuse seed endpoints and database operations, but adapt helpers that depend on your test framework or imported packages. The sandbox does not expose your Selenium or Appium driver object. See [JavaScript integration](/docs/integrations/javascript). * Rewrite `JavascriptExecutor` page scripts as web `javascript` steps with `environment: browser`. Replace driver argument references with DOM queries and return or throw explicitly. Mobile JavaScript has no browser execution context. * On mobile, [`appium`](/docs/reference/mobile-commands/appium) executes a named script with JSON-string arguments. Command availability and arguments depend on the device platform. Verify each script on the selected emulator or simulator before retiring its legacy coverage. * Replace the grid and driver setup with `npx momentic install-browsers chromium` (web) or a hosted browser/emulator. See [Hosted test environments](/docs/running-tests/hosted-test-environments). ## What does not map * There is no `WebDriver` object to hold or pass. You cannot run two driver sessions in one test; parallel testing is per-test parallelism, not multi-session choreography. * Selectors still work as targets, but the intended use is natural language. Web steps accept CSS selectors, not WebDriver `By` objects. Rewrite XPath or mobile selector objects as a description of the intended target. Preserve index, ancestor, and state constraints when they distinguish the target. * A custom `ExpectedCondition` does not translate by name. Use a supported condition step or rewrite a DOM check as browser JavaScript. Preserve its timeout and failure behavior; a single JavaScript evaluation is not a polling wait. * Remote execution covers Android emulators and iOS simulators, not physical device farms. Keep a device-farm runner for the tests that need hardware. * Selenium suites that drive WebDriver against non-browser targets do not map; Momentic tests browsers and mobile apps. ## Selenium, Playwright, or Momentic in 2026 Choose per flow based on required browsers and devices, framework-dependent helpers, and the maintenance work you can measure: * Keep Selenium or Appium coverage for unsupported browsers, physical devices, or driver-specific behavior you still need. A stable suite may not need a migration. * Compare a Playwright port when you want to retain browser tests as code. Inventory selector, wait, fixture, and CI changes before estimating the work. * Port a bounded flow to Momentic when you want repository YAML with preset steps, AI actions, and modules. Adapt its setup, assertions, and cleanup using this guide, then compare the run evidence with the original test. Estimate migration effort from that pilot, including authoring, review, helper adaptation, and CI changes. A coding agent can draft YAML, but you still need to verify the test's behavior. Replace coverage only after the migrated flow passes the checks below. Do not port a suite you plan to retire. ## Incremental strategy 1. Pick one bounded flow with recurring locator or wait failures. Port its setup, steps, assertions, and cleanup to a single `*.test.yaml` before converting the rest of the suite. 2. Lint and run that file using the commands below. Compare the original and migrated run evidence on the same build. Check that the assertion fails when the expected outcome is absent; a passing happy path alone is not evidence of equivalent coverage. 3. Extract modules once another test needs the same sequence. For mobile, verify the build, OS version, app state, and permissions on your intended local or remote target. 4. Add a separate Momentic CI job. Keep the Selenium or Appium job and its reports while you compare failures. Use separate test data when both jobs mutate the same backend. 5. Replace gates flow by flow after reviewing equivalent coverage and repeated results. Retain legacy tests for unsupported browsers, hardware, and custom behavior. Retire their grid or device-farm jobs only when that coverage is no longer required. For the web example, lint and run from the configured project root: ```bash theme={null} npx momentic lint checkout.test.yaml npx momentic run checkout.test.yaml --upload-results --reporter junit ``` For the Android example on a local AVD, provide both the AVD and APK: ```bash theme={null} npx momentic-mobile lint mobile-tests/welcome.test.yaml npx momentic-mobile run mobile-tests/welcome.test.yaml \ --local-avd-id Pixel_9_API_35 --local-apk-path ./build/app.apk \ --parallel 1 --upload-results --reporter junit ``` For iOS, use `--local-ios-device-type` and `--local-app-path` instead, or upload the build and select a channel and tag for remote execution. See [mobile run options](/docs/cli-reference/momentic-mobile/commands/run). The AVD name and build path above must match your machine. In CI, use the same committed test files and lockfile, set `MOMENTIC_API_KEY` from your CI secret store, and install the browser or device prerequisites. Keep the CLI's exit status as the job result and publish the JUnit report from `./reports`. See [GitHub Actions](/docs/running-tests/ci/github-actions) or the [other CI guides](/docs/guides). ## Porting at scale with a coding agent Hand the port to your coding agent with a prompt like: ```text theme={null} Port the Selenium tests in src/test/java/checkout/ to Momentic tests. Read the momentic-test skill first. Write one *.test.yaml per @Test method, convert each Page class to a *.module.yaml, remove only waits replaced by equivalent condition checks, and port any JavascriptExecutor blocks to javascript steps with environment: browser. Run each ported test with npx momentic run . ``` ## Related * [Test portability](/docs/get-started/test-portability) * [Web steps reference](/docs/reference/commands/index) * [Mobile steps reference](/docs/reference/mobile-commands/index) * [Hosted test environments](/docs/running-tests/hosted-test-environments) * [Modules](/docs/core-concepts/modules) # 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`). The saved object contains `downloadedFile`, a complete `file://` URI. Pass `{{ env.DOWNLOADED_FILE.downloadedFile }}` to a later [upload step](/docs/guides/page-interactions/upload-files). ## Limits * One file per **Click** step. * Download timeout: 10 seconds. * Downloaded files are temporary and are deleted five minutes after capture. * 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 select elements and Click for custom menus. Pick an option from a dropdown during a test. The approach depends on whether the element is a 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 page HTML contains a substring. | | [`checkPageDoesNotContain`](/docs/reference/commands/check-page-does-not-contain) | Assert that the page HTML does not contain a substring. | ## Element checks Every browser element-check variant has a soft counterpart: replace `checkElement` with `softCheckElement` and keep the same suffix and parameters. For `softAssert` and `softAssertVisually` as well, see the [soft assertions guide](/docs/guides/use-cases/collect-independent-assertion-failures). | 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 from a cookie 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) | Return browser auth state or save it to a storage-state JSON file. | ## Visual | Command | Summary | | - | - | | [`captcha`](/docs/reference/commands/captcha) | Legacy CAPTCHA command; solving is no longer supported. | | [`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. | | [`while`](/docs/core-concepts/steps#while-loops) | Repeat a block while a condition holds or until an iteration limit. | | [`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 | Evaluate `code` as an expression by adding an implicit `return`. Defaults to `false`. | | `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`](/docs/reference/commands/key-up) 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 * [keyUp](/docs/reference/commands/key-up) * [press](/docs/reference/commands/press): one-shot key presses and chords * [Steps](/docs/core-concepts/steps) # keyUp Source: https://momentic.ai/docs/reference/commands/key-up Release a previously pressed key. Use after [`keyDown`](/docs/reference/commands/key-down) 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 * [keyDown](/docs/reference/commands/key-down) * [press](/docs/reference/commands/press): one-shot key presses and chords * [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: onboardingComplete value: "true" ``` ```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 as a `Response` object. ## 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 function body that returns a `Response` object. | | `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. ## 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`](/docs/reference/commands/drag-and-drop). 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, from 0 to 60000 in multiples of 1000. | | `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, from 0 to 60000 in multiples of 1000. | | `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. Pastes the clipboard contents into the focused element. 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`. Reach for `press` when a flow depends on the keyboard: submitting a form with `Enter`, dismissing a dialog with `Escape`, or running an app's keyboard shortcuts. To hold a key across several steps, use [`keyDown`](/docs/reference/commands/key-down) and [`keyUp`](/docs/reference/commands/key-up) instead. ## 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 Submit a login form without clicking the button: ```yaml theme={null} - type: text: qa@acme.test into: the Email field - type: text: "{{ env.PASSWORD }}" into: the Password field - press: Enter ``` Close a modal with the keyboard: ```yaml theme={null} - press: Escape - checkPageDoesNotContain: Confirm your choice ``` ```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 * [keyDown](/docs/reference/commands/key-down) * [keyUp](/docs/reference/commands/key-up) * [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`, the recorder keeps every match. ## 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, from 0 to 60000 in multiples of 1000. | | `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. Use the `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: `GET`, `POST`, `PUT`, `DELETE`, or `PATCH`. Defaults to `GET`. | | `headers` | `Record` | No | Request headers. | | `params` | `Record` | No | Query parameters. | | `body` | `unknown` | No | Request body. | | `contentType` | `"json" \| "form-urlencoded"` | No | Body encoding. Defaults to `json`; `form-urlencoded` requires an object with string values. | | `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`. 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: pixels: 900 in: Results panel ``` ## Related * [Steps](/docs/core-concepts/steps) * [scrollUp](/docs/reference/commands/scroll-up) * [scrollLeft](/docs/reference/commands/scroll-left) * [scrollRight](/docs/reference/commands/scroll-right) # 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`. 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) * [scrollDown](/docs/reference/commands/scroll-down) * [scrollUp](/docs/reference/commands/scroll-up) * [scrollRight](/docs/reference/commands/scroll-right) # 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`. 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) * [scrollDown](/docs/reference/commands/scroll-down) * [scrollUp](/docs/reference/commands/scroll-up) * [scrollLeft](/docs/reference/commands/scroll-left) # 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`. 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) * [scrollDown](/docs/reference/commands/scroll-down) * [scrollLeft](/docs/reference/commands/scroll-left) * [scrollRight](/docs/reference/commands/scroll-right) # select Source: https://momentic.ai/docs/reference/commands/select Pick an option from a `` element by description or CSS selector. Coordinate targets are not supported. ## Parameters | Parameter | Type | Required | Description | | - | - | - | - | | `from` | `string` | No | Description of the ``/`