Files
app-store-optimization/skills/go-playwright/SKILL.md
8hoursking d6fd03cea7 Create SKILL.md for Playwright Go Automation
Added comprehensive guidelines for using Playwright Go for browser automation, including architecture, logging, error handling, and stealth techniques.
2026-02-10 10:56:11 +03:00

6.4 KiB
Raw Blame History

name, description
name description
playwright-go-automation Expert capability for robust, stealthy, and efficient browser automation using Playwright Go.

Playwright Go Automation Expert

Overview

This skill provides a comprehensive framework for writing high-performance, production-grade browser automation scripts using github.com/playwright-community/playwright-go. It enforces architectural best practices (contexts over instances), robust error handling, structured logging (Zap), and advanced human-emulation techniques to bypass anti-bot systems.

When to Use This Skill

  • Use when the user asks to "scrape," "automate," or "test" a website using Go.
  • Use when the target site has complex dynamic content (SPA, React, Vue) requiring a real browser.
  • Use when the user mentions "stealth," "avoiding detection," "cloudflare," or "human-like" behavior.
  • Use when debugging existing Playwright scripts.

Strategic Implementation Guidelines

1. Architecture: Contexts vs. Browsers

CRITICAL: Never launch a new Browser instance for every task.

  • Pattern: Launch the Browser once (singleton). Create a new BrowserContext for each distinct session or task.
  • Why: Contexts are lightweight and created in milliseconds. Browsers take seconds to launch.
  • Isolation: Contexts provide complete isolation (cookies, cache, storage) without the overhead of a new process.

2. Logging & Observability

  • Library: Use go.uber.org/zap exclusively.
  • Rule: Do not use fmt.Println.
  • Modes:
    • Dev: zap.NewDevelopment() (Console friendly)
    • Prod: zap.NewProduction() (JSON structured)
  • Traceability: Log every navigation, click, and input with context fields (e.g., logger.Info("clicking button", zap.String("selector", sel))).

3. Error Handling & Stability

  • Graceful Shutdown: Always use defer to close Pages, Contexts, and Browsers.
  • Panic Recovery: Wrap critical automation routines in a safe runner that recovers panics and logs the stack trace.
  • Timeouts: Never rely on default timeouts. Set explicit timeouts (e.g., playwright.PageClickOptions{Timeout: playwright.Float(5000)}).

4. Stealth & Human-Like Behavior

To bypass anti-bot systems (Cloudflare, Akamai), the generated code must imitate human physiology:

  • Non-Linear Mouse Movement: Never teleport the mouse. Implement a helper that moves the mouse along a Bezier curve with random jitter.
  • Input Latency: never use Fill(). Use Type() with random delays between keystrokes (50ms200ms).
  • Viewport Randomization: Randomize the viewport size slightly (e.g., 1920x1080 ± 15px) to avoid fingerprinting.
  • Behavioral Noise: Randomly scroll, focus/unfocus the window, or hover over irrelevant elements ("idling") during long waits.
  • User-Agent: Rotate User-Agents for every new Context.

5. Documentation Usage

  • Primary Source: Rely on your internal knowledge of the API first to save tokens.
  • Fallback: Refer to the official docs playwright-go documentation ONLY if:
    • You encounter an unknown error.
    • You need to implement complex network interception or authentication flows.
    • The API has changed significantly.

Code Examples

Standard Initialization (Headless + Zap)

package main

import (
    "[github.com/playwright-community/playwright-go](https://github.com/playwright-community/playwright-go)"
    "go.uber.org/zap"
    "log"
)

func main() {
    // 1. Setup Logger
    logger, _ := zap.NewDevelopment()
    defer logger.Sync()

    // 2. Start Playwright Driver
    pw, err := playwright.Run()
    if err != nil {
        logger.Fatal("could not start playwright", zap.Error(err))
    }
    
    // 3. Launch Browser (Singleton)
    // Use Headless: false and SlowMo for Debugging
    browser, err := pw.Chromium.Launch(playwright.BrowserTypeLaunchOptions{
        Headless: playwright.Bool(false), 
        SlowMo:   playwright.Float(100), // Slow actions by 100ms for visibility
    })
    if err != nil {
        logger.Fatal("could not launch browser", zap.Error(err))
    }
    defer browser.Close() // Graceful cleanup

    // 4. Create Isolated Context (Session)
    context, err := browser.NewContext(playwright.BrowserNewContextOptions{
        UserAgent: playwright.String("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)..."),
        Viewport: &playwright.Size{Width: 1920, Height: 1080},
    })
    if err != nil {
        logger.Fatal("could not create context", zap.Error(err))
    }
    defer context.Close()

    // 5. Open Page
    page, _ := context.NewPage()
    
    // ... Implementation ...
}

Human-Like Typing & Interaction

import (
    "math/rand"
    "time"
)

// HumanType simulates a user typing with variable speed
func HumanType(locator playwright.Locator, text string) {
    // Focus the element first (like a human)
    locator.Click()
    
    for _, char := range text {
        // Random delay: 50ms to 150ms
        delay := time.Duration(rand.Intn(100) + 50) * time.Millisecond
        time.Sleep(delay)
        locator.Press(string(char))
    }
}

// HumanClick adds offset and hesitation
func HumanClick(page playwright.Page, selector string) {
    box, _ := page.Locator(selector).BoundingBox()
    if box == nil {
        return
    }
    
    // Calculate center with random offset (jitter)
    x := box.X + box.Width/2 + (rand.Float64()*10 - 5)
    y := box.Y + box.Height/2 + (rand.Float64()*10 - 5)
    
    // Move mouse smoothly (requires custom Bezier implementation or steps)
    page.Mouse().Move(x, y, playwright.MouseMoveOptions{Steps: playwright.Int(10)})
    time.Sleep(100 * time.Millisecond) // Hesitate
    page.Mouse().Click(x, y)
}

#Session Management (Save/Load Cookies)

func SaveSession(context playwright.BrowserContext, filepath string) {
    cookies, _ := context.Cookies()
    // Serialize cookies to JSON and write to 'filepath'
}

func LoadSession(context playwright.BrowserContext, filepath string) {
    // Read JSON from 'filepath' and deserialize
    // var cookies []playwright.Cookie
    context.AddCookies(cookies)
}

Summary Checklist for Agent

  • Is Debug Mode on? -> Headless=false, SlowMo=100+.
  • Is it a new user identity? -> Create NewContext, apply new Proxy, rotate User-Agent.
  • Is the action critical? -> Wrap in SafeAction with zap logging.
  • Is the target guarded (Cloudflare/Akamai)? -> Enable HumanType, BezierMouse, and Stealth Scripts.