Create, run, and maintain Momentic E2E tests and modules, which are serialized to disk as *.test.yaml and *.module.yaml files. Momentic uses fast, accurate AI…
SaferSkills independently audited momentic-test (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Momentic is an end-to-end testing framework. Tests are ordered lists of structured steps executed with Playwright and CDP.
targets into concrete browser actions.
Momentic caches resolved step metadata such as selectors, XPaths, visible text, and coordinates so most runs avoid repeated AI calls. This is critical for speed, but stale cache is a real debugging possibility: a step may hit the wrong element. AI assertions may also use past-result memory to stay consistent across runs; bad memory can explain repeated borderline failures.
Caches are scoped by git metadata, including branch. Cache writes are skipped on protected branches, including the configured main branch, unless cache saving is forced with --save-cache or the CI environment variable is set. Cache reads can still happen on protected branches. Use --disable-cache to bypass cache entirely.
Ways to force fresh behavior:
changes the step identity used for cache matching. In v1, splicing a changed step also creates fresh internal UUIDs.
--disable-cache for dynamic targets that should resolve fresh every run, e.g "the calendar cell for today's date".CacheId into splice with--cache-id <CacheId>.
Momentic uses "smart waiting" before targeting steps. It waits up to the configured Smart waiting timeout, which defaults to 5 seconds, for page state to settle or the desired element to appear. Within that window, do not add manual sleeps or waits. For slower or more semantic readiness, use waitForUrl, text/element checks, or an AI assertion.
momentic.config.yaml sets project defaults, but many settings can be overridden at the test level: browser type, viewport, locale/timezone, geolocation, page-load timeout, smart-waiting timeout, proxy, headers, auth, extensions, etc. Always check the test's own metadata before assuming the project default applies.
Each run has a test-scoped env context that persists across steps, including modules. Later steps can read values written by earlier steps.
saveAs on steps with return values.--env-key.return plus saveAs / --env-key; usesetVariable(name, value) when setting multiple variables.
env.NAME in JavaScript and module input expressions.{{ env.NAME }} in string fields. {{ ... }} can evaluate JavaScript,but do not use it inside JavaScript step source because env is already in scope there.
Module inputs are JavaScript fragments as strings. Quote literal strings and use env.X for variables; they are not {{ }} templates.
JavaScript steps can run in NODE or BROWSER.
NODE: default for API calls, data prep, OTP/email/SMS, DB queries, andvariable writes. It has Momentic globals and preloaded libraries. env, setVariable, email, sms, axios, assert, faker, moment, pg, OTPAuth, child_process, etc. Check the JavaScript command docs or the Step Authoring Guide for more details
BROWSER: runs in the page with window / document and page globals. Itdoes not have Node-only Momentic helpers.
Keep short one-off JavaScript inline. In v2 YAML, reusable utilities and long scripts can live in a project script file, following existing project conventions. Prefer locations such as ./scripts/page-utilities/auth-loader.js. Read nearby scripts first and match their module style, helper naming, env usage, and error style.
Tests are *.test.yaml files. Modules are reusable step collections stored as *.module.yaml files. Test IDs are authoritative and live on the test file's id field.
There are two major file formats:
fileType: momentic/test/v2 or fileType: momentic/module/v2 -> v2.Direct YAML editing is preferred for high-confidence changes as it is faster.
fileType or any other value -> v1. Never edit v1 YAMLdirectly; persist changes only through momentic_test_splice_steps.
momentic.config.yaml is the project root config. It stores project defaults for agents, AI features, browser options, recording, timeouts, browser type, file globs, and environments. See https://momentic.ai/docs/configuration/momentic-config.md.
v2 steps can reference local files by relative path:
path: ./modules/login.module.yamljavascript: ./scripts/setup.jsauthLoad: ./auth-state.json, authSave: ./auth-state.jsonRelative paths resolve from the YAML file containing the step, not from the project root or importing test. Use ./... or ../...; do not use absolute paths or ~. If you move, rename, or delete a referenced file, grep for the old path and update every reference.
v1 YAML should still be edited only through MCP. Do not use codeFile in v1 YAML or MCP CLI step strings; v1 JavaScript steps should carry executable code in code / --code. Use JavaScript file references only in v2 YAML.
Do not add internal or auto-generated fields to v2 YAML.
Gather only what you need:
baseUrl or named environment.For long tasks, inspect nearby tests and modules before authoring. Reusing an existing module is usually better than rebuilding a common flow inline.
Ask before long-running checks, starting over from scratch, destructive actions, or editing a shared module.
If the user requests a specific workflow, respect it unless it is unsafe or impossible. Otherwise, use direct v2 YAML editing when the file is v2, the change is localized, the step sequence is known, and live UI discovery is not required. Good examples: scaffold from a nearby pattern, reword an assertion, adjust a target, update an env key, fix a file reference, or insert a small known step.
Use the MCP browser-validation workflow when the file is v1 or unknown, UI state must be discovered, locator timing is flaky, the flow is multi-step and unclear, or the user asks to build/validate interactively ("headful mode").
Use momentic_test_create for new tests; search for the tool if it is not visible. It requires name and either baseUrl or environment. Only pass destination fields such as pathSegments when requested. momentic_session_start requires an existing testId; it does not create tests.
coordinates only as a last resort for cases the AI cannot see, such as SVG internals, canvas, or a user-requested selector-level target.
expresses the behavior. JS steps can run in either the browser (client-side) or Node (server-side).
are needed to make the next dependent action reliable.
immediate validation before dependent actions. Prefer waitForUrl for URL contracts, checkPageContains / checkElement... for stable text or elements, and assert for semantic visual state.
act, AI_ACTION, AI_ACTION_DYNAMIC) unless theuser asks or the existing test already uses one.
literal values, quoting, comments, ordering, and step style.
or a backend is down, report the failure instead of weakening the test.
before / steps / after or setup / main / teardownunless the test intent requires it.
v2 is the human-editable format. Steps are compact: each step has one top-level command key, such as click: Submit, or a detailed map under that key. Tests use before / steps / after; modules use steps. Durations are always milliseconds. No visible step/command IDs.
Direct-edit loop:
momentic_test_create, then edit the YAML in one batch instead of adding known steps one-by-one through MCP.confirmation.
Common mistakes:
npx momentic lint validates v2 schemas and file references. Lint runs automatically before momentic app and momentic run; run it manually if you are unsure of syntax after edits or after moving/renaming referenced files.
State refresh after disk edits:
momentic_test_reload: reload before momentic_run_step.momentic_test_get inspects persisted state; it does not refresh an activesession unless the tool explicitly says so.
Use this for every v1 edit and for v2 work that needs live discovery. The tool surface is shared; persistence differs: v1 uses splice, while v2 can use splice or direct YAML edit plus reload.
momentic_get_artifacts(): project context, config path, cwd, and artifactfiles for tests, modules, environments, etc. Read only what you need.
momentic_test_get({ testId | testPath }): inspect persisted test state.Before a session, this is useful. During an active session after splicing, prefer the splice response or returnTest: true.
momentic_module_recommend({ userRequest }): find reusable flows.momentic_module_get({ selector }): inspect module params, defaults, enums,and steps. Selector is exactly one of { id }, { name }, or { path }.
momentic_session_start({ testId, ... }): start browser session. It returnsmetadata, the Step Authoring Guide artifact, and Test Content with active-session step IDs. Required: testId. Call it by itself, not in parallel with other MCP tools. Options include env/config/project overrides, headful mode, and video.
resetSession? }): run existing active-session steps. Use step IDs from Test Content or splice responses, never raw YAML. Use parentStepIdChain: [] for top-level steps. **Never run a range containing an AI action through this MCP tool.** MCP tool calls are capped at 60s, and AI actions routinely run well past that and get cancelled mid-run — the run is killed and its work is lost. ALWAYS execute such a range with the momentic run-step` CLI in your terminal (see "Executing long-running AI Action steps"), which has no such cap.
momentic_run_step and resetSession: true onthe same sessionId; do not reset between every micro-edit.
momentic_session_terminate({ sessionId }): terminate when done. If startedwith video: true, the response includes the video directory.
Author MCP steps in checkpoint-sized chunks. Preview forward until a logical section works, then splice that checkpoint. Good checkpoints are natural flow boundaries such as login complete, form submitted, page deleted, etc. Avoid splicing one step at a time, unless it is highly risky and non-idempotent.
momentic_preview_step({ sessionId, step }): execute one step in the browser withoutpersisting. If it returns CacheId, include --cache-id <CacheId> when splicing that step. The response screenshot shows the page state after the step. Never preview an AI action through this MCP tool — it will be cancelled at the 60s tool-call cap mid-run and its work lost. ALWAYS preview an AI action with the momentic preview-step CLI in your terminal (see "Executing long-running AI Action steps").
momentic_get_session_state with returnBrowserState: true, then inspect the artifact for stable names, roles, visible text, and prominent structure to help craft a reliable description. Use sparingly as browser state is large.
form fields, splice them together and run that saved range instead of previewing each field one by one.
targetSection?, parentStepIdChain?, returnTest? })`: insert, replace, or delete steps and persist.
inserted/deleted refs and active-session step IDs.
returnTest: true, verify the returned structure before continuing.still connects.
avoid repeated previews. Preview the setup steps, splice the checkpoint before the risky action, then execute the risky saved step once only when validation requires it.
field unless locator or page state is uncertain.
running the relevant saved range with momentic_run_step.
Sessions are live browser processes. Screenshots and browser states are instant snapshots. If the screenshot does not show expected state after an action, call momentic_get_session_state once more; the page may still be loading.
MCP tools may return artifact links under .momentic-mcp/.... Read linked files only when needed:
envKey, JavaScript/API outputs, or dependentenv values.
momentic_get_session_state returns serialized UI state only withreturnBrowserState: true; screenshots are returned by default.
preview_step and splice_steps use CLI-style strings: --step-type <TYPE> [options], e.g. CLICK, TYPE, NAVIGATE, AI_ASSERTION, MODULE, WAIT_FOR_URL.
Examples:
--step-type NAVIGATE --url "https://example.com"--step-type CLICK --description "the Sign in button"--step-type TYPE --description "Search input" --value "hello" --press-enter
--step-type AI_ASSERTION --assertion "the page shows a Sign in button" --timeout-seconds 10
--step-type MODULE --module-id <id> --inputs email=env.USER_EMAIL --inputs password=env.USER_PASSWORD
Splice example:
{
"sessionId": "SESSION_ID",
"startIndex": 0,
"deleteCount": 0,
"steps": [
"--step-type NAVIGATE --url \"https://example.com\"",
"--step-type AI_ASSERTION --assertion \"the page shows a Sign in button\" --timeout-seconds 10 --cache-id UUID_FROM_PREVIEW"
],
"targetSection": "main"
}For conditionals, create the CONDITIONAL step with --assertion-type and the matching assertion fields, then splice nested steps with parentStepIdChain: [conditionalStepId].
This is mandatory, not a suggestion. AI actions (AI_ACTION_DYNAMIC) plan and run many sub-steps at runtime and routinely take well over 60 seconds. MCP tool calls are capped at 60 seconds and are cancelled regardless of progress, so running an AI action through momentic_preview_step / momentic_run_step gets it killed mid-run and you lose the work. The terminal has no such cap. ALWAYS execute any step range that contains an AI action through the `momentic` CLI in your terminal — NEVER through the MCP run/preview tools.
The CLI commands mirror the MCP tools one-to-one and run against the same long-lived daemon. When the MCP server is started with --daemon, an MCP session and a CLI call share the same live browser (keyed by the project config path): author over MCP, then run the AI action over the CLI with the same sessionId. If the server is not in --daemon mode, or you are unsure, drive the whole flow over the CLI: session-start, then preview/splice/run, then session-terminate.
Pass --json on any command for the raw tool result instead of text. Screenshots and other artifacts are written under .momentic/mcp-cli-artifacts/.
All commands also accept --api-key, --server, --config, and --filter.
momentic session-start <testId> [--env <name>] [--headful-browser] [--video]— start a session (mirrors momentic_session_start). Prints the sessionId and the Step Authoring Guide. Use only when not reusing an MCP session.
momentic session-terminate --session <id> — terminate a session (mirrorsmomentic_session_terminate).
momentic session-state --session <id> — current session state (mirrorsmomentic_get_session_state).
momentic session-env --session <id> — environment variables available to thesession (mirrors momentic_get_environment_variables).
momentic preview-step --session <id> --step "<cli-style step>" — execute onestep without persisting (mirrors momentic_preview_step). --step takes the same CLI-style step string as MCP; pass --step "--step-type CLICK --help" for step authoring help.
momentic run-step --session <id> --from-step <stepId> [--from-parent <ids...>] [--to-step <stepId>] [--to-parent <ids...>] [--section main] [--reset]— run a saved step range (mirrors momentic_run_step). This is the command to use for AI actions. --from-parent / --to-parent are the parentStepIdChain (root to immediate parent; omit for top-level). --reset resets the browser first.
momentic splice-steps --session <id> --start <index> --delete <count> [--step "<cli-style step>" ...] [--section main] [--parent <ids...>] [--return-test]— insert/replace/delete steps and persist (mirrors momentic_test_splice_steps). Repeat --step to splice multiple steps. --delete 0 inserts, 1 replaces one, N deletes N. --parent is the parentStepIdChain when splicing into a nested step.
Author over MCP, then execute the AI action over the CLI with the shared session (stepId values come from the splice response / Test Content):
momentic run-step --session "$SESSION_ID" --from-step "$AI_ACTION_STEP_ID"Fully self-contained CLI flow:
momentic session-start my-test-id # prints SESSION_ID
momentic splice-steps --session "$SESSION_ID" --start 0 --delete 0 \
--step "--step-type NAVIGATE --url https://example.com" \
--step "--step-type AI_ACTION_DYNAMIC --text \"complete checkout with the saved test card\""
momentic run-step --session "$SESSION_ID" --from-step "$FIRST_STEP_ID"
momentic session-terminate --session "$SESSION_ID"Default to module-first for logical flows of 4+ steps such as login, navigation, setup, or checkout. Call momentic_module_recommend, inspect strong candidates with momentic_module_get, then decide module vs inline.
Modules cannot contain modules. Splicing a MODULE step inside a module fails.
Editing a shared module requires user confirmation. To modify a module through MCP, replace the module step with a MODULE step carrying the needed metadata flags: --parameters, --parameter-enum, --default-parameter, --module-display-name, --module-description, --module-enabled. Keys in defaultParameters and parameterEnums must exist in parameters.
Module inputs values are JavaScript fragments as strings. Quote string literals, reference env as env.X, and respect enum constraints exactly.
whether to run.
the session, then run the edited range.
next downstream saved step or range.
momentic_get_session_state.momentic_get_session_state once more.AI_ASSERTION, checkPageContains, checkElement...,or waitForUrl over generic WAIT.
an appropriate timeout instead of sleeps.
momentic_run_step with resetSession: true.description using visible text, role, and nearby context; if absent, debug the prerequisite step.
step.
actionable because it is hidden, detached, outside the viewport, covered, or animating. Prefer fixing page state when possible. Use --force only for that step when bypassing actionability is acceptable, or enable project-wide visual actions if coordinate-based interaction is the right tradeoff.
visualActions: true. Momentic interacts by X/Y coordinates and tries to preserve element identity best-effort instead of hard-failing like Playwright actionability checks.
Momentic AI. Use quotes only when that exact text must appear on screen or in the element's accessible name; omit quotes for semantic matching.
the relevant page region, object, count, or state.
screen. Remove quotes when semantic matching is intended. Describe the purpose of elements when possible rather than specific text or labels.
if the element is in the viewport. Use scroll/hover setup.
AI_ASSERTION supports VISION_ONLY mode which hasbetter visual reasoning.
clearer and old memory no longer applies.
timeout but each attempt is an instantaneous snapshot. As such, extremely fast changes like toasts that appear and vanish in 1 second can be missed. Also, there is no ability to evaluate changes over time ("the screen is darker than before"). Prefer crafting assertions for stable final state; if necessary client-side JavaScript observers can be used.
npx momentic lint <path>; broken relative filereferences are common after moves.
input syntax with momentic_module_get.
saveAs / --env-key orsetVariable, and that the consuming syntax is env.X vs {{ env.X }}.
helpers; Node JS cannot read live DOM globals.
After about three attempts on the same problem, stop and ask the user for a direction.
returnTest;never raw YAML step IDs.
the same session.
momentic_preview_step.momentic_test_splice_steps.momentic_run_step with resetSession: true.momentic_test_reload if active, else fresh session.momentic run-stepCLI in the terminal — NEVER momentic_run_step, which is cancelled at the 60s MCP tool-call cap mid-run.
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.