# Quick start — web

> For the complete documentation index, see [llms.txt](/llms.txt)

Get your first test written and running in a few minutes. Works with any backend
stack (Node, Django, Rails, Go…) — no `package.json` required.

## 1. Initialize

Run once in your project:

```sh
npx @unotest/web init
```

`init` writes the config and a starter scenario, sets up the browser (bundled
Chromium, or your system Chrome if you pick it), and wires the MCP server so
Claude Code / Cursor / Codex pick it up automatically. Re-run anytime — it never
overwrites your edits.

## 2. Open the viewer

```sh
npx @unotest/web viewer
```

A local IDE-style UI for your tests — no cloud, no account. Browse scenarios,
run them, and watch each step live. This is your home base.

## 3. Ask your agent for a test

In your AI editor, open your project and describe the flow in plain English:

> Open my app, sign in as the demo user, and check that the dashboard heading
> appears.

Through the MCP server the agent explores your live app — clicking, filling,
reading the real DOM — then writes a clean scenario to `unotest/e2e/<name>.js`
with stable selectors, runs it, and debugs itself if it fails.

```js
function test_login() {
  step("Sign in as the demo user", () => {
    goto("/login");
    fill(getByLabel("Email"), TEST_USER_EMAIL);
    fill(getByLabel("Password"), TEST_PASSWORD);
    click(getByRole("button", { name: "Continue" }));
  });

  step("Dashboard is shown", () => {
    assertVisible(getByRole("heading", { name: "Dashboard" }));
  });
}
```

## 4. Run it

Click any scenario in the viewer, or from the CLI:

```sh
npx @unotest/web e2e login
```

## 5. Review & commit

You get a reviewable `.js` test. Read it, tweak it, commit it. That's the whole
loop — the agent does the legwork, you own the result.

:::tip
Point your agent at its authoring guide — see [For your AI agent](/agent/overview/).
:::

## Next

- [Concepts: scenarios & `step()`](/concepts/scenarios/)
- [Write your first test (guided)](/guides/first-test/)
- [The viewer](/viewer/overview/)
