build(web): replace Playwright MCP with project-scoped Playwright CLI
- feat: add `.agents/skills/playwright-cli/` with complete Skill markdown, agent interface, and 9 reference files covering session management, spec-driven testing, video recording, tracing, storage, request mocking, element attributes, test debugging, and running custom code - feat: add `.playwright/cli.config.json` to configure the Playwright CLI - feat: add `web/package.json` `playwright:cli` script that resolves `playwright cli` from the repo root - build: remove `@playwright/mcp` dependency from `web/package.json` - build: set `XDG_CACHE_HOME` in `mise.toml` - build: delete `.codex/config.toml` (MCP server config) - docs: update `README.md`, `docs/web/roadmap.md`, `docs/web/decisions.md`, and `web/README.md` to reflect the new Playwright CLI approach
This commit is contained in:
@@ -0,0 +1,275 @@
|
||||
# Storage Management
|
||||
|
||||
Manage cookies, localStorage, sessionStorage, and browser storage state.
|
||||
|
||||
## Storage State
|
||||
|
||||
Save and restore complete browser state including cookies and storage.
|
||||
|
||||
### Save Storage State
|
||||
|
||||
```bash
|
||||
# Save to auto-generated filename (storage-state-{timestamp}.json)
|
||||
mise exec -- npm run playwright:cli -- state-save
|
||||
|
||||
# Save to specific filename
|
||||
mise exec -- npm run playwright:cli -- state-save .artifacts/playwright-cli/my-auth-state.json
|
||||
```
|
||||
|
||||
### Restore Storage State
|
||||
|
||||
```bash
|
||||
# Load storage state from file
|
||||
mise exec -- npm run playwright:cli -- state-load .artifacts/playwright-cli/my-auth-state.json
|
||||
|
||||
# Reload page to apply cookies
|
||||
mise exec -- npm run playwright:cli -- open https://example.com
|
||||
```
|
||||
|
||||
### Storage State File Format
|
||||
|
||||
The saved file contains:
|
||||
|
||||
```json
|
||||
{
|
||||
"cookies": [
|
||||
{
|
||||
"name": "session_id",
|
||||
"value": "abc123",
|
||||
"domain": "example.com",
|
||||
"path": "/",
|
||||
"expires": 1893456000,
|
||||
"httpOnly": true,
|
||||
"secure": true,
|
||||
"sameSite": "Lax"
|
||||
}
|
||||
],
|
||||
"origins": [
|
||||
{
|
||||
"origin": "https://example.com",
|
||||
"localStorage": [
|
||||
{ "name": "theme", "value": "dark" },
|
||||
{ "name": "user_id", "value": "12345" }
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Cookies
|
||||
|
||||
### List All Cookies
|
||||
|
||||
```bash
|
||||
mise exec -- npm run playwright:cli -- cookie-list
|
||||
```
|
||||
|
||||
### Filter Cookies by Domain
|
||||
|
||||
```bash
|
||||
mise exec -- npm run playwright:cli -- cookie-list --domain=example.com
|
||||
```
|
||||
|
||||
### Filter Cookies by Path
|
||||
|
||||
```bash
|
||||
mise exec -- npm run playwright:cli -- cookie-list --path=/api
|
||||
```
|
||||
|
||||
### Get Specific Cookie
|
||||
|
||||
```bash
|
||||
mise exec -- npm run playwright:cli -- cookie-get session_id
|
||||
```
|
||||
|
||||
### Set a Cookie
|
||||
|
||||
```bash
|
||||
# Basic cookie
|
||||
mise exec -- npm run playwright:cli -- cookie-set session abc123
|
||||
|
||||
# Cookie with options
|
||||
mise exec -- npm run playwright:cli -- cookie-set session abc123 --domain=example.com --path=/ --httpOnly --secure --sameSite=Lax
|
||||
|
||||
# Cookie with expiration (Unix timestamp)
|
||||
mise exec -- npm run playwright:cli -- cookie-set remember_me token123 --expires=1893456000
|
||||
```
|
||||
|
||||
### Delete a Cookie
|
||||
|
||||
```bash
|
||||
mise exec -- npm run playwright:cli -- cookie-delete session_id
|
||||
```
|
||||
|
||||
### Clear All Cookies
|
||||
|
||||
```bash
|
||||
mise exec -- npm run playwright:cli -- cookie-clear
|
||||
```
|
||||
|
||||
### Advanced: Multiple Cookies or Custom Options
|
||||
|
||||
For complex scenarios like adding multiple cookies at once, use `run-code`:
|
||||
|
||||
```bash
|
||||
mise exec -- npm run playwright:cli -- run-code "async page => {
|
||||
await page.context().addCookies([
|
||||
{ name: 'session_id', value: 'sess_abc123', domain: 'example.com', path: '/', httpOnly: true },
|
||||
{ name: 'preferences', value: JSON.stringify({ theme: 'dark' }), domain: 'example.com', path: '/' }
|
||||
]);
|
||||
}"
|
||||
```
|
||||
|
||||
## Local Storage
|
||||
|
||||
### List All localStorage Items
|
||||
|
||||
```bash
|
||||
mise exec -- npm run playwright:cli -- localstorage-list
|
||||
```
|
||||
|
||||
### Get Single Value
|
||||
|
||||
```bash
|
||||
mise exec -- npm run playwright:cli -- localstorage-get token
|
||||
```
|
||||
|
||||
### Set Value
|
||||
|
||||
```bash
|
||||
mise exec -- npm run playwright:cli -- localstorage-set theme dark
|
||||
```
|
||||
|
||||
### Set JSON Value
|
||||
|
||||
```bash
|
||||
mise exec -- npm run playwright:cli -- localstorage-set user_settings '{"theme":"dark","language":"en"}'
|
||||
```
|
||||
|
||||
### Delete Single Item
|
||||
|
||||
```bash
|
||||
mise exec -- npm run playwright:cli -- localstorage-delete token
|
||||
```
|
||||
|
||||
### Clear All localStorage
|
||||
|
||||
```bash
|
||||
mise exec -- npm run playwright:cli -- localstorage-clear
|
||||
```
|
||||
|
||||
### Advanced: Multiple Operations
|
||||
|
||||
For complex scenarios like setting multiple values at once, use `run-code`:
|
||||
|
||||
```bash
|
||||
mise exec -- npm run playwright:cli -- run-code "async page => {
|
||||
await page.evaluate(() => {
|
||||
localStorage.setItem('token', 'jwt_abc123');
|
||||
localStorage.setItem('user_id', '12345');
|
||||
localStorage.setItem('expires_at', Date.now() + 3600000);
|
||||
});
|
||||
}"
|
||||
```
|
||||
|
||||
## Session Storage
|
||||
|
||||
### List All sessionStorage Items
|
||||
|
||||
```bash
|
||||
mise exec -- npm run playwright:cli -- sessionstorage-list
|
||||
```
|
||||
|
||||
### Get Single Value
|
||||
|
||||
```bash
|
||||
mise exec -- npm run playwright:cli -- sessionstorage-get form_data
|
||||
```
|
||||
|
||||
### Set Value
|
||||
|
||||
```bash
|
||||
mise exec -- npm run playwright:cli -- sessionstorage-set step 3
|
||||
```
|
||||
|
||||
### Delete Single Item
|
||||
|
||||
```bash
|
||||
mise exec -- npm run playwright:cli -- sessionstorage-delete step
|
||||
```
|
||||
|
||||
### Clear sessionStorage
|
||||
|
||||
```bash
|
||||
mise exec -- npm run playwright:cli -- sessionstorage-clear
|
||||
```
|
||||
|
||||
## IndexedDB
|
||||
|
||||
### List Databases
|
||||
|
||||
```bash
|
||||
mise exec -- npm run playwright:cli -- run-code "async page => {
|
||||
return await page.evaluate(async () => {
|
||||
const databases = await indexedDB.databases();
|
||||
return databases;
|
||||
});
|
||||
}"
|
||||
```
|
||||
|
||||
### Delete Database
|
||||
|
||||
```bash
|
||||
mise exec -- npm run playwright:cli -- run-code "async page => {
|
||||
await page.evaluate(() => {
|
||||
indexedDB.deleteDatabase('myDatabase');
|
||||
});
|
||||
}"
|
||||
```
|
||||
|
||||
## Common Patterns
|
||||
|
||||
### Authentication State Reuse
|
||||
|
||||
```bash
|
||||
# Step 1: Login and save state
|
||||
mise exec -- npm run playwright:cli -- open https://app.example.com/login
|
||||
mise exec -- npm run playwright:cli -- snapshot
|
||||
mise exec -- npm run playwright:cli -- fill e1 "user@example.com"
|
||||
mise exec -- npm run playwright:cli -- fill e2 "password123"
|
||||
mise exec -- npm run playwright:cli -- click e3
|
||||
|
||||
# Save the authenticated state
|
||||
mise exec -- npm run playwright:cli -- state-save .artifacts/playwright-cli/auth.json
|
||||
|
||||
# Step 2: Later, restore state and skip login
|
||||
mise exec -- npm run playwright:cli -- state-load .artifacts/playwright-cli/auth.json
|
||||
mise exec -- npm run playwright:cli -- open https://app.example.com/dashboard
|
||||
# Already logged in!
|
||||
```
|
||||
|
||||
### Save and Restore Roundtrip
|
||||
|
||||
```bash
|
||||
# Set up authentication state
|
||||
mise exec -- npm run playwright:cli -- open https://example.com
|
||||
mise exec -- npm run playwright:cli -- eval "() => { document.cookie = 'session=abc123'; localStorage.setItem('user', 'john'); }"
|
||||
|
||||
# Save state to file
|
||||
mise exec -- npm run playwright:cli -- state-save .artifacts/playwright-cli/my-session.json
|
||||
|
||||
# ... later, in a new session ...
|
||||
|
||||
# Restore state
|
||||
mise exec -- npm run playwright:cli -- state-load .artifacts/playwright-cli/my-session.json
|
||||
mise exec -- npm run playwright:cli -- open https://example.com
|
||||
# Cookies and localStorage are restored!
|
||||
```
|
||||
|
||||
## Security Notes
|
||||
|
||||
- Never commit storage state files containing auth tokens
|
||||
- Add `*.auth-state.json` to `.gitignore`
|
||||
- Delete state files after automation completes
|
||||
- Use environment variables for sensitive data
|
||||
- By default, sessions run in-memory mode which is safer for sensitive operations
|
||||
Reference in New Issue
Block a user