Effortlessly generate automated browser tests using natural language commands. Let AI handle the tedious parts of testing so you can focus on building.
- ⚡ Automated Test Generation — Describe your test in plain English, and watch it come to life.
- 🌐 Browser Automation — Uses Playwright to interact with real web pages.
- 🕷 (Coming later) Site Crawling — Generate tests for entire websites (still in progress).
$ npx init playwright@latest
$ npm install --global iiw
$ cat "your openai api key" > .env
Just describe your test case in plain language, and iiw will handle the rest.
$ iiw "go to google flights and book a flight to paris"
The AI will open a browser and walk through the steps to complete your task. You’ll see the browser in action, automating clicks, inputs, and navigation.
Example output
const { chromium } = require('playwright');
(async () => {
const browser = await chromium.launch({
headless: false
});
const context = await browser.newContext();
const page = await context.newPage();
await page.locator('body').click();
await page.goto('https://consent.google.com/m?continue=https://www.google.com/travel/flights&gl=DK&m=0&pc=flt&cm=2&hl=en-US&src=1');
await page.getByRole('button', { name: 'Accept all' }).click();
await page.getByRole('combobox', { name: 'Where to?' }).fill('Paris');
await page.locator('div').filter({ hasText: /^Paris, France$/ }).first().click();
await page.getByRole('textbox', { name: 'Departure' }).click();
await page.getByRole('button', { name: 'Saturday, February 22, 2025' }).click();
await page.getByRole('button', { name: 'Sunday, March 23, 2025 , 1886' }).click();
await page.getByRole('button', { name: 'Done. Search for round trip' }).click();
await page.getByRole('button', { name: 'Search' }).click();
await page.getByRole('button', { name: 'Flight details. Leaves Billund Airport at 6:30 AM on Saturday, February 22 and arrives at Paris Charles de Gaulle Airport at 10:30 AM on Saturday, February 22.', exact: true }).click();
await page.getByRole('button', { name: 'Select flight' }).click();
// ---------------------
await context.close();
await browser.close();
})();
Not quite perfect yet, but a little bit of post processing should make this work great.
Rerun the test.
$ npx playwright test generated.spec.ts
$ iiw --crawl news.ycombinator.com "skip the login functionality"
The idea here is that we can crawl a site to extract all the functinality it has. This should output a long list of detailed natural language test cases that can then each be run with the test case runner above.