Source profileQuality 93/100

librefang/librefang/crates/librefang-runtime/tests/fixtures/registry/hands/browser/SKILL.md

browser-automation

Playwright-based browser automation patterns for autonomous web interaction

Source repository stars
361
Declared platforms
0
Static risk flags
0
Last source update
2026-08-25
Source checked
2026-08-25

Decision brief

What it does: where it fits

Playwright-based browser automation patterns for autonomous web interaction

Best for

    Not for

    • Tasks that require unconfirmed production actions or broad system permissions.
    • Environments where the pinned source and install steps cannot be inspected.

    Compatibility matrix

    Platform support, with evidence labels

    PlatformStatusEvidenceWhat to check
    CodexNot declaredNo explicit evidencePortability before use
    Claude CodeNot declaredNo explicit evidencePortability before use
    CursorNot declaredNo explicit evidencePortability before use
    Gemini CLINot declaredNo explicit evidencePortability before use
    Open the compatibility checker

    Installation

    Inspect first. Install second.

    The source command is displayed only when detected. A safe inspection prompt is always available so your agent can explain every action before execution.

    Source-detected install commandSource
    npx skills add https://github.com/librefang/librefang --skill "crates/librefang-runtime/tests/fixtures/registry/hands/browser"
    Safe inspection promptEditorial

    Inspect the Agent Skill "browser-automation" from https://github.com/librefang/librefang/blob/b0078ea302bffdb6582823acdaa99372b1fdda8f/crates/librefang-runtime/tests/fixtures/registry/hands/browser/SKILL.md at commit b0078ea302bffdb6582823acdaa99372b1fdda8f. List every install step, command, network request, credential, file read/write, external action, and rollback step. Explain whether it fits my task. Do not install or execute anything until I approve.

    Workflow

    What the source asks the agent to do

    1. 01

      Multi-Step Forms (Wizards)

      Review the “Multi-Step Forms (Wizards)” section in the pinned source before continuing.

      Review and apply the “Multi-Step Forms (Wizards)” source section.
    2. 02

      Playwright CSS Selector Reference

      Review the “Playwright CSS Selector Reference” section in the pinned source before continuing.

      Review and apply the “Playwright CSS Selector Reference” source section.
    3. 03

      Basic Selectors

      Review the “Basic Selectors” section in the pinned source before continuing.

      Review and apply the “Basic Selectors” source section.
    4. 04

      Form Selectors

      Review the “Form Selectors” section in the pinned source before continuing.

      Review and apply the “Form Selectors” source section.
    5. 05

      Navigation Selectors

      Review the “Navigation Selectors” section in the pinned source before continuing.

      Review and apply the “Navigation Selectors” source section.

    Permission review

    Static risk signals and limitations

    No configured static risk pattern was detected

    This is not proof of safety. Runtime behavior, indirect dependencies, and hidden external systems are outside the static scan.

    Evidence record

    Why each signal appears

    EvidenceSourceComputedTestedEditorial
    SignalValueEvidence typeMeaning
    Quality score93/100ComputedDocumentation, specificity, maintenance, and trust rules
    Repository stars361SourceRepository attention, not individual Skill quality
    Compatibility0 platformsSourceDeclared in the catalog source record
    Usage guideautomated source guideEditorialGenerated or reviewed according to the visible evidence level

    Pinned source

    Provenance and original SKILL.md

    Repository
    librefang/librefang
    Skill path
    crates/librefang-runtime/tests/fixtures/registry/hands/browser/SKILL.md
    Commit
    b0078ea302bffdb6582823acdaa99372b1fdda8f
    License
    MIT
    Collected
    2026-08-25
    Default branch
    main
    View the original SKILL.md

    Browser Automation Skill

    Playwright CSS Selector Reference

    Basic Selectors

    SelectorDescriptionExample
    #idBy ID#checkout-btn
    .classBy class.add-to-cart
    tagBy elementbutton, input
    [attr=val]By attribute[data-testid="submit"]
    tag.classCombinedbutton.primary
    parent childDescendantdiv.container button
    parent > childDirect childul > li
    :nth-child(n)Nth elementli:nth-child(2)
    :first-childFirst elementul > li:first-child
    :last-childLast elementul > li:last-child
    [attr*=val]Attribute contains[class*="price"]
    [attr^=val]Attribute starts with[href^="https"]
    [attr$=val]Attribute ends with[href$=".pdf"]
    :not(sel)Negationbutton:not(.disabled)
    sel1, sel2Multiple selectors#submit, button[type="submit"]

    Form Selectors

    SelectorUse Case
    input[type="email"]Email fields
    input[type="password"]Password fields
    input[type="search"]Search boxes
    input[name="q"]Google/search query
    textareaMulti-line text areas
    select[name="country"]Dropdown menus
    input[type="checkbox"]Checkboxes
    input[type="radio"]Radio buttons
    button[type="submit"]Submit buttons
    input[type="file"]File upload fields
    input[type="date"]Date pickers
    input[type="tel"]Phone number fields
    input[autocomplete="cc-number"]Credit card fields
    [contenteditable="true"]Rich text editors

    Navigation Selectors

    SelectorUse Case
    a[href*="cart"]Cart links
    a[href*="checkout"]Checkout links
    a[href*="login"]Login links
    nav aNavigation menu links
    .breadcrumb aBreadcrumb links
    [role="navigation"] aARIA nav links
    a[href*="account"]Account/profile links
    a[href*="register"], a[href*="signup"]Registration links
    header a[href="/"]Logo/home link
    footer aFooter links

    E-commerce Selectors

    SelectorUse Case
    .product-price, [data-price]Product prices
    .add-to-cart, #add-to-cartAdd to cart buttons
    .cart-total, .order-totalCart total
    .quantity, input[name="quantity"]Quantity selectors
    .checkout-btn, #checkoutCheckout buttons
    [data-product-id]Product identifiers
    .product-title, h1.product-nameProduct names
    .product-image img, [data-zoom-image]Product images
    .star-rating, [data-rating]Review ratings
    .in-stock, .availabilityStock status
    select[name="size"], .size-selectorSize selectors
    [data-variant], .color-swatchVariant selectors

    Generic Selector Strategies (Priority Order)

    Use selectors that are resilient to UI redesigns. Prefer semantic and accessibility-based selectors over class names.

    Tier 1 — Test Attributes (most stable)

    SelectorDescription
    [data-testid="value"]Explicit test ID — survives refactors
    [data-test="value"]Alternative test attribute convention
    [data-cy="value"]Cypress test attribute
    [data-qa="value"]QA-specific test attribute

    Tier 2 — Accessibility Attributes

    SelectorDescription
    [aria-label="Search"]Accessible name, framework-agnostic
    [aria-labelledby="id"]References a labelling element
    [role="button"]ARIA role — semantic intent
    [role="link"]ARIA link role
    [role="textbox"]ARIA textbox role
    [role="dialog"]Modals and popups
    [role="navigation"]Navigation landmarks
    [role="search"]Search landmarks
    [aria-expanded="true"]Open dropdowns/menus
    [aria-selected="true"]Selected tabs/options
    [aria-checked="true"]Checked checkboxes/radios
    [aria-disabled="true"]Disabled elements (do not click)

    Tier 3 — Semantic HTML

    SelectorDescription
    button[type="submit"]Form submit buttons
    input[name="fieldname"]Form fields by name
    input[type="email"]Email input by type
    label[for="fieldid"]Label linked to input
    nav aNavigation links
    main, article, sectionContent landmarks
    header, footerPage structure
    h1, h2, h3Headings for orientation

    Tier 4 — ID and Visible Text

    StrategyWhen to use
    #unique-idWhen ID is human-readable and stable
    Visible text contentWhen no good attribute selectors exist
    a:has-text("Sign In")Playwright-specific text matching

    Tier 5 — Class Selectors (least stable)

    RiskPattern
    Low risk.btn-primary, .nav-link (design-system classes)
    Medium risk.header-search-input (component-specific)
    High risk.css-1a2b3c, .sc-fAbCdE (auto-generated by CSS-in-JS)

    Rule: Never rely on auto-generated class names (random strings like .css-xyz123). These change on every build.

    Accessibility-Based Interaction Patterns

    Modern web apps expose accessibility attributes that are more stable than CSS classes.

    Finding Interactive Elements by Role

    Buttons:     [role="button"], button
    Links:       [role="link"], a[href]
    Text inputs: [role="textbox"], input[type="text"], textarea
    Checkboxes:  [role="checkbox"], input[type="checkbox"]
    Radio:       [role="radio"], input[type="radio"]
    Comboboxes:  [role="combobox"] (autocomplete/typeahead fields)
    Tabs:        [role="tab"] (tab navigation)
    Menus:       [role="menu"], [role="menuitem"]
    Dialogs:     [role="dialog"], [role="alertdialog"]
    

    Reading Page Structure via Landmarks

    [role="banner"]       → site header (logo, global nav)
    [role="navigation"]   → navigation sections
    [role="main"]         → primary page content
    [role="search"]       → search functionality
    [role="contentinfo"]  → footer (copyright, legal links)
    [role="complementary"] → sidebar content
    [role="form"]         → form regions
    

    Label-Based Field Identification

    Instead of guessing input selectors, find labels first:
    1. browser_read_page → look for label text (e.g., "Email Address")
    2. Use: label:has-text("Email") + input  (sibling)
       Or:  input[aria-label="Email Address"]
       Or:  #<id-from-label-for-attribute>
    

    SPA Framework Detection & Handling

    Detecting the Framework

    SignalFrameworkNotes
    <div id="root"> or <div id="__next">React / Next.jsContent rendered client-side
    <div id="app"> with data-v- attributesVue.js / Nuxtdata-v-xxxxx are scoped style markers
    <app-root> or custom element tagsAngularUses web component-like tags
    <div id="svelte"> or compiled class namesSvelte / SvelteKitMinimal runtime footprint
    URL contains #/ hash routingAny SPAClient-side routing via hash
    __NEXT_DATA__ script tagNext.jsServer-side rendering with hydration
    __NUXT__ or __NUXT_DATA__ in pageNuxt.jsVue SSR framework

    Framework-Specific Interaction Tips

    React apps:

    • State updates are batched — wait 500ms-2s after interactions for re-renders
    • Look for data-testid attributes (common in React Testing Library projects)
    • Portal-rendered content (modals, tooltips) may be at the end of <body>, not nested in the component tree
    • React-Select dropdowns: click the container, then look for [class*="option"] in the menu that appears

    Vue apps:

    • v-if elements may not exist in DOM until conditions are met — re-read page after state changes
    • Vue transitions: wait for CSS transitions to complete before interacting
    • Vuetify/Element UI components have predictable class prefixes (.v-btn, .el-input)

    Angular apps:

    • Elements often have _ngcontent- or _nghost- attributes (do not use these as selectors — they change per build)
    • Angular Material components: use [role] and [aria-label] attributes instead of classes
    • Forms may use reactive validation — errors appear only after interaction (blur event)

    General SPA rules:

    • After clicking a navigation element, wait 1-3 seconds before reading the page
    • If content is missing, check for loading indicators: .loading, .spinner, [aria-busy="true"], .skeleton
    • Retry browser_read_page up to 3 times with 2-second intervals before giving up
    • URL changes without full page reload confirm SPA routing — do not expect browser_navigate events

    Site-Specific Selector Patterns

    These are reference selectors for common sites. They change frequently — always verify with browser_read_page if a selector fails, then construct a fresh selector from the live DOM.

    Google Search

    ElementSelector
    Search inputinput[name="q"], textarea[name="q"]
    Search buttoninput[name="btnK"], button[type="submit"]
    Result titlesh3 (within #search)
    Result links#search a[href^="http"]
    "Next" paginationa#pnnext

    Amazon

    ElementSelector
    Search input#twotabsearchtextbox
    Search button#nav-search-submit-button
    Add to cart#add-to-cart-button
    Quantity dropdown#quantity
    Cart count#nav-cart-count

    GitHub

    ElementSelector
    Searchinput[name="q"]
    Repository name[itemprop="name"] a
    Star buttonbutton[aria-label*="Star"]
    Submit buttonbutton[type="submit"]

    Note: When a saved selector fails, use browser_read_page to discover the current DOM, then build a new selector from live content. Prefer [data-testid], [aria-label], or visible text over fragile class-based selectors.


    Common Workflows

    Product Search & Purchase

    1. browser_navigate → store homepage
    2. browser_type → search box with product name
    3. browser_click → search button or press Enter
    4. browser_read_page → scan results
    5. browser_click → desired product
    6. browser_read_page → verify product details & price
    7. browser_click → "Add to Cart"
    8. browser_navigate → cart page
    9. browser_read_page → verify cart contents & total
    10. STOP → Report to user, wait for approval
    11. browser_click → "Proceed to Checkout" (only after approval)
    

    Account Login

    1. browser_navigate → login page
    2. browser_read_page → identify form fields and any CAPTCHA
    3. browser_type → email/username field
    4. browser_type → password field
    5. browser_click → login/submit button
    6. browser_read_page → verify successful login (check for dashboard/profile elements)
    7. If MFA required → inform user, wait for code input
    

    Form Submission

    1. browser_navigate → form page
    2. browser_read_page → understand form structure
    3. browser_type → fill each field sequentially
    4. browser_click → checkboxes/radio buttons as needed
    5. browser_screenshot → visual verification before submit
    6. browser_click → submit button
    7. browser_read_page → verify confirmation
    

    Price Comparison

    1. For each store:
       a. browser_navigate → store URL
       b. browser_type → search query
       c. browser_read_page → extract prices
       d. memory_store → save price data
    2. memory_recall → compare all prices
    3. Report findings to user
    

    Multi-Page Data Extraction

    1. browser_navigate → starting page
    2. browser_read_page → extract data from current page
    3. memory_store → save extracted data
    4. Check for pagination:
       a. browser_click → "Next" button or page number link
       b. browser_read_page → verify new page loaded (check for changed content)
       c. Repeat from step 2
    5. If no more pages → compile and report results
    

    Account Registration

    1. browser_navigate → registration page
    2. browser_read_page → identify required fields
    3. browser_type → fill name, email, password fields sequentially
    4. browser_click → accept terms checkbox (if required)
    5. browser_screenshot → verify all fields before submission
    6. browser_click → submit/register button
    7. browser_read_page → check for:
       - Success page → registration complete
       - Email verification prompt → inform user
       - Validation errors → read errors, correct fields, retry
    

    File Download Monitoring

    1. browser_navigate → page with download link
    2. browser_read_page → identify download button/link
    3. browser_click → download trigger
    4. browser_read_page → check for download confirmation or redirect
    5. If download requires additional steps (accept terms, choose format):
       a. browser_click → required selections
       b. browser_click → final download button
    6. Report download status to user
    

    Wait Strategies & Timing

    When to Wait

    Proper waiting prevents most automation failures. Never use fixed sleep times when a condition-based wait is possible.

    ScenarioStrategyNotes
    Page navigationWait for load eventbrowser_navigate handles this automatically
    After clicking linkRead page to confirm new contentCheck for expected elements on destination
    AJAX/dynamic contentRe-read page after delaySome SPAs load content asynchronously
    Form submissionRead page for confirmationCheck for success message or redirect
    Slow networksRetry with backoff3s, 6s, 12s intervals
    Animation/transitionBrief pause before interactionModal fade-in, dropdown expansion

    Detecting Page Load Completion

    After browser_navigate or browser_click that triggers navigation:
    1. browser_read_page → check if expected content is present
    2. If content missing → wait 2-3 seconds → browser_read_page again
    3. If still missing after 3 retries → page may have changed structure
    4. Use browser_screenshot to visually confirm page state
    

    SPA (Single Page Application) Handling

    SPAs (React, Angular, Vue, Svelte) do not trigger traditional page loads. Client-side routing means the browser URL changes but no network navigation occurs.

    1. browser_click → triggers route change (URL updates but no page reload)
    2. browser_read_page → may return stale content from previous view
    3. Check for loading indicators in the output:
       - Text: "Loading...", "Please wait", skeleton placeholders
       - Attributes: [aria-busy="true"]
       - Classes: .loading, .spinner, .skeleton, .placeholder
    4. If loading detected OR content stale → wait 2 seconds
    5. browser_read_page → retry (attempt 2 of 3)
    6. If still stale → wait 3 seconds → browser_read_page (attempt 3 of 3)
    7. If content never updates:
       a. browser_screenshot → check if content is visually present but not captured as text
       b. The content may be inside an iframe or shadow DOM — try alternative access
       c. Report the issue to the user with the screenshot
    

    Iframe Content Access

    When target content is inside an iframe:
    1. browser_read_page → look for <iframe> elements and their src attributes
    2. browser_navigate → directly to the iframe src URL (if same-origin)
    3. Interact with the content normally
    4. browser_navigate → back to the parent page when done
    Note: Cross-origin iframes may block direct access. Inform the user if this occurs.
    

    Shadow DOM Awareness

    Web components using shadow DOM hide their internals from normal CSS selectors:
    1. If a known element is not found by any selector, suspect shadow DOM
    2. browser_screenshot → visually confirm the element exists on the page
    3. Try interacting via visible text content (may pierce shadow boundaries)
    4. If interaction fails, inform the user that the element is inside a shadow root
    

    Error Recovery Strategies

    Error Recovery Decision Tree

    When any interaction fails, walk through this decision tree top-to-bottom:

    INTERACTION FAILED
    │
    ├─ Is this the correct page?
    │  ├─ NO → browser_read_page to check URL
    │  │       ├─ Redirected to login? → re-authenticate, then retry
    │  │       ├─ Redirected to error page? → handle HTTP error (see below)
    │  │       └─ Wrong page entirely? → browser_navigate to correct URL
    │  └─ YES ↓
    │
    ├─ Is an overlay blocking the element?
    │  ├─ YES → dismiss overlay (cookie banner, modal, chat widget)
    │  │        then retry the original interaction
    │  └─ NO ↓
    │
    ├─ Does the element exist in the DOM?
    │  ├─ NO → page may not have finished rendering
    │  │       ├─ Wait 2 seconds → browser_read_page → retry (up to 3 times)
    │  │       ├─ Scroll the page to trigger lazy loading → retry
    │  │       ├─ Try alternative selectors (see priority order below)
    │  │       └─ Still not found? → browser_screenshot → report to user
    │  └─ YES ↓
    │
    ├─ Is the element visible and interactive?
    │  ├─ Disabled ([disabled], [aria-disabled="true"]) → inform user, cannot interact
    │  ├─ Hidden (display:none, off-screen) → may be inside collapsed section, try expanding
    │  ├─ Covered by another element → identify and dismiss the covering element
    │  └─ YES ↓
    │
    ├─ Did the click/type register?
    │  ├─ NO → JavaScript may not have attached handlers yet
    │  │       ├─ Wait 2 seconds → retry
    │  │       ├─ Try clicking a more specific child element
    │  │       └─ Try clicking by visible text instead of CSS selector
    │  └─ YES ↓
    │
    └─ Did the expected state change occur?
       ├─ NO → SPA may need time to re-render
       │       ├─ Wait 2-3 seconds → browser_read_page to verify
       │       ├─ Check for loading indicators ([aria-busy], .spinner)
       │       └─ After 3 retries, browser_screenshot → report to user
       └─ YES → continue to next step
    

    Selector Fallback Order

    When the primary selector fails, try alternatives in this order:

    1. [data-testid="..."], [data-test="..."], [data-cy="..."]  — test attributes
    2. [aria-label="..."], [role="button"]                       — accessibility
    3. Visible text content: a:has-text("Sign In")               — human-readable
    4. input[name="..."], input[type="..."]                      — form semantics
    5. #id                                                        — unique ID
    6. [class*="keyword"]                                         — partial class match (last resort)
    

    Quick Reference

    ErrorRecovery
    Element not foundWalk selector fallback order, scroll page, screenshot
    Page timeoutRetry URL once, try base domain, report to user
    Login requiredInform user, ask for credentials
    CAPTCHAScreenshot and inform user — cannot solve
    Pop-up/modalDismiss first, then retry original action
    Cookie consentClick "Accept All" or dismiss banner
    Rate limited (429)Wait 30s, retry; after 3 failures, stop and report
    Session expiredDetect login redirect, re-authenticate, resume
    Wrong pageVerify URL, navigate back or to correct page
    Empty SPA contentWait 3-5s for render, retry read up to 3 times

    Navigation Failure Recovery

    1. Timeout on browser_navigate:
       a. Retry the same URL once
       b. If still fails, check if URL is valid (no typos, correct protocol)
       c. Try simplified URL (remove query params, try base domain)
       d. Report connectivity issue to user
    
    2. Unexpected redirect:
       a. browser_read_page → check current URL and content
       b. If redirected to login → handle login flow
       c. If redirected to error page → report the error code and message
       d. If redirected to different page → assess if it is relevant, otherwise navigate back
    
    3. HTTP errors observed in page content:
       - 403 Forbidden → site may be blocking automation, inform user
       - 404 Not Found → URL is stale or incorrect, try searching for the correct page
       - 429 Too Many Requests → wait 60 seconds, retry with longer intervals
       - 500/502/503 → server issue, retry after 30 seconds (max 3 retries)
    

    Stale Element Recovery (SPA-Specific)

    Elements become stale when the page re-renders — common in React, Vue, and Angular:

    1. Identify the stale interaction (click that produced no result or error)
    2. browser_read_page → get fresh DOM snapshot
    3. Check if the element's selector still matches in the new DOM
    4. If not, construct a new selector from the fresh page content
    5. Retry the interaction with the updated selector
    6. If element has moved, use browser_screenshot to find its new location
    

    Pop-up and Overlay Dismissal

    Order of priority when overlays block interaction:
    1. Cookie consent banners:
       - Selectors: [aria-label*="cookie" i] button, #onetrust-accept-btn-handler
       - Text: "Accept All", "Accept Cookies", "Agree", "OK", "Got it"
       - Fallback: .cookie-banner .close, #cookie-close, [aria-label="Close"]
    
    2. Newsletter/subscription modals:
       - Selectors: [role="dialog"] [aria-label="Close"], .modal .close, button.dismiss
       - Fallback: press Escape key (via browser_type on body element)
    
    3. Chat widgets:
       - Usually do not block (z-index layer); if blocking, click minimize/close
    
    4. Age verification gates:
       - Click "Yes" / "I am over 18" / "Enter"
       - May need to select a birth date from dropdowns
    
    5. App install banners:
       - Look for "Continue in browser", "Not now", or close/dismiss buttons
    
    6. Browser-level permission prompts:
       - Auto-dismissed by Playwright context settings
    

    Anti-Detection Techniques

    Behavioral Patterns

    Automation detection looks for non-human interaction patterns. Mitigate by:

    1. TIMING: Do not interact instantly after page load
       - Wait 1-3 seconds before first interaction
       - Insert 0.5-2 second gaps between form field entries
       - Vary timing (not perfectly uniform intervals)
    
    2. NAVIGATION: Follow natural browsing patterns
       - Visit homepage before deep URLs when possible
       - Click through navigation instead of using direct URLs
       - Scroll before interacting with below-the-fold content
    
    3. INPUT: Simulate realistic behavior
       - Type character by character (browser_type handles this)
       - Click buttons rather than submitting forms programmatically
       - Do not fill hidden honeypot fields (see below)
       - Do not request pages faster than 1 per 3 seconds on the same domain
    

    Honeypot Field Detection

    Do NOT fill fields that have:
      - style="display: none" or style="visibility: hidden"
      - class="hidden", class="d-none", class="sr-only"
      - type="hidden" (unless it is a legitimate CSRF token or form ID)
      - Position: absolute with left: -9999px (off-screen placement)
    
    Use browser_read_page to inspect field visibility before filling.
    

    Screenshot & Content Extraction

    When to Take Screenshots

    SituationPurpose
    Before form submissionVisual verification of filled data
    After login attemptConfirm success or capture error state
    When element not foundSee actual page state for debugging
    Price/product comparisonVisual record for user
    CAPTCHA encounteredShow user what needs solving
    Before financial transactionProof of cart/payment details
    Unexpected page stateDiagnose navigation or rendering issues

    Content Extraction Patterns

    Tables:  browser_read_page → identify table boundaries → parse rows/columns → memory_store
    Data:    browser_read_page → search for labels ("Price:", "In Stock", "Rating:") → extract adjacent values
    Dynamic: browser_read_page → if "Loading..." or skeleton → wait 2-3s → retry
    Scroll:  extract visible data → scroll down → browser_read_page → repeat until complete (max 10 cycles)
    

    Form Filling & Interaction Sequences

    Dropdown / Select Menus

    Standard HTML <select>:
      browser_click → the <select> element to open it
      browser_click → the <option> with desired value
    
    Custom dropdown (div-based):
      1. browser_click → the dropdown trigger element (.dropdown-toggle, .select-wrapper)
      2. browser_read_page → find the dropdown options that appeared
      3. browser_click → the desired option from the expanded list
    

    Date Pickers

    Native HTML date input (input[type="date"]):
      browser_type → the date value in YYYY-MM-DD format directly into the input
    
    Custom calendar widget:
      1. browser_click → date input to open calendar
      2. browser_click → month/year navigation arrows to reach target month
      3. browser_click → the target day cell
      4. browser_read_page → verify selected date
    

    File Uploads

    Standard file input (input[type="file"]):
      - Playwright can set file input values directly
      - Not always available via browser_type — inform user if upload needed
    
    Drag-and-drop upload zones:
      - Usually have a fallback "Browse files" button/link
      - browser_click → "Browse" or "Choose file" fallback button
    

    Multi-Step Forms (Wizards)

    1. browser_read_page → identify current step and total steps
    2. Fill current step fields with browser_type and browser_click
    3. browser_click → "Next" / "Continue" button
    4. browser_read_page → verify progression to next step
    5. If validation error appears:
       a. browser_read_page → identify error messages
       b. Fix the flagged fields
       c. browser_click → "Next" again
    6. Repeat until final step
    7. browser_screenshot → capture summary/review page
    8. STOP → get user approval before final submission
    

    Autocomplete / Typeahead Fields

    1. browser_type → partial text into the input field
    2. Wait 1-2 seconds for suggestion dropdown to appear
    3. browser_read_page → check if suggestions loaded
    4. browser_click → the desired suggestion from the dropdown
    5. browser_read_page → verify the field populated correctly
    

    Checkbox and Radio Button Groups

    Checkboxes (multi-select):
      browser_click → each desired checkbox
      Use browser_read_page to check current state ([checked] attribute)
      Do NOT click already-checked boxes unless intending to uncheck
    
    Radio buttons (single-select):
      browser_click → the desired option
      Only one can be active — clicking a new one deselects the previous
    

    Multi-Tab and Popup Handling

    Links That Open New Tabs

    When browser_click opens a new tab (target="_blank" links):
    1. The new tab becomes the active context
    2. browser_read_page → verify content in new tab
    3. Complete actions in the new tab
    4. browser_close → close the new tab to return to the original
    5. browser_read_page → verify original tab is still in expected state
    

    Authentication Popups (OAuth, SSO)

    OAuth/Social login flows often open a popup:
    1. browser_click → "Sign in with Google/GitHub/etc."
    2. New popup/tab opens with the provider's login page
    3. browser_type → credentials in the popup
    4. browser_click → authorize/allow button
    5. Popup closes automatically, original page refreshes
    6. browser_read_page → verify login success on original page
    

    Multiple Window Coordination

    When workflow requires information from multiple pages:
    1. Open first page → extract needed data → memory_store
    2. browser_navigate → second page (replaces current)
    3. Extract data from second page → memory_store
    4. Use memory_recall to combine data from both sources
    5. browser_navigate → return to original page if needed
    
    Avoid keeping multiple tabs open simultaneously when possible —
    single-tab workflows are more reliable and predictable.
    

    Cookie and Session Management

    Session Persistence

    Playwright browser sessions persist cookies within a single session:
    - Logging in once is enough for subsequent navigations to the same site
    - Cookies expire when the browser context is closed (browser_close)
    - For long workflows, periodically verify session is still active:
      1. browser_navigate → a page that requires authentication
      2. browser_read_page → check for login page redirect
      3. If redirected to login → session expired, re-authenticate
    

    Cookie Consent Handling

    Most sites display cookie banners on first visit. Handle immediately:
    1. browser_read_page → check for cookie banner presence
    2. Look for accept buttons with these common selectors:
       - #cookie-accept, #accept-cookies, #onetrust-accept-btn-handler
       - button[data-action="accept"], .cookie-consent .accept
       - Text content: "Accept All", "Accept Cookies", "I Agree", "OK"
    3. browser_click → the accept button
    4. browser_read_page → verify banner dismissed
    5. If banner persists → try clicking the close/X button instead
    

    Geo-Restricted Content

    When content varies by location:
    1. browser_read_page → check for location selection prompts
    2. If location selector present:
       a. browser_click → country/region dropdown
       b. browser_click → desired country/region
       c. browser_read_page → verify content updated for selected region
    3. Some sites redirect to country-specific domains (.co.uk, .de, etc.)
       - Navigate directly to the correct country domain
    

    Performance Optimization

    Minimizing Page Reads

    browser_read_page is the most expensive operation (returns full page text).
    Optimize by:
    1. Use browser_read_page once after navigation, extract ALL needed data
    2. Use browser_screenshot for quick visual checks instead of full reads
    3. After clicking a button, only read the page if you need to verify
       the result or extract new data
    4. Cache page content in memory_store if you will reference it later
    

    Efficient Navigation

    1. Use direct URLs when possible instead of click-through navigation:
       BAD:  homepage → click "Products" → click "Electronics" → click "Phones"
       GOOD: browser_navigate → /products/electronics/phones
    
    2. Use URL patterns for pagination:
       If page 1 is /results?page=1, go directly to /results?page=5
       instead of clicking "Next" five times
    
    3. Combine operations:
       Instead of: navigate → read → navigate → read → navigate → read
       Use: navigate → read + extract all → navigate next → read + extract all
    

    Handling Lazy-Loaded Content

    Many modern sites load content as the user scrolls (infinite scroll):
    1. browser_read_page → get initially loaded content
    2. If you need more items:
       a. browser_click → a far-down element to trigger scroll loading
       b. Wait 2-3 seconds for new content to render
       c. browser_read_page → extract newly loaded content
       d. Repeat until sufficient data collected
    3. Set a maximum iteration count (e.g., 10 scroll cycles)
       to prevent infinite loops on endlessly scrolling pages
    

    Rate Limiting Awareness

    Respect site rate limits to avoid IP blocks:
    - Space requests to same domain by at least 2-3 seconds
    - If you receive a 429 error or see "Too many requests":
      1. Wait 30-60 seconds before next request
      2. Double the wait time on each subsequent 429
      3. After 3 consecutive 429s, inform user and stop
    - Watch for soft rate limiting signals:
      - CAPTCHA appearing mid-session
      - Results becoming empty or different
      - Redirect to a "verify you are human" page
    

    Common Failure Modes & Debugging

    Diagnosis Checklist

    When an interaction fails, check in this order:

    1. CORRECT PAGE?
       browser_read_page → confirm you are on the expected URL/page
    
    2. ELEMENT EXISTS?
       browser_read_page → search output for the target element's text or nearby text
    
    3. ELEMENT VISIBLE?
       browser_screenshot → check if element is visible (not behind overlay, not off-screen)
    
    4. ELEMENT BLOCKED?
       Look for cookie banners, modals, chat widgets covering the element
    
    5. ELEMENT INTERACTIVE?
       Check if element is disabled, greyed out, or read-only
    
    6. PAGE FULLY LOADED?
       Look for loading indicators in page content (spinner text, "Loading...")
    
    7. SESSION VALID?
       Check if you have been redirected to a login page
    

    Common Failure Patterns

    Clicking does nothing:

    Causes:
      - Element is covered by an overlay (cookie banner, modal)
      - Element is outside the viewport (needs scroll)
      - Element is disabled or has pointer-events: none
      - JavaScript click handler has not attached yet (page still loading)
      - Clicking on a wrapper div instead of the actual button
    
    Fixes:
      1. Dismiss any overlays first
      2. Scroll to the element before clicking
      3. Wait 2 seconds and retry
      4. Try a more specific selector targeting the inner clickable element
    

    Form submission fails silently:

    Causes:
      - Required field left empty (client-side validation blocked submit)
      - Hidden honeypot field was filled (bot detection)
      - CSRF token expired (session timeout)
      - JavaScript form validation prevents submission
    
    Fixes:
      1. browser_read_page → check for inline validation error messages
      2. browser_screenshot → look for highlighted required fields
      3. Verify all required fields are filled (check for asterisks or "required" labels)
      4. Try refreshing the page and filling the form again (new CSRF token)
    

    Page content appears empty or minimal:

    Causes:
      - Site requires JavaScript rendering (content injected by React/Vue/Angular)
      - Content is behind an authentication wall
      - Site is geo-blocked or IP-blocked
      - Content loads via AJAX after initial page load
    
    Fixes:
      1. Wait 3-5 seconds after navigation, then browser_read_page
      2. browser_screenshot → check if content is visually present but not in text
      3. Check if login is required
      4. Try a different URL or approach
    

    Redirect loop or unexpected page:

    Causes:
      - Session expired → site redirects to login → tries to redirect back → loop
      - Geo-redirect based on IP location
      - A/B testing serves different page version
      - Site requires cookie acceptance before showing content
    
    Fixes:
      1. browser_read_page → check current URL
      2. Handle cookie consent if prompted
      3. Re-authenticate if on login page
      4. Try navigating to the base domain first, then to the target page
    

    Security Checklist

    Before Entering Credentials

    • Verify the domain matches the expected site (check for typosquatting)
    • Confirm the page is served over HTTPS
    • Look for suspicious elements (extra fields, unusual layout)
    • Never enter credentials on HTTP pages
    • Warn user about any certificate warnings or security indicators

    During Sensitive Operations

    • Never store passwords in memory_store — use them only in browser_type
    • Never auto-approve financial transactions — always STOP and confirm with user
    • Report any unexpected redirects during authentication
    • Log out of sessions when workflow is complete

    Phishing Indicators to Watch For

    IndicatorExampleAction
    Misspelled domainamaz0n.com, gooogle.comSTOP and warn user
    Unusual TLDamazon.xyz, paypal.ruSTOP and warn user
    HTTP on login pagehttp://bank.com/loginSTOP and warn user
    Extra form fieldsSSN on a retail loginSTOP and warn user
    Suspicious redirectsLogin redirects to different domainSTOP and warn user
    Urgency language"Account suspended, act now"Inform user, suggest verifying

    Data Handling Rules

    SAFE to store in memory_store:
      - Product names, prices, descriptions
      - Public profile information
      - Search results and comparisons
      - Order confirmation numbers
      - Non-sensitive form field values
    
    NEVER store in memory_store:
      - Passwords, PINs, security codes
      - Credit card numbers or CVVs
      - Social Security or government ID numbers
      - Authentication tokens or session cookies
      - Private messages or confidential communications
    

    Frequently asked questions

    What to verify before installation and use

    What does the browser-automation source document cover?

    Playwright-based browser automation patterns for autonomous web interaction

    How do I install browser-automation?

    The source record exposes this install command: npx skills add https://github.com/librefang/librefang --skill "crates/librefang-runtime/tests/fixtures/registry/hands/browser". Inspect the command and pinned source before running it.

    Alternatives

    Compare before choosing