Cookbook

Practical recipes for building browser automations with InverseUI. Learn how to use the Recording SDK and leverage persistent profiles.

Handling Credentials & Login Sessions

One of the biggest challenges in browser automation is managing logins across multiple sites. Instead of hardcoding credentials or re-authenticating for every run, use persistent browser profiles to log in once and reuse those sessions across all your InverseUI automations.

Option 1: Persistent Profile

Use a persistent browser profile for your project. On the first run, log into the sites you need (GitHub, LinkedIn, internal tools…). All sessions are saved and reused in subsequent runs.

First run: Browser opens → log into any sites you need → sessions saved to .inverseui/profile

Subsequent runs: Already logged in, automation runs immediately.

import asyncio
from pathlib import Path
from playwright.async_api import async_playwright

PROFILE_DIR = Path(".inverseui/profile")

async def main():
    async with async_playwright() as p:
        ctx = await p.chromium.launch_persistent_context(
            user_data_dir=str(PROFILE_DIR),
            headless=False,
        )
        page = ctx.pages[0] if ctx.pages else await ctx.new_page()

        # Navigate to job application
        await page.goto("https://jobs.ashbyhq.com/openai/.../application")

        # Fill location field with autocomplete
        location_input = page.locator("//div[@id='form']/.../input")
        await location_input.fill("Munich")
        await page.locator("#floating-ui-1 [role='option']").first.click()

        # Select date from picker
        date_input = page.locator("//div[@id='form']/.../input")
        await date_input.click()
        await page.locator("div.react-datepicker__month [role='option']", has_text="26").first.click()

        await ctx.close()

if __name__ == "__main__":
    asyncio.run(main())

Option 2: Attach to an Existing Chrome

Use your own Chrome with all your login sessions, extensions, and cookies. Start it with a debugging port, then let Playwright attach and drive that exact browser. Perfect for debugging and power users who want to leverage existing authenticated sessions.

Step 1: Find your Chrome profile path

First, identify which Chrome profile contains the login sessions you want to use:

  1. Open Chrome and switch to the profile (account) you want to use
  2. In that window, open a new tab and navigate to chrome://version
  3. Find the Profile Path line

For example, you might see:

Profile Path    /Users/yourname/Library/Application Support/Google/Chrome/Profile 2

Note the folder name at the end (e.g., Profile 2). This is your profile directory.

Step 2: Copy your profile (one-time setup)

Chrome doesn't allow remote debugging on the default data directory. Copy your profile to a new location:

# macOS
mkdir -p "$HOME/inverseui"
cp -R "$HOME/Library/Application Support/Google/Chrome/Profile 2" "$HOME/inverseui/Profile 2"

# Linux
mkdir -p "$HOME/inverseui"
cp -R "$HOME/.config/google-chrome/Profile 2" "$HOME/inverseui/Profile 2"

# Windows (PowerShell)
mkdir "$env:USERPROFILE\inverseui"
Copy-Item -Recurse "$env:LOCALAPPDATA\Google\Chrome\User Data\Profile 2" "$env:USERPROFILE\inverseui\Profile 2"

Replace Profile 2 with your actual profile folder name from Step 1.

Step 3: Start Chrome with debugging enabled

Launch Chrome pointing to your copied profile with remote debugging enabled:

# macOS
/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome \
  --remote-debugging-port=9222 \
  --user-data-dir="$HOME/inverseui" \
  --profile-directory="Profile 2"

# Linux
google-chrome \
  --remote-debugging-port=9222 \
  --user-data-dir="$HOME/inverseui" \
  --profile-directory="Profile 2"

# Windows (cmd)
"C:\Program Files\Google\Chrome\Application\chrome.exe" ^
  --remote-debugging-port=9222 ^
  --user-data-dir="%USERPROFILE%\inverseui" ^
  --profile-directory="Profile 2"

What these flags do:

  • --remote-debugging-port=9222 — Enables the Chrome DevTools Protocol for Playwright to connect
  • --user-data-dir — Points to the directory containing your copied profile
  • --profile-directory — Specifies which profile folder to use (with all your logins, cookies, and extensions)

Step 4: Attach with Playwright

# attach_existing.py
import asyncio
from playwright.async_api import async_playwright

CDP_URL = "http://localhost:9222"

async def main():
    async with async_playwright() as p:
        browser = await p.chromium.connect_over_cdp(CDP_URL)
        ctx = browser.contexts[0] if browser.contexts else await browser.new_context()
        page = ctx.pages[0] if ctx.pages else await ctx.new_page()

        # Already logged in to whatever sites you used in that Chrome
        await page.goto("https://example.com")
        # ... InverseUI-generated steps ...

        # ⚠ don't browser.close(), that would kill your Chrome

if __name__ == "__main__":
    asyncio.run(main())

Recording SDK

Launch Chrome and capture interactions entirely from Python—no manual extension clicks needed. Control when recording starts and stops directly from your automation scripts (Playwright, Selenium, etc.) to capture user interactions and build reusable workflows.

Setup

First, ensure you have the InverseUI Chrome extension installed and your authentication token configured.

Configuration

# config.py
EXTENSION_PATH = "/path/to/InverseUI-Chrome-Extension/"
EXTENSION_ID = "your_extension_id"

# Your authentication token
INVERSEUI_AUTH_TOKEN = "your_auth_token_here"
INVERSEUI_AUTH_COOKIE = {
    "domain": ".inverseui.com",
    "name": "inverseui_auth_token",
    "value": INVERSEUI_AUTH_TOKEN,
    "path": "/",
    "secure": True,
    "httpOnly": False,
    "sameSite": "strict"
}

Starting a Recording

Control when to start recording browser actions from your Python automation script.

from selenium import webdriver
from selenium.webdriver.chrome.service import Service
import time

# Set up Chrome with InverseUI extension
options = webdriver.ChromeOptions()
options.add_argument(f'--load-extension=${EXTENSION_PATH}')
options.add_argument('--disable-blink-features=AutomationControlled')

driver = webdriver.Chrome(service=Service(), options=options)

# Add authentication cookie
driver.get("https://inverseui.com")
driver.add_cookie(INVERSEUI_AUTH_COOKIE)

# Start recording via extension API
driver.execute_script("""
    chrome.runtime.sendMessage(
        '${EXTENSION_ID}',
        { action: 'START_RECORDING' },
        (response) => { console.log('Recording started:', response); }
    );
""")

time.sleep(2)  # Wait for recording to start

# Your automation code here
driver.get("https://example.com")
# ... perform actions ...

Stopping Recording & Fetching Actions

After your automation completes, stop the recording and retrieve all captured actions.

# Stop the recording
driver.execute_script("""
    chrome.runtime.sendMessage(
        '${EXTENSION_ID}',
        { action: 'STOP_RECORDING' },
        (response) => { console.log('Recording stopped:', response); }
    );
""")

time.sleep(1)

# Fetch captured actions
actions = driver.execute_script("""
    return new Promise((resolve) => {
        chrome.runtime.sendMessage(
            '${EXTENSION_ID}',
            { action: 'GET_ACTIONS' },
            (response) => { resolve(response); }
        );
    });
""")

# Process the captured actions
if actions and 'actions' in actions:
    for action in actions['actions']:
        print(f"Action: ${action['browserAction']}")
        print(f"  Timestamp: ${action['timestamp']}")
        print(f"  XPath: ${action.get('xpath', 'N/A')}")
        print(f"  Content: ${action.get('content', 'N/A')}")
        print()

InverseUI Python Library

Coming Soon

The InverseUI Python SDK makes it easy to work with recorded automations programmatically.

Planned Features

  • Call Recorded Functions: Execute your recorded browser automations as simple Python functions
  • AI Agent Mode: Install with pip install inverseui[agent] for autonomous agent capabilities
  • Seamless Integration: Works alongside your existing Playwright, Selenium, or custom automation code

Preview of planned API:

from inverseui import InverseUI

# Initialize client
client = InverseUI(api_key="your_api_key")

# Call a recorded automation as a function
result = client.call_function(
    "search_airbnb_room",
    city="San Francisco",
    guests=2
)

# Or with AI agent capabilities
from inverseui.agent import Agent

agent = Agent(api_key="your_api_key")
result = agent.run(
    "Find and book the cheapest hotel in NYC for next weekend"
)