Skip to content

Basic Scraper

The smallest useful Autowright script. It’s plain Playwright with one changed import and one config block — everything else is your code.

The script

scraper.ts
import { chromium } from '@autowright/browser';
const browser = await chromium.launch({
headless: true,
autowright: {
scriptId: 'price-scraper', // stable ID for this script
serviceUrl: 'http://localhost:4400', // the coordination service
repoUrl: 'https://github.com/your-org/scrapers', // repo the fixer clones
scriptPath: 'src/scraper.ts', // this file, repo-relative
},
});
const page = await browser.newPage();
await page.goto('https://shop.example.com/deals');
// Extract data with normal locators
const deals = await page.locator('.deal-card').all();
for (const deal of deals) {
const name = await deal.locator('.deal-name').textContent();
const price = await deal.locator('.deal-price').textContent();
console.log(`${name}: ${price}`);
}
await browser.close();

Run it like any other script:

Terminal window
npx tsx scraper.ts

What Autowright adds

Nothing changes on the happy path — the script scrapes and exits. But every run is invisibly recorded: each goto, locator, and textContent call lands in the action log, and the observer keeps rolling screenshots, network requests, and console output.

If .deal-card disappears in a site redesign:

  • The failure is classified SELECTOR_NOT_FOUND and the evidence — the real DOM at failure time, the last screenshots, the action log — is bundled and reported. See Artifacts.
  • The original TimeoutError is re-thrown, so your script exits non-zero exactly as plain Playwright would.
  • The fixer clones your-org/scrapers, finds what replaced .deal-card in the captured DOM, and opens a pull request. See Fix Lifecycle.

Local-only mode

Without repoUrl (or with the stack down), Autowright still writes every failure’s evidence to ./autowright-artifacts/ on local disk — useful as a flight recorder even before you wire up the fixing pipeline.

Next