OttoTester does — autonomously. It explores your web app from a plain-English goal, writes the tests, heals them when the UI changes, learns from every run, and grades its own work. See each part →
1import { test, expect } from '@/test'
2
3// Written by OttoTester after exploring the app.
4test('user can sign in with email + password', async ({ page }) => {
5 await page.goto('/auth/login')
6 await page.getByLabel('Email').fill(env.AUTH_user_EMAIL)
7 await page.getByLabel('Password').fill(env.AUTH_user_PASSWORD)
8 await page.getByRole('button', { name: /sign in/i }).click()
9 await expect(page).toHaveURL('/dashboard')
10 await expect(page.getByText(/welcome back/i)).toBeVisible()
11}) /api/cart to settle before asserting the totalPoint Otto at a PRD, design doc, or spec. It proposes the test cases they imply — prioritized and mapped against what's already covered, so you see coverage gaps before you ship.
Plan, generate, run, heal — all four phases in one place, and the agent does the writing.
Drop a PRD, a design doc, or just describe the feature in plain English. The planner explores your app, proposes candidate tests, and surfaces them for your review before any code is written.
End-to-end, functional, and regression tests with semantic, accessibility-aware locators. Credentials flow through env vars; shared data sets feed pooled inputs.
On every commit. PR check-runs report the verdict natively in GitHub. Failed tests open issues automatically. Any CI can trigger runs through the API.
When a locator or expected value drifts, the healer diagnoses the root cause and ships a fix — without rewriting the test.
Point OttoTester at your dev URL. We open a managed browser session against it.
Tell OttoTester what to cover in plain English. The agent explores your app on its own and proposes test candidates for you to review.
Review the generated tests, approve what looks right, and OttoTester writes them into your repo. Done.
Free for 14 days. No credit card. Cancel any time.