Skip to content
| Marketplace
Sign in
Visual Studio Code>Programming Languages>Manul BrowserNew to Visual Studio Code? Get it now.
Manul Browser

Manul Browser

Oleksii Poliakov

|
1 install
| (0) | Free
Write and run browser automation in plain English. Runs .hunt files with the manul-browser engine from npm, PyPI or a Go build, with a test explorer, step-by-step debugging and automatic hook pickup.
Installation
Launch VS Code Quick Open (Ctrl+P), paste the following command, and press enter.
Copied to clipboard
More Info

Manul Browser for VS Code

Write browser automation in plain English and run it from the editor.

STEP 1: Sign in
    NAVIGATE to https://www.saucedemo.com/
    FILL 'Username' field with 'standard_user'
    FILL 'Password' field with 'secret_sauce'
    CLICK 'Login' button
    VERIFY that 'Products' is present

This is the editor side of manul-browser: one engine, written in Go, that resolves elements by the label a person sees rather than by selector. The extension finds that engine, runs .hunt files with it, and shows what happened on the lines it happened to.

Works with whichever way you installed the engine

There is one engine and three ways to get it. The extension looks for all of them, in this order, and uses the first that actually runs:

Installed with Where it is found
npm install manul-browser node_modules/@manul-browser/engine-<os>-<cpu>, from the workspace folder upwards
pip install manul-browser .venv, venv, env or .env in the workspace, the active VIRTUAL_ENV, or manulBrowser.pythonPath
A Go build or a release archive manul in the workspace (./, bin/, core/), $GOBIN, $GOPATH/bin, ~/go/bin
Anything on PATH resolved through pip's and npm's launchers to the binary behind them

manulBrowser.enginePath overrides the search. Manul: Select Engine lists everything that was found and lets you pick; the status bar shows which one is in use.

Different engine versions are handled by asking, not by assuming: the extension reads the installed engine's --help and leaves out options that build does not have, and it merges whatever manul schema reports into the command list, so a newer engine's verbs show up in completion without an extension update.

Hooks are picked up for you

A hook script holds what a .hunt file cannot say: custom controls, CALL handlers, and suite hooks such as before_all.

# manul_hooks.py
import manul

@manul.before_all
def login(ctx):
    ctx.set("token", fetch_token())     # {token} in every hunt

manul.serve_hooks()

The engine only uses a hook script it is given with --hooks. Run a hunt without the flag and {token} stays {token}. The extension passes the flag on every run:

  • Which script — the nearest manul_hooks.py, manul_hooks.mjs, manul_hooks.js or manul_hooks.cjs at or above the hunt file, no higher than the workspace folder. manulBrowser.hooks.path names one explicitly; manulBrowser.hooks.enabled turns pickup off.
  • Which interpreter — a Python script runs under the environment the engine came from, or the first environment in the workspace that has the manul package, not under whatever python happens to be on PATH. That mismatch is the usual reason a hook script "does not work": it dies on import manul before it can say anything.
  • What it registers — the Hooks view lists each script's suite hooks, CALL handlers and custom controls, and jumps to them. In a hunt, CALL HOST <name> completes from that list and Go to Definition opens the handler; { completes the variables the script publishes.
  • What is wrong with it — a script that never calls serve_hooks() / serveHooks() is flagged before you run it, because the engine would start it, wait, and give up.

Manul: Create Hook Script writes a starting point in Python or JavaScript.

One thing to know: each hunt file is run as its own engine process, so before_all and after_all run once per file, not once for a whole Test Explorer run. To run a folder as a single suite, right-click it in the explorer and choose Manul: Run in Terminal.

Running

  • Run / Debug in the editor title, the CodeLens on the first line, the explorer context menu, or Ctrl+Alt+R.
  • The Test Explorer lists every .hunt file with its STEP blocks, runs them — several at once if manulBrowser.run.workers says so — and reports each block.
  • After a run every executed line carries its outcome and duration. Hover a line for the detail: the error, the candidates the engine ranked for that step and why the winner won, and the screenshot if one was taken.
  • The Run panel in the Manul Browser side bar shows the engine, the hook script and the last result, and holds the options: browser, visible or headless, screenshots, retries, HTML report.

Options left on From config are not passed at all, so manul.config.json decides. That file gets completion and validation.

Debugging

Set breakpoints in the gutter and choose Debug. With no breakpoints the run pauses before every step.

F10 run this step, pause before the next
F5 continue to the next breakpoint
Shift+F5 stop
Explain score the target of the paused step without running it
Show target scroll the browser to the element that would be used

Debug runs always show the browser window.

Writing

  • Syntax highlighting, outline and formatting for .hunt files.
  • Completion for every command, header and block, with placeholders.
  • The Step Palette view: the same list, searchable, one click from the cursor. Manul: Insert Step… is the keyboard version.
  • New Hunt File, Record a Hunt from a URL and Scan a URL into a Draft Hunt create files in your tests folder.

When something does not work

Run Manul: Check Setup (Doctor). It checks, and says in plain words: which engines were found and which one runs, whether that build has the options the extension needs, which hook script a run would get, and whether the interpreter for it can actually import the binding.

Settings

Setting Default
manulBrowser.enginePath (find it) Path to the manul binary
manulBrowser.pythonPath (find it) Interpreter or venv folder for the engine and .py hooks
manulBrowser.nodePath node Node for .js / .mjs hooks
manulBrowser.hooks.enabled true Pass a hook script to every run
manulBrowser.hooks.path (find it) A specific hook script
manulBrowser.run.browser config chromium, firefox, or leave it to the config file
manulBrowser.run.channel chrome, msedge, firefox-dev, …
manulBrowser.run.headless config on, off, or leave it to the config file
manulBrowser.run.retries 0 Re-run a failed hunt; a later pass is reported as flaky
manulBrowser.run.screenshot config on-fail, always, none
manulBrowser.run.htmlReport false Write reports/manul_report.html
manulBrowser.run.explain false Print score breakdowns
manulBrowser.run.workers 1 Hunt files run at once from the Test Explorer
manulBrowser.run.extraArgs [] Extra engine arguments
manulBrowser.run.env {} Extra environment variables
manulBrowser.testsHome tests Where new hunt files go
manulBrowser.inlineResults true Show outcomes at the end of each line

Requirements

  • VS Code 1.90 or later.
  • A manul-browser engine, 0.1.2 or later for everything described here. Older builds run, with the options they lack left out.
  • Chrome, Chromium, Edge or Firefox for the engine to drive.

Development

npm install
npm test            # unit tests, no browser needed
npm run package     # builds the .vsix

A push to main whose package.json version has no GitHub Release yet gets one, with the .vsix attached: bumping the version is what releases.

src/core has no dependency on VS Code and holds everything worth testing in isolation: finding the engine, finding and reading hook scripts, mapping the engine's results back to lines. src/test/integration runs inside a real VS Code against a real engine; its header says how to start it.

License

Apache 2.0 — Copyright 2026 Oleksii Poliakov. See LICENSE.

  • Contact us
  • Jobs
  • Privacy
  • Manage cookies
  • Terms of use
  • Trademarks
  • Your Privacy Choices
  • Consumer Health Privacy
© 2026 Microsoft