|
| 1 | +# Browser Automation Setup (install-browser) |
| 2 | + |
| 3 | +> Installed: `support/install-browser.py` |
| 4 | +> Purpose: Install Chrome-for-Testing + agent-browser MCP server |
| 5 | +> Platform: Container environment (Linux) |
| 6 | +
|
| 7 | +--- |
| 8 | + |
| 9 | +## What It Does |
| 10 | + |
| 11 | +`install-browser` sets up browser automation for the LocalPibox stack by: |
| 12 | + |
| 13 | +1. **Downloading Chrome-for-Testing** — fetches the latest stable Chrome from Google's official CDN |
| 14 | +2. **Installing agent-browser** — runs `agent-browser install`, then `install --with-deps` (Playwright dependency resolver) |
| 15 | +3. **Configuring container-safe defaults** — writes container-optimized Chrome launch args |
| 16 | + |
| 17 | +### Why `install-browser` over `agent-browser install` alone |
| 18 | + |
| 19 | +Running `agent-browser install --with-deps` directly downloads a system Chrome and handles deps, but: |
| 20 | + |
| 21 | +- **Slow connections** — the built-in download has a hardcoded timeout that can fail on slow networks |
| 22 | +- **Chrome-for-Testing CDN** — `install-browser` fetches from Google's official CDN (`googlechromelabs.github.io` → `storage.googleapis.com`) with explicit timeouts (30s for version fetch, no hard cap on the download itself) |
| 23 | +- **Exec bit self-healing** — Python's `zipfile.extractall()` drops Unix exec bits; `install-browser` detects and restores them automatically (Chrome crashes at startup if `chrome_crashpad_handler` is not executable) |
| 24 | +- **Container config merging** — writes `~/.agent-browser/config.json` with container-safe launch args, **merged** into any existing config (preserves user customizations) |
| 25 | +- **Version tracking** — installs from the same version JSON API that Playwright uses, keeping Chrome in sync with agent-browser's expectations |
| 26 | +- Visual testing of web apps |
| 27 | +- Browser-based validation (login flows, form submission, UI testing) |
| 28 | +- Capturing screenshots and accessibility audits |
| 29 | +- Testing the pi.dev agent-browser integration |
| 30 | + |
| 31 | +--- |
| 32 | + |
| 33 | +## Installation Process |
| 34 | + |
| 35 | +### Step 1: Chrome Download |
| 36 | + |
| 37 | +``` |
| 38 | +Downloads from: https://googlechromelabs.github.io/chrome-for-testing/ |
| 39 | +Target path: /home/lpb/.agent-browser/browsers/chrome-<version>/ |
| 40 | +``` |
| 41 | + |
| 42 | +- Fetches the latest stable version from Google's version JSON API |
| 43 | +- Extracts `chrome-linux64.zip` to the target directory |
| 44 | +- Restores Unix exec bits (Python's `zipfile.extractall()` drops them) |
| 45 | +- Self-heals existing installs if exec bits were lost |
| 46 | + |
| 47 | +**Chrome executables tracked:** |
| 48 | +- `chrome` — main binary |
| 49 | +- `chrome_crashpad_handler` — crash reporter |
| 50 | +- `headless_shell` — headless mode shell |
| 51 | + |
| 52 | +### Step 2: agent-browser Install |
| 53 | + |
| 54 | +``` |
| 55 | +Runs: agent-browser install → agent-browser install --with-deps |
| 56 | +``` |
| 57 | + |
| 58 | +- Installs the `agent-browser` CLI globally (already installed via npm) |
| 59 | +- Uses Playwright's dependency resolver to install only the exact libraries needed |
| 60 | +- System deps are installed per the downloaded Chrome version |
| 61 | + |
| 62 | +### Step 3: Container Config |
| 63 | + |
| 64 | +``` |
| 65 | +Writes: ~/.agent-browser/config.json |
| 66 | +``` |
| 67 | + |
| 68 | +Container-safe launch args are merged into the config: |
| 69 | +```json |
| 70 | +{ |
| 71 | + "args": "--no-sandbox,--no-first-run,--disable-gpu,--disable-crashpad" |
| 72 | +} |
| 73 | +``` |
| 74 | + |
| 75 | +These args are required because: |
| 76 | +- `--no-sandbox` — Chrome refuses to run as root without it |
| 77 | +- `--no-first-run` — skips the first-run dialog |
| 78 | +- `--disable-gpu` — no GPU in containers |
| 79 | +- `--disable-crashpad` — crash reports can't be sent from containers |
| 80 | + |
| 81 | +The config is **merged** (not replaced) — user customizations are preserved. |
| 82 | + |
| 83 | +### Step 4: Verification |
| 84 | + |
| 85 | +The script verifies: |
| 86 | +- Chrome binary is present and executable |
| 87 | +- `agent-browser` binary is present |
| 88 | +- Chrome reports a valid version string |
| 89 | +- agent-browser reports installed status |
| 90 | + |
| 91 | +--- |
| 92 | + |
| 93 | +## Usage |
| 94 | + |
| 95 | +`install-browser` is installed in the PATH (user-space, no root/sudo needed). |
| 96 | + |
| 97 | +```bash |
| 98 | +install-browser |
| 99 | +``` |
| 100 | + |
| 101 | +### What's Installed |
| 102 | + |
| 103 | +| Component | Path | Version Source | |
| 104 | +|---|---|---| |
| 105 | +| Chrome | `/home/lpb/.agent-browser/browsers/chrome-<ver>/chrome-linux64/chrome` | Google CDN | |
| 106 | +| agent-browser | `/home/lpb/.npm-global/bin/agent-browser` | npm global install | |
| 107 | +| Config | `~/.agent-browser/config.json` | Generated on first run | |
| 108 | + |
| 109 | +### Source Files |
| 110 | + |
| 111 | +| File | Purpose | |
| 112 | +|---|---| |
| 113 | +| `support/install-browser.py` | Python script — main logic | |
| 114 | +| `~/.local/bin/install-browser` | User-space CLI wrapper (in PATH) | |
| 115 | + |
| 116 | +### Self-Healing |
| 117 | + |
| 118 | +If Chrome is extracted without exec bits (e.g., from a broken zip extraction), `install-browser` detects and restores them automatically. The following files are checked: |
| 119 | +- `chrome` |
| 120 | +- `chrome_crashpad_handler` |
| 121 | +- `headless_shell` |
| 122 | + |
| 123 | +--- |
| 124 | + |
| 125 | +## Architecture |
| 126 | + |
| 127 | +``` |
| 128 | +┌─────────────────────────────────────────────────────────────────────┐ |
| 129 | +│ install-browser.py │ |
| 130 | +│ │ |
| 131 | +│ 1. fetch_stable_chrome_version() │ |
| 132 | +│ → GET https://googlechromelabs.github.io/chrome-for-testing/ │ |
| 133 | +│ last-known-good-versions-with-downloads.json │ |
| 134 | +│ │ |
| 135 | +│ 2. install_chrome(cons) │ |
| 136 | +│ → Download chrome-linux64.zip │ |
| 137 | +│ → Extract with mode restoration │ |
| 138 | +│ → Self-heal exec bits if needed │ |
| 139 | +│ │ |
| 140 | +│ 3. install_agent_browser(cons) │ |
| 141 | +│ → Run agent-browser install │ |
| 142 | +│ → Run agent-browser install --with-deps │ |
| 143 | +│ → Merge container-safe args into config.json │ |
| 144 | +│ │ |
| 145 | +│ 4. verify_installation(cons) │ |
| 146 | +│ → Check Chrome binary exists + executable │ |
| 147 | +│ → Run chrome --version │ |
| 148 | +│ → Run agent-browser --version │ |
| 149 | +└─────────────────────────────────────────────────────────────────────┘ |
| 150 | +``` |
| 151 | + |
| 152 | +--- |
| 153 | + |
| 154 | +## Troubleshooting |
| 155 | + |
| 156 | +### Chrome PermissionError (errno 13) |
| 157 | + |
| 158 | +**Symptom:** Chrome crashes on startup with `PermissionError: [Errno 13] Permission denied` |
| 159 | + |
| 160 | +**Cause:** Chrome binary lacks exec bit (Python's `zipfile.extractall()` drops Unix modes) |
| 161 | + |
| 162 | +**Fix:** Re-run `install-browser` — it restores exec bits automatically: |
| 163 | +```bash |
| 164 | +install-browser |
| 165 | +``` |
| 166 | + |
| 167 | +### Chrome Already Installed |
| 168 | + |
| 169 | +The script is idempotent — if Chrome is already present and executable, it skips installation: |
| 170 | +``` |
| 171 | +Chrome already installed at /home/lpb/.agent-browser/browsers/chrome-123.0.6275.0 |
| 172 | +``` |
| 173 | + |
| 174 | +### Missing System Dependencies |
| 175 | + |
| 176 | +If `agent-browser install --with-deps` fails partially, Chrome may work but with reduced functionality. Check: |
| 177 | +```bash |
| 178 | +agent-browser install --with-deps |
| 179 | +``` |
| 180 | + |
| 181 | +### Chrome Version Mismatch |
| 182 | + |
| 183 | +If Chrome version doesn't match Playwright's expectations: |
| 184 | +```bash |
| 185 | +agent-browser install # reinstalls Playwright browsers |
| 186 | +agent-browser install --with-deps # reinstalls system deps |
| 187 | +``` |
| 188 | + |
| 189 | +--- |
| 190 | + |
| 191 | +## Current Status |
| 192 | + |
| 193 | +| Component | Status | Version | |
| 194 | +|---|---|---| |
| 195 | +| Chrome | ✅ Installed | Latest stable (auto-updated) | |
| 196 | +| agent-browser | ✅ Installed | Via npm global | |
| 197 | +| Config | ✅ Generated | Container-safe args merged | |
| 198 | +| MCP Server | ✅ Ready | `agent-browser` MCP available | |
| 199 | + |
| 200 | +**Last verified:** 2026-08-25 |
0 commit comments