Agent Runtime
Status: Connected
Parsing documentation...
Extracted api references
Generating type definitions...
opensteeropensteer
Y Combinator logoBacked by Y Combinator.

The most comprehensive browser automation framework for AI

Enterprise-grade automation at scale.

Custom plans, unlimited concurrent sessions, dedicated proxies, and advanced support for teams that need more.

+ self-service sso
+ unlimited concurrent sessions
+ custom audit logs
+ advanced captcha bypass
+ dedicated support
view pricing

Simple, transparent pricing.

Start for free, upgrade when you need to scale. Everything you need to build robust AI agents.

Testing & Reliability

Integration Patterns

Production-ready integration patterns for SDK/CLI and cloud execution flows.

Full Workflow: CLI Exploration to Scraper Script

Step 1: Explore and cache with CLI

export OPENSTEER_SESSION=eures-session

opensteer open https://europa.eu/eures/portal/jv-se/home --name "eures-jobs"

opensteer snapshot action
opensteer input 5 "software engineer" --pressEnter --description "the job search input"
opensteer click 12 --description "the search button"

## Wait for results, then extract job listings
opensteer snapshot extraction
opensteer extract '{"jobs":[{"title":{"element":20},"company":{"element":22},"url":{"element":20,"attribute":"href"}},{"title":{"element":35},"company":{"element":37},"url":{"element":35,"attribute":"href"}},{"title":{"element":50},"company":{"element":52},"url":{"element":50,"attribute":"href"}}]}' \
  --description "job listing with title company and url"

## Cache detail page extraction too
opensteer click 20 --description "first job link"
opensteer snapshot extraction
opensteer extract '{"title":{"element":3},"company":{"element":7},"location":{"element":12},"description":{"element":18}}' \
  --description "job detail page"

opensteer close

Step 2: Generate replay script (same namespace, same descriptions)

import { Opensteer } from "opensteer";

async function run() {
  const opensteer = new Opensteer({
    name: "eures-jobs",
    storage: { rootDir: process.cwd() },
  });

  await opensteer.launch({ headless: false });

  try {
    await opensteer.goto("https://europa.eu/eures/portal/jv-se/home");

    await opensteer.input({
      text: "software engineer",
      description: "the job search input",
    });
    await opensteer.click({ description: "the search button" });

    await opensteer.waitForText("Showing 1 to 10");

    // Extract all job listings using cached description — no schema needed
    const listings = await opensteer.extract({
      description: "job listing with title company and url",
    });

    // Visit each detail page and extract using cached description
    for (const job of listings.jobs) {
      await opensteer.goto(job.url);
      await opensteer.waitForText(job.title || "Job details");

      const detail = await opensteer.extract({
        description: "job detail page",
      });
      console.log(JSON.stringify(detail, null, 2));
    }
  } finally {
    await opensteer.close();
  }
}

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

Advanced: API-Based Extraction (uses direct page access)

This is a rare pattern. Only use it when the site has internal REST/GraphQL endpoints and DOM extraction via opensteer.extract() is insufficient.

import { Opensteer } from "opensteer";

async function run() {
  const opensteer = new Opensteer({
    name: "api-scraper",
    storage: { rootDir: process.cwd() },
  });

  await opensteer.launch({ headless: false });

  try {
    // Navigate first to establish session cookies
    await opensteer.goto("https://example.com");

    const data = await opensteer.page.evaluate(async () => {
      const res = await fetch("https://api.example.com/search?q=shoes&limit=100", {
        headers: { "Content-Type": "application/json" },
      });
      return res.json();
    });

    console.log(JSON.stringify(data, null, 2));
  } finally {
    await opensteer.close();
  }
}

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

SDK Rule: For all other data extraction, use opensteer.extract().

Covered Features

  • cli:extract
  • sdk:extract
  • sdk:extractFromPlan