.agents/skills/browse/SKILL.md
Playwright-powered browser automation and E2E testing for SolanaOS Hub. Covers test configuration, agent-driven test generation (planner/generator/healer), NanoHub route testing, Convex API validation, wallet flow testing, IPFS Hub verification, and CI/CD integration. Use when asked about E2E tests, browser automation, Playwright setup, NanoHub testing, visual regression, or Hub route verification.
npx skillsauth add x402agent/solana-clawd browseInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Browser automation and end-to-end testing skill for the SolanaOS NanoHub, powered by Playwright.
# Install Playwright browsers
npx playwright install chromium
# Run E2E tests
bun run test:e2e
# Run with UI mode
npx playwright test --ui
# Generate tests interactively
npx playwright codegen https://seeker.solanaos.net
The NanoHub uses a dual config setup:
playwright.config.ts)Browser-based E2E tests against the built frontend.
import { defineConfig, devices } from '@playwright/test'
export default defineConfig({
testDir: './e2e',
testMatch: /.*\.pw\.test\.ts/,
timeout: 60_000,
expect: { timeout: 10_000 },
fullyParallel: true,
retries: process.env.CI ? 2 : 0,
use: {
baseURL: process.env.PLAYWRIGHT_BASE_URL || 'http://127.0.0.1:4173',
trace: 'retain-on-failure',
},
webServer: {
command: 'bun run preview -- --host 127.0.0.1 --port 4173',
url: 'http://127.0.0.1:4173',
reuseExistingServer: !process.env.CI,
},
projects: [
{ name: 'chromium', use: { ...devices['Desktop Chrome'] } },
],
})
vitest.e2e.config.ts)Node-based E2E tests for CLI and API validation (no browser needed).
bun vitest run -c vitest.e2e.config.ts
| Route | Auth | What to verify |
|-------|------|----------------|
| / | No | Landing page renders, navigation works |
| /launch | No | Boot sequence animation, CTA links |
| /mobile | No | Seeker mobile walkthrough renders |
| /skills | No | Skill cards load from Convex |
| /souls | No | Soul cards load from Convex |
| /ipfs | No | IPFS Hub page renders, wallet input works |
| /agents | No | Agent directory loads public agents |
| /dashboard | Yes | Wallet connect, agent factory, pairing |
| /upload | Yes | Skill publish flow with file upload |
| /settings | Yes | User preferences, agent config |
| /mining | No | BitAxe fleet dashboard renders |
| /strategy | No | Strategy builder loads |
| /create | Yes | Skill creator wizard |
| /auth/callback | No | GitHub OAuth redirect handling |
import { test, expect } from '@playwright/test'
test('IPFS Hub page loads', async ({ page }) => {
await page.goto('/ipfs')
await expect(page.locator('h1')).toContainText('Private IPFS')
await expect(page.locator('.gallery-stat-card')).toHaveCount(4)
})
test('agent directory shows cards', async ({ page }) => {
await page.goto('/agents')
await expect(page.locator('h1')).toContainText('Registered')
// Wait for Convex query
await page.waitForSelector('.agent-card', { timeout: 10_000 })
})
test('skill search works', async ({ page }) => {
await page.goto('/skills')
await page.locator('input[type="search"]').fill('solanaos')
await page.waitForSelector('.skill-card')
await expect(page.locator('.skill-card')).toHaveCount.greaterThan(0)
})
import { test, expect } from '@playwright/test'
// Use storage state from auth setup
test.use({ storageState: 'e2e/.auth/user.json' })
test('dashboard loads for authenticated user', async ({ page }) => {
await page.goto('/dashboard')
await expect(page.locator('.dashboard-section')).toBeVisible()
})
import { describe, expect, it } from 'vitest'
const CONVEX_URL = process.env.CONVEX_URL || 'https://artful-frog-940.convex.cloud'
describe('Convex IPFS API', () => {
it('GET /api/v1/ipfs/files returns array', async () => {
const res = await fetch(
`${CONVEX_URL}/api/v1/ipfs/files?wallet=test`,
{ headers: { Accept: 'application/json' } }
)
expect(res.ok).toBe(true)
const data = await res.json()
expect(data).toHaveProperty('files')
expect(Array.isArray(data.files)).toBe(true)
})
it('GET /api/v1/ipfs/stats returns stats object', async () => {
const res = await fetch(
`${CONVEX_URL}/api/v1/ipfs/stats?wallet=test`,
{ headers: { Accept: 'application/json' } }
)
expect(res.ok).toBe(true)
const data = await res.json()
expect(data.stats).toHaveProperty('totalFiles')
})
})
Playwright includes three built-in AI test agents.
npx playwright init-agents --loop=vscode
Explores the app and produces a Markdown test plan.
Input: "Generate a test plan for the IPFS Hub upload and recall flow"
Output: specs/ipfs-hub.md
The planner needs a seed test that sets up the environment:
// tests/seed.spec.ts
import { test } from '@playwright/test'
test('seed', async ({ page }) => {
await page.goto('/')
})
Transforms Markdown plans into executable Playwright test files.
Input: specs/ipfs-hub.md
Output: tests/ipfs-hub/upload-file.spec.ts
Automatically repairs failing tests by:
Input: "Heal tests/ipfs-hub/upload-file.spec.ts"
Output: Passing test (or skipped with reason)
| Option | Description |
|--------|-------------|
| testDir | Directory with test files |
| testMatch | Glob/regex for test file matching |
| testIgnore | Glob/regex for files to skip |
| timeout | Per-test timeout (default: 30s) |
| retries | Retry count for flaky tests |
| workers | Parallel worker count |
| fullyParallel | Run all tests in parallel |
| forbidOnly | Fail if test.only found (CI) |
| reporter | Output format: list, html, json, dot |
| outputDir | Artifacts directory (screenshots, videos, traces) |
| globalSetup | Path to setup script (runs before all tests) |
| globalTeardown | Path to teardown script (runs after all tests) |
| webServer | Auto-start dev server before tests |
use Options| Option | Description |
|--------|-------------|
| baseURL | Base URL for page.goto('/') |
| storageState | Pre-populated auth state |
| trace | Trace capture: off, on, retain-on-failure, on-first-retry |
| screenshot | Screenshot capture: off, on, only-on-failure |
| video | Video recording: off, on, retain-on-failure |
| headless | Run without browser UI (default: true) |
| viewport | Browser viewport size |
| locale | User locale emulation |
| colorScheme | light or dark mode |
| geolocation | GPS coordinate emulation |
| permissions | Browser permission grants |
| offline | Simulate offline mode |
| proxy | HTTP proxy settings |
| extraHTTPHeaders | Headers sent with every request |
| actionTimeout | Timeout per action (click, fill, etc.) |
| testIdAttribute | Custom test ID attribute |
// Skip a test
test.skip('not ready', async ({ page }) => {})
// Mark as expected failure
test.fail('known bug', async ({ page }) => {})
// Mark as slow (3x timeout)
test.slow()
// Tag for filtering
test('login @smoke', async ({ page }) => {})
test('checkout', { tag: ['@e2e', '@slow'] }, async ({ page }) => {})
// Run tagged tests
// npx playwright test --grep @smoke
// npx playwright test --grep-invert @slow
# Run all tests
npx playwright test
# Run specific file
npx playwright test e2e/ipfs-hub.pw.test.ts
# Run by title match
npx playwright test -g "IPFS Hub"
# Run with browser visible
npx playwright test --headed
# Debug mode (inspector + slow)
npx playwright test --debug
# Interactive UI mode
npx playwright test --ui
# Generate test code interactively
npx playwright codegen https://seeker.solanaos.net
# View last test report
npx playwright show-report
# View trace file
npx playwright show-trace test-results/trace.zip
# Only re-run failures
npx playwright test --last-failed
# Shard across CI workers
npx playwright test --shard=1/3
# .github/workflows/e2e.yml
name: E2E Tests
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: oven-sh/setup-bun@v2
- run: bun install
- run: npx playwright install --with-deps chromium
- run: bun run build
- run: npx playwright test
- uses: actions/upload-artifact@v4
if: failure()
with:
name: playwright-report
path: playwright-report/
| Variable | Description |
|----------|-------------|
| PLAYWRIGHT_BASE_URL | Override base URL (skip local server) |
| PLAYWRIGHT_PORT | Override preview server port (default: 4173) |
| CLAWHUB_E2E_TOKEN | API token for authenticated CLI tests |
| CLAWDHUB_E2E_TOKEN | Alias for above |
| CLAWHUB_REGISTRY | Registry URL override |
| CLAWHUB_SITE | Site URL override |
| CI | Enables retries, single worker, forbidOnly |
development
Formally verify programs by writing Lean 4 proofs. Trigger this skill whenever the user wants to formally verify code, generate Lean 4 proofs, prove properties about algorithms or smart contracts, verify invariants, convert program logic into formal specifications, or anything involving Lean 4 and formal verification. Also trigger when the user mentions "qedgen", "lean proof", "formal proof", "verify my code", "prove correctness", "formal verification", or wants mathematical guarantees about their implementation.
data-ai
Orchestrate multi-bot trading swarms on Pump.fun with persona-driven agents
tools
End-to-end Solana development playbook (Jan 2026). Prefer Solana Foundation framework-kit (@solana/client + @solana/react-hooks) for React/Next.js UI. Prefer @solana/kit for all new client/RPC/transaction code. When legacy dependencies require web3.js, isolate it behind @solana/web3-compat (or @solana/web3.js as a true legacy fallback). Covers wallet-standard-first connection (incl. ConnectorKit), Anchor/Pinocchio programs, Codama-based client generation, LiteSVM/Mollusk/Surfpool testing, and security checklists.
tools
Buy and sell tokens on Pump.fun bonding curves and AMM pools