All articlesAgentic AI

AI Browser Automation in TypeScript: Debug in Minutes

Browser automation

πŸš€ The Problem Every Developer Faces

You deploy to production. Everything works locally. Then the bug reports start rolling in:

  • β€œThe article won't load”
  • β€œPayment button doesn't appear”
  • β€œDashboard shows empty data”

You spend hours in DevTools, checking logs, reproducing edge cases. What if AI could do this for you?

πŸ€– Enter AI-Powered Browser Automation

Traditional browser automation (Selenium, Puppeteer) requires you to write brittle selectors and step-by-step instructions. But with Stagehand and Browserbase, you simply tell the AI what you want, and it figures out how.

🎭 Meet Stagehand

Stagehand is an AI-powered browser automation framework that uses Large Language Models to interact with web pages intelligently. No more document.querySelector('#btn-submit-form-2023') nightmares.

☁️ Meet Browserbase

Browserbase provides cloud-hosted browsers with:

  • βœ… Zero setup - no Chrome installations
  • βœ… Live session viewing - watch your automation in real-time
  • βœ… Reliable infrastructure - no β€œbrowser crashed” errors
  • βœ… Built for scale - concurrent sessions, global distribution

Together? Pure magic. πŸͺ„

πŸ“– Real-World Example: Debugging a Production Issue

I had an article page that worked perfectly locally but showed nothing in production. Instead of manually checking, I wrote this TypeScript script:

import "dotenv/config";
import { Stagehand } from "@browserbasehq/stagehand";

async function main() {
  // 1️⃣ Initialize Stagehand with Browserbase
  const stagehand = new Stagehand({
    env: "BROWSERBASE",
  });

  await stagehand.init();

  console.log(`Stagehand Session Started`);
  console.log(
    `Watch live: https://browserbase.com/sessions/${stagehand.browserbaseSessionID}`
  );

  const page = stagehand.page;

  // 2️⃣ Navigate to the problem URL
  await page.goto("https://www.loopingagent.com/article/agentic-commerce-protocol");
  console.log("\n=== Page loaded ===\n");

  // 3️⃣ Extract all visible content using AI
  const contentResult = await page.extract(
    "Extract all visible text content on this page, including any error messages, the article title if present, and the main article content."
  );
  console.log("=== Page Content ===");
  console.log(contentResult);
  console.log("\n");

  // 4️⃣ Observe page structure with AI
  const structureResult = await page.observe(
    "What main elements are visible on this page? Is there an article? Are there any error messages or loading indicators?"
  );
  console.log("=== Page Structure ===");
  console.log(structureResult);
  console.log("\n");

  // 5️⃣ Check for specific article content
  const articleCheck = await page.extract(
    "Is there an article about 'agentic commerce' on this page? If yes, extract the first paragraph. If no, describe what you see instead."
  );
  console.log("=== Article Check ===");
  console.log(articleCheck);
  console.log("\n");

  // 6️⃣ Clean up
  await stagehand.close();
}

main().catch((err) => {
  console.error(err);
  process.exit(1);
});

πŸ” What Happened?

In under 2 minutes, the script discovered:

βœ… What was there: Header, navigation, footer, social links
❌ What was missing: The entire article content

Diagnosis: Dynamic routing issue - the page rendered but the content wasn't being fetched at build time.

This would have taken 30+ minutes of manual debugging. The AI did it in seconds.

🎯 The Four AI Superpowers

1. πŸ“€ `extract()` - Read & Scrape Intelligently

const result = await page.extract(
  "Get all product prices and names from this page"
);

No selectors. No DOM traversal. Just natural language.

2. ⚑ `act()` - Perform Actions Like a Human

await page.act("Click the checkout button and proceed to payment");

The AI finds the button, clicks it, and handles any popups or navigation.

3. πŸ‘€ `observe()` - Understand Page State

const elements = await page.observe(
  "What interactive elements are on this page?"
);

Perfect for dynamic content and SPAs.

4. πŸ€– `agent.execute()` - Autonomous Multi-Step Tasks

const agent = stagehand.agent({
  instructions: "You're a shopping assistant."
});

const result = await agent.execute(
  "Find the cheapest laptop under $1000 and add it to cart"
);

The agent browses, compares, and completes complex workflows autonomously.

πŸ› οΈ Getting Started (5 Minutes)

Prerequisites

Setup

# 1. Create project
mkdir my-automation && cd my-automation
pnpm init

# 2. Install dependencies
pnpm add @browserbasehq/stagehand dotenv zod@3.25.67
pnpm add -D tsx typescript

# 3. Create .env file
echo "BROWSERBASE_API_KEY=your_key_here" >> .env
echo "BROWSERBASE_PROJECT_ID=your_project_id" >> .env
echo "OPENAI_API_KEY=your_key_here" >> .env

# 4. Add start script to package.json
{
  "scripts": {
    "start": "tsx index.ts"
  }
}

Important: Zod Version

⚠️ Use Zod 3.25.67 or lower (not v4.x):

{
  "dependencies": {
    "zod": "3.25.67"
  }
}

πŸ’‘ Use Cases

πŸ”Ž Quality Assurance

// Test checkout flow across multiple environments
await page.act("Add item to cart");
await page.act("Proceed to checkout");
const result = await page.observe("Is the payment form visible?");

πŸ“Š Competitive Analysis

// Extract pricing from competitor sites
const prices = await page.extract(
  "Get all pricing tiers with their features"
);

πŸ› Production Debugging

// Reproduce user-reported bugs
const error = await page.extract(
  "Are there any error messages or broken elements?"
);

πŸ“ˆ Web Scraping

// Intelligent data extraction
const data = await page.extract(
  "Extract all job postings with titles, companies, and salaries"
);

πŸŽ“ Key Concepts for TypeScript Developers

Type Safety

Stagehand is fully typed. Extract results can be typed with Zod schemas:

import { z } from "zod";

const ProductSchema = z.object({
  name: z.string(),
  price: z.number(),
  inStock: z.boolean(),
});

const products = await page.extract(
  "Extract all products",
  { schema: ProductSchema }
);
// products is now type-safe!

Async/Await All The Way

Every Stagehand operation returns a Promise. Use async/await:

async function scrapeData() {
  await page.goto(url);
  const data = await page.extract("...");
  return data;
}

Error Handling

Always wrap in try/catch and clean up:

try {
  await stagehand.init();
  // your automation
} catch (error) {
  console.error("Automation failed:", error);
} finally {
  await stagehand.close();
}

🚨 Common Gotchas

1. Concurrent Session Limits

Free Browserbase tier = 1 concurrent session. Always close sessions:

await stagehand.close(); // Or manually in dashboard

2. Interrupted Scripts

Add cleanup handlers:

process.on('SIGINT', async () => {
  await stagehand.close();
  process.exit(0);
});

3. AI Token Costs

Each AI operation costs tokens. Extract wisely:

// ❌ Bad: Multiple extracts
const title = await page.extract("Get title");
const price = await page.extract("Get price");

// βœ… Good: Single extract
const data = await page.extract("Get title and price");

πŸ“š Essential Resources

🎯 The Bottom Line

Before AI: Write brittle selectors, handle edge cases, maintain fragile tests.

With Stagehand + Browserbase: Describe what you want in natural language. Let AI handle the complexity.

Result: Ship faster. Debug smarter. Sleep better. 😴

🏷️ Tags

#BrowserAutomation #TypeScript #AI #Stagehand #Browserbase #WebScraping #Testing #DevTools #Playwright #Selenium #NodeJS #Debugging


Related articles