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:
- Open Chrome and switch to the profile (account) you want to use
- In that window, open a new tab and navigate to
chrome://version - Find the Profile Path line
For example, you might see:
Profile Path /Users/yourname/Library/Application Support/Google/Chrome/Profile 2Note 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"
)