TypeScript and JavaScript
npm install -D swiftbrowseThe swiftbrowse package is an ES module with TypeScript types and no dependencies. It runs the native swiftbrowse binary as a child process and talks to it over JSON lines. Use it with any test framework: node:test, Vitest, Jest, Mocha.
A test
import { test, before, after } from 'node:test';
import { launch } from 'swiftbrowse';
let browser;
before(async () => { browser = await launch(); });
after(() => browser.close());
test('adds a todo', async () => {
const page = await browser.newSession();
await page.navigate('http://localhost:3000/');
await page.fill('New todo', 'Write docs');
await page.pressKey('Enter', { expect: { type: 'text_visible', text: 'Write docs' } });
await page.expect([
{ type: 'count', target: { by: 'role', role: 'listitem' }, count: 1 },
{ type: 'no_console_errors' },
]);
await page.close();
});node --testStart one launch() per test file (or per worker) and one newSession() per test. A session is isolated: its own cookies, storage and tabs. Sessions run concurrently, and each attaches to the warm browser daemon, so creating one takes milliseconds.
API
launch(options?) → Promise<Browser>
Starts a swiftbrowse sdk process.
| Option | Default | Meaning |
|---|---|---|
testDefaults |
true |
No approval prompts for "Delete" or "Pay" clicks, evaluate allowed, uploads from the working directory. Set it to false for the agent-safe policy. |
headed |
false |
Show browser windows. |
noDaemon |
false |
Launch a browser for this process instead of attaching to the warm daemon. |
chromium |
discovered | Path to a Chromium binary. |
evidenceDir |
temp directory | Where screenshots, videos and saved states go. |
timeoutMs |
10000 | How long actions wait for their target, in ms. |
allowHosts / blockHosts |
Restrict navigation (*.example.com patterns allowed). |
|
uploadDirs |
Extra directories uploadFile may read from. |
|
allowFileUrls |
false |
Permit file:// navigation. |
throwOnError |
true |
Throw SwiftBrowseError when an operation fails. |
executable |
found | Path to the swiftbrowse binary. |
browser.newSession({ headless?, viewport?, throwOnError? }) → Promise<Session>
viewport is [width, height]; the default is [1280, 800].
browser.close()
Closes every session and stops the process. Call it in after/afterAll.
Session methods
Every operation is a camelCase method: required arguments in order, then an options object whose keys are the operation's other arguments in snake_case.
await page.navigate(url, { wait_until: 'network_idle' });
await page.click('Save', { expect: { type: 'text_visible', text: 'Saved' }, timeout_ms: 10000 });
await page.fill({ by: 'label', text: 'Email' }, 'ada@example.com');
await page.selectOption('Country', 'Norway');
await page.check('I agree');
await page.uploadFile('Documents', ['fixtures/notes.txt']);
await page.route({ url: '**/api/todos', json: [] });
await page.switchTab({ url_contains: 'checkout' });
await page.switchFrame({ name: 'payment' });
await page.saveStorageState('member');
const shot = await page.getScreenshot({ full_page: true });Plus three helpers:
page.expect(condition | condition[], { timeoutMs = 5000, name }): an auto-waiting assertion. See Assertions.page.text(): the page as compact text (URL, title, headings, interactive elements).page.run(op, args): any operation by name.
Results and errors
Every method resolves to an ActionResult. If the operation failed, it throws a SwiftBrowseError instead, unless throwOnError is false. The error carries kind (for example not_found, ambiguous or verification_failed) and the full result, and its message includes any notes. Test frameworks report it like any failed assertion.
import { SwiftBrowseError } from 'swiftbrowse';
try {
await page.click('Missing', { timeout_ms: 500 });
} catch (e) {
if (e instanceof SwiftBrowseError && e.kind === 'not_found') { /* … */ }
}Types
Methods, options, Target, Condition and ActionResult are typed. The types are generated from the engine's schemas, so editors autocomplete every argument and condition, and CI fails if they drift from the engine.
The binary
The SDK uses, in order: the executable option, $SWIFTBROWSE_BIN, the binary from the platform package npm installed (swiftbrowse-<platform>), then swiftbrowse on PATH. The package also installs the CLI: npx swiftbrowse test.
Parallelism with node:test
node --test runs test files in parallel processes. Tests inside a file run in order unless you use { concurrency: true }. Each file's launch() gets its own sessions on the shared warm browsers.