Write your first test
Start with a workflow you care about. We’ll use saving a contact here; swap in your app’s route, labels and expected result.
Install Dyno
Section titled “Install Dyno”You’ll need Node 24+. Install from GitHub for now, then download Chromium once:
npm install --save-dev github:Robdel12/dynonpx dyno initnpx dyno installinit adds a config and an example test without overwriting existing files. Commit your lockfile so local runs and CI use the same Dyno revision.
Dyno currently pins Interactor fixes that are not yet on the registry. pnpm 11 blocks Git subdependencies and their prepare builds by default. Projects that permit this Git source need the following in pnpm-workspace.yaml, alongside their existing build entries:
blockExoticSubdeps: falseallowBuilds: interactor.js: trueblockExoticSubdeps changes the project’s whole dependency-source policy; the build permission above only allows Interactor. See pnpm’s source policy before choosing that setting.
Point it at your app
Section titled “Point it at your app”In dyno.config.js, set the command that starts your app and the URL it serves:
export default { testDir: 'tests/browser', webServer: { command: 'npm run dev', url: 'http://127.0.0.1:3000', reuseExistingServer: !process.env.CI, },};Dyno starts that command for you. Locally, reuseExistingServer lets you use an app that’s already running; Dyno leaves that server alone when it stops.
Test the result
Section titled “Test the result”Replace the example test in tests/browser:
import { describe, test } from 'dyno';
describe('Contacts', () => { test('saves a contact', async ({ app, I }) => { await app.goto('/contacts/new'); await I.find('Name').then.fill('Robert'); await I.click('Save'); await I.find('$([role=status])').text('Contact saved'); });});Interactor waits for the expected UI. Await each action and assertion, and keep tests inside a named describe.
Run it
Section titled “Run it”npx dyno doctornpx dyno --uidoctor checks your config, test bundle and browser setup. --ui runs the test with the app visible. Use npx dyno for a headless run.
Next, learn the interaction basics or share workflows with custom interactors. JavaScript, JSX, TypeScript and TSX work; run your own type checker for TypeScript.