> ## Documentation Index
> Fetch the complete documentation index at: https://momentic.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# JavaScript

> Run arbitrary JavaScript inside a test, either in a sandboxed Node environment or in the current browser page.

**JavaScript** steps execute code as part of a test. `async`/`await` is
supported. Return values are passed to downstream steps and must be
[JSON-serializable](https://en.wikipedia.org/wiki/Serialization).

```javascript theme={null}
const res = await axios.post("https://api.example.com/login", {
  email: env.USERNAME,
  password: env.PASSWORD,
});

setVariable("SESSION_TOKEN", res.data.token);
return res.status;
```

## Execution contexts

| Context          | When to use                                                 | Access                             |
| ---------------- | ----------------------------------------------------------- | ---------------------------------- |
| **Node sandbox** | Default. API calls, data prep, secret rotation, DB queries. | Momentic globals (see below)       |
| **Browser page** | Enable **Execute in browser**. DOM queries, local storage.  | `window`, `document`, page globals |

Browser steps don't have access to the Node sandbox globals.

## Timeout

JavaScript steps default to a **90 second** timeout. Configure per step via the
**Timeout** field, or in YAML (value is in seconds):

```yaml theme={null}
- javascript:
    code: |
      const msg = await email.fetchLatest({
        inbox: "qa+signup@momentic.ai",
        timeout: 60_000,
      });
      return msg.text;
    timeout: 120
```

The maximum configurable timeout is **10 minutes** (600 seconds), suitable for
long external polls or batched lookups against slow APIs.

If a nested helper such as `email.fetchLatest` or `sms.fetchLatest` polls for
longer than the JavaScript step's own timeout, the step is killed before the
helper returns. Set the step's **Timeout** to comfortably cover the longest
nested poll.

## `{{ }}` templating

Any string input on any step can contain `{{ expression }}`. Expressions
evaluate at runtime and are interpolated into the value.

```yaml theme={null}
- type:
    text: "{{ env.USERNAME }}@gmail.com"
    into: Email field
```

<Warning>
  Don't use `{{}}` inside **JavaScript** step source. Variables are already in
  scope as `env.VARIABLE_NAME`.
</Warning>

## Momentic utilities

Provided by the Momentic runtime.

### `env`

Read-only map of the current environment's variables. See
[Variables](/core-concepts/variables) for how variables are resolved.

```javascript theme={null}
const res = await axios.get("https://api.example.com/me", {
  headers: { Authorization: `Bearer ${env.API_TOKEN}` },
});
```

### `setVariable(name, value)`

Write a variable scoped to the current test run. Downstream steps can read it
via `{{ name }}` in any string input, or via `env.name` inside JavaScript.

```javascript theme={null}
const res = await axios.post("https://api.example.com/login", {
  email: env.USERNAME,
  password: env.PASSWORD,
});

setVariable("SESSION_TOKEN", res.data.token);
```

### `email`

Send and fetch email. See [Email](/integrations/email) for inbox setup.

```javascript theme={null}
// fetch the latest verification email
const msg = await email.fetchLatest({
  inbox: "qa+signup@momentic.ai",
  timeout: 30,
});
const code = msg.text.match(/\d{6}/)[0];
setVariable("VERIFICATION_CODE", code);
```

### `sms`

Send and fetch SMS. See [SMS](/integrations/sms) for number setup.

```javascript theme={null}
const msg = await sms.fetchLatest({
  to: "+15551234567",
  timeout: 60,
});
setVariable("OTP", msg.body.match(/\d{6}/)[0]);
```

### `extractCookiesFromResponse(response)`

Convert a `fetch` / `axios` response's `Set-Cookie` headers into an array of
Playwright-compatible cookies. Useful for bootstrapping an authenticated browser
context.

```javascript theme={null}
const res = await fetch("https://api.example.com/login", {
  method: "POST",
  body: JSON.stringify({ email: env.USERNAME, password: env.PASSWORD }),
});

const cookies = await extractCookiesFromResponse(res);
setVariable("AUTH_COOKIES", cookies);
```

### `mock`

Only available in **mock handler** steps on mocked routes. Exposes the
intercepted `Request` and the upstream `Response`.

```javascript theme={null}
// stub the /pricing response but forward everything else
if (mock.request.url.endsWith("/pricing")) {
  return new Response(JSON.stringify({ plan: "enterprise" }), {
    status: 200,
    headers: { "content-type": "application/json" },
  });
}
return mock.response;
```

## Libraries

### `axios`

HTTP client. See [axios docs](https://axios-http.com/docs/intro).

```javascript theme={null}
const { data } = await axios.get("https://api.example.com/status");
assert.equal(data.ok, true);
```

### `assert`

Node's built-in assertions. See [Node docs](https://nodejs.org/api/assert.html).

```javascript theme={null}
assert.equal(res.status, 200);
assert.deepStrictEqual(res.data, { success: true });
```

### `faker`

Generate realistic fake data. See [Faker docs](https://fakerjs.dev/api/).

```javascript theme={null}
const email = faker.internet.email();
const name = faker.person.fullName();
setVariable("NEW_USER_EMAIL", email);
setVariable("NEW_USER_NAME", name);
```

### `moment`

Parse and format dates. See [Moment docs](https://momentjs.com/docs/).

```javascript theme={null}
// pick a date 30 days from now, formatted for a date input
setVariable("FUTURE_DATE", moment().add(30, "days").format("YYYY-MM-DD"));
```

### `pg`

Postgres client. See [node-postgres docs](https://node-postgres.com/).

```javascript theme={null}
const client = new pg.Client({ connectionString: env.DATABASE_URL });
await client.connect();
const { rows } = await client.query(
  "SELECT id FROM users WHERE email = $1 LIMIT 1",
  [env.TEST_EMAIL],
);
await client.end();
setVariable("USER_ID", rows[0].id);
```

### `OTPAuth`

Generate TOTP codes for 2FA tests. See
[otpauth docs](https://github.com/hectorm/otpauth).

```javascript theme={null}
const totp = new OTPAuth.TOTP({ secret: env.TOTP_SECRET });
setVariable("OTP_CODE", totp.generate());
```

### `child_process`

Spawn subprocesses. See [Node docs](https://nodejs.org/api/child_process.html).

```javascript theme={null}
const { execSync } = child_process;
const branch = execSync("git rev-parse --abbrev-ref HEAD").toString().trim();
setVariable("GIT_BRANCH", branch);
```

### `Octokit` + `createAppAuth`

Authenticated GitHub API access. See
[Octokit docs](https://github.com/octokit/octokit.js) and
[auth-app docs](https://github.com/octokit/auth-app.js/).

```javascript theme={null}
const octokit = new Octokit({
  authStrategy: createAppAuth,
  auth: {
    appId: env.GITHUB_APP_ID,
    privateKey: env.GITHUB_APP_PRIVATE_KEY,
    installationId: env.GITHUB_INSTALLATION_ID,
  },
});

const { data: pr } = await octokit.rest.pulls.get({
  owner: "momentic-ai",
  repo: "examples",
  pull_number: 42,
});
setVariable("PR_STATE", pr.state);
```
