A coding agent could develop this repo's Go packages and could not develop the application: every path to running YellowJacket ended in a blocking GTK window, so 265 bound methods, 46 events, 33 component directories and 13 stores had exactly one form of verification available — `tsc --noEmit`. The unlock is that `wails dev`'s dev server on :34115 serves the real frontend with the real generated bindings against the same Go backend a desktop window attaches to, so a plain Chromium under Xvfb gets a fully functional app. Four test tiers now exist, cheapest first: - `make ui-test` — 313 Vitest tests in a real browser in ~2 s, no app, no backend, no display. Works because `frontend/wailsjs/` is a pure passthrough to `window.go`/`window.runtime`, so faking just those two globals runs the real bindings and the real store code. - `make test` — services in-process, asserting on the payload the frontend would receive, via a new `events.Emit` wrapper. - `make dev-headless` + `playwright-cli` — the real app, driven interactively, with an event bridge on `window.__yjEvents` and a dev-only control surface at `/__test/`. - `make e2e` — 19 of those flows frozen as Playwright specs. `events.Emit(ctx, …)` replaces all 35 direct `runtime.EventsEmit` call sites: wails' `getEvents` `log.Fatalf`s on any context without its runtime, so those paths could not run under test and a background worker could take the app down. Four packages had each hand-rolled the same guard; nine more guarded on `ctx != nil`, which does not help. `TestNoDirectRuntimeEmits` fails the build on a new one. Fixtures are generated, not committed (`make testdata`), and seeds are built by *running the app* — never by hand-writing config and DB rows, which would be a second description of a valid YJ_HOME. `.gitea/workflows/ci.yml` is the first workflow here that tests anything; the other three only package, so `gitea_ci` reported only packaging jobs and misled anyone asking whether a push was healthy. Both jobs were prototyped to green in a bare ubuntu:24.04 container before the YAML was written, which immediately caught `make lint` linting three configurations that nothing builds: all three passes omitted `webkit2_41`, so wails resolved webkit2gtk-4.0 — which Arch still ships and Ubuntu 24.04 dropped. Operational instructions live in `.pi/skills/yellowjacket-dev/`, measured discoveries in `.planning/NOTES.md`, and architecture in `CLAUDE.md` — split by tense, not by topic, because a topical split gives every new fact two plausible homes. `make skill-check` fails a commit if the skill cites a make target that does not exist.
226 lines
5.5 KiB
Markdown
226 lines
5.5 KiB
Markdown
# Browser Session Management
|
|
|
|
Run multiple isolated browser sessions concurrently with state persistence.
|
|
|
|
## Named Browser Sessions
|
|
|
|
Use `-s` flag to isolate browser contexts:
|
|
|
|
```bash
|
|
# Browser 1: Authentication flow
|
|
playwright-cli -s=auth open https://app.example.com/login
|
|
|
|
# Browser 2: Public browsing (separate cookies, storage)
|
|
playwright-cli -s=public open https://example.com
|
|
|
|
# Commands are isolated by browser session
|
|
playwright-cli -s=auth fill e1 "user@example.com"
|
|
playwright-cli -s=public snapshot
|
|
```
|
|
|
|
## Browser Session Isolation Properties
|
|
|
|
Each browser session has independent:
|
|
- Cookies
|
|
- LocalStorage / SessionStorage
|
|
- IndexedDB
|
|
- Cache
|
|
- Browsing history
|
|
- Open tabs
|
|
|
|
## Browser Session Commands
|
|
|
|
```bash
|
|
# List all browser sessions
|
|
playwright-cli list
|
|
|
|
# Stop a browser session (close the browser)
|
|
playwright-cli close # stop the default browser
|
|
playwright-cli -s=mysession close # stop a named browser
|
|
|
|
# Stop all browser sessions
|
|
playwright-cli close-all
|
|
|
|
# Forcefully kill all daemon processes (for stale/zombie processes)
|
|
playwright-cli kill-all
|
|
|
|
# Delete browser session user data (profile directory)
|
|
playwright-cli delete-data # delete default browser data
|
|
playwright-cli -s=mysession delete-data # delete named browser data
|
|
```
|
|
|
|
## Environment Variable
|
|
|
|
Set a default browser session name via environment variable:
|
|
|
|
```bash
|
|
export PLAYWRIGHT_CLI_SESSION="mysession"
|
|
playwright-cli open example.com # Uses "mysession" automatically
|
|
```
|
|
|
|
## Common Patterns
|
|
|
|
### Concurrent Scraping
|
|
|
|
```bash
|
|
#!/bin/bash
|
|
# Scrape multiple sites concurrently
|
|
|
|
# Start all browsers
|
|
playwright-cli -s=site1 open https://site1.com &
|
|
playwright-cli -s=site2 open https://site2.com &
|
|
playwright-cli -s=site3 open https://site3.com &
|
|
wait
|
|
|
|
# Take snapshots from each
|
|
playwright-cli -s=site1 snapshot
|
|
playwright-cli -s=site2 snapshot
|
|
playwright-cli -s=site3 snapshot
|
|
|
|
# Cleanup
|
|
playwright-cli close-all
|
|
```
|
|
|
|
### A/B Testing Sessions
|
|
|
|
```bash
|
|
# Test different user experiences
|
|
playwright-cli -s=variant-a open "https://app.com?variant=a"
|
|
playwright-cli -s=variant-b open "https://app.com?variant=b"
|
|
|
|
# Compare
|
|
playwright-cli -s=variant-a screenshot
|
|
playwright-cli -s=variant-b screenshot
|
|
```
|
|
|
|
### Persistent Profile
|
|
|
|
By default, browser profile is kept in memory only. Use `--persistent` flag on `open` to persist the browser profile to disk:
|
|
|
|
```bash
|
|
# Use persistent profile (auto-generated location)
|
|
playwright-cli open https://example.com --persistent
|
|
|
|
# Use persistent profile with custom directory
|
|
playwright-cli open https://example.com --profile=/path/to/profile
|
|
```
|
|
|
|
## Attaching to a Running Browser
|
|
|
|
Use `attach` to connect to a browser that is already running, instead of launching a new one.
|
|
|
|
### Attach by channel name
|
|
|
|
Connect to a running Chrome or Edge instance by its channel name. The browser must have remote debugging enabled — navigate to `chrome://inspect/#remote-debugging` in the target browser and check "Allow remote debugging for this browser instance".
|
|
|
|
```bash
|
|
# Attach to Chrome
|
|
playwright-cli attach --cdp=chrome
|
|
|
|
# Attach to Chrome Canary
|
|
playwright-cli attach --cdp=chrome-canary
|
|
|
|
# Attach to Microsoft Edge
|
|
playwright-cli attach --cdp=msedge
|
|
|
|
# Attach to Edge Dev
|
|
playwright-cli attach --cdp=msedge-dev
|
|
```
|
|
|
|
Supported channels: `chrome`, `chrome-beta`, `chrome-dev`, `chrome-canary`, `msedge`, `msedge-beta`, `msedge-dev`, `msedge-canary`.
|
|
|
|
When `--session` is not provided, the session is named after the channel (e.g. `--cdp=msedge` creates a session called `msedge`), so parallel attaches to Chrome and Edge don't collide on `default`. Pass `--session=<name>` to override.
|
|
|
|
### Attach via CDP endpoint
|
|
|
|
Connect to a browser that exposes a Chrome DevTools Protocol endpoint:
|
|
|
|
```bash
|
|
playwright-cli attach --cdp=http://localhost:9222
|
|
```
|
|
|
|
### Attach via browser extension
|
|
|
|
Connect to a browser with the Playwright extension installed:
|
|
|
|
```bash
|
|
playwright-cli attach --extension
|
|
```
|
|
|
|
### Detach
|
|
|
|
Tear down an attached session without affecting the external browser:
|
|
|
|
```bash
|
|
# Detach the default attached session
|
|
playwright-cli detach
|
|
|
|
# Detach a specific attached session
|
|
playwright-cli -s=msedge detach
|
|
```
|
|
|
|
`detach` only works on sessions created via `attach`. For sessions created via `open`, use `close`.
|
|
|
|
## Default Browser Session
|
|
|
|
When `-s` is omitted, commands use the default browser session:
|
|
|
|
```bash
|
|
# These use the same default browser session
|
|
playwright-cli open https://example.com
|
|
playwright-cli snapshot
|
|
playwright-cli close # Stops default browser
|
|
```
|
|
|
|
## Browser Session Configuration
|
|
|
|
Configure a browser session with specific settings when opening:
|
|
|
|
```bash
|
|
# Open with config file
|
|
playwright-cli open https://example.com --config=.playwright/my-cli.json
|
|
|
|
# Open with specific browser
|
|
playwright-cli open https://example.com --browser=firefox
|
|
|
|
# Open in headed mode
|
|
playwright-cli open https://example.com --headed
|
|
|
|
# Open with persistent profile
|
|
playwright-cli open https://example.com --persistent
|
|
```
|
|
|
|
## Best Practices
|
|
|
|
### 1. Name Browser Sessions Semantically
|
|
|
|
```bash
|
|
# GOOD: Clear purpose
|
|
playwright-cli -s=github-auth open https://github.com
|
|
playwright-cli -s=docs-scrape open https://docs.example.com
|
|
|
|
# AVOID: Generic names
|
|
playwright-cli -s=s1 open https://github.com
|
|
```
|
|
|
|
### 2. Always Clean Up
|
|
|
|
```bash
|
|
# Stop browsers when done
|
|
playwright-cli -s=auth close
|
|
playwright-cli -s=scrape close
|
|
|
|
# Or stop all at once
|
|
playwright-cli close-all
|
|
|
|
# If browsers become unresponsive or zombie processes remain
|
|
playwright-cli kill-all
|
|
```
|
|
|
|
### 3. Delete Stale Browser Data
|
|
|
|
```bash
|
|
# Remove old browser data to free disk space
|
|
playwright-cli -s=oldsession delete-data
|
|
```
|