Claude Skill

drive-local-webapp

Launch or connect to a local development web server and drive it with a reusable headless-Chromium command interface. Use when asked to render, smoke-test, interact with, verify, or screenshot a local frontend or HTML mockup.

LLM Mart · 0 points · 15 views 0 listing impressions 0 install-command copies
Virus-scanned Reviewed automatically before listing.

Full trust report

Download ConnorGriffin-skills-skills_tools_drive-local-webapp-5f6aaee.zip · 6 KB
Part of connorgriffin/skills — 25 skills

Install

skills CLI npx skills add https://github.com/ConnorGriffin/skills/tree/main/skills/tools/drive-local-webapp
Claude Code claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install connorgriffin-skills@llmmart
Git git clone https://github.com/ConnorGriffin/skills.git

The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole connorgriffin/skills collection as a plugin from our marketplace. Git is the plain clone.

Skill manifest

Drive a local web app

Use the bundled Playwright driver instead of writing a one-off browser script. It keeps one page alive while reading commands from standard input and reports each command as OK or FAIL.

One-time setup

Resolve this installed skill's directory, then run:

cd <drive-local-webapp-skill-directory>
npm ci
npx playwright install chromium

Node.js 20 or newer is recommended. Browser binaries are cached by Playwright. Verify the installation reproducibly:

npm run self-check

Workflow

  1. Start the target application's normal development or demo server. Use throwaway fixtures, never production or personal data. Check that the chosen port is free before binding it.

  2. Run node scripts/driver.mjs from this skill directory and pipe one command per line:

    DRIVER_SCREENSHOT_DIR=/tmp/webapp-shots node scripts/driver.mjs <<'EOF'
    nav http://127.0.0.1:8766/
    wait-for text=Dashboard
    click button:text-is("Settings")
    fill input[placeholder="API token"] :: demo-token
    click button:text-is("Save")
    screenshot
    console --errors
    EOF
    
  3. Treat any FAIL line or non-zero exit as a failed check. Treat a non-empty CONSOLE_ERRORS array as a failed check unless the error is explicitly expected.

  4. Inspect the screenshot itself. File existence does not prove the intended UI rendered.

If the host sandbox blocks Chromium process creation, rerun the same driver command with the client's narrowly scoped approval mechanism. Do not reinstall Chromium or alter the application to work around a host permission error.

Only navigate to a local page you trust or a URL the user explicitly placed in scope. Headless Chromium is not a security boundary: page JavaScript can make network requests and exercise the permissions available to the browser process. Do not use this driver as a general-purpose browser for untrusted sites.

Commands

nav <url>
wait-for <selector>
click <selector>
mouse-click <x>,<y>
fill <selector> :: <value>
set <selector> :: <value>
press <key>
wait <milliseconds>
eval <javascript-expression>
screenshot [absolute-path]
console --errors

Use :text-is("Label") for exact text. Playwright's :has-text() is case-insensitive substring matching and can silently click the wrong control.

Use mouse-click for a target with no addressable element, such as a canvas, an embedded map, or a region inside a chart. Prefer a selector wherever one exists; coordinates go stale as soon as the layout moves.

Keep screenshots outside the target repository. The driver defaults to the system temporary directory, or use DRIVER_SCREENSHOT_DIR. It refuses to overwrite an existing screenshot path.

Common failures

  • Selectors containing spaces require the literal :: separator for fill and set.
  • Hidden tab content may exist in the DOM; click the actual tab before waiting on its contents.
  • Charts initialized inside display:none containers may have zero width. Activate the tab, wait, and verify the app resizes or lazily initializes the chart.
  • A client-side token gate may leave the screen loading without a console error. Inspect the application's setup UI and use a demo token.
  • screenshot captures the full page, but mouse-click addresses the visible viewport. On a page taller than the viewport, a point measured off a screenshot is not the point that gets clicked, and a point past the viewport still reports OK while hitting nothing. Scroll the target into view first, and assert on the effect rather than on the OK line.
Files (skills)
  • agents
    • openai.yaml 208 B
      interface:
        display_name: "Drive Local Web App"
        short_description: "Verify local web apps in headless Chromium"
        default_prompt: "Use $drive-local-webapp to smoke-test and screenshot this local web app."
      
  • scripts
    • driver.mjs 5.6 KB · in bundle
    • self-check.mjs 3 KB · in bundle
  • package-lock.json 1.7 KB
    {
      "name": "drive-local-webapp-skill",
      "version": "1.0.0",
      "lockfileVersion": 3,
      "requires": true,
      "packages": {
        "": {
          "name": "drive-local-webapp-skill",
          "version": "1.0.0",
          "dependencies": {
            "playwright": "1.61.1"
          }
        },
        "node_modules/fsevents": {
          "version": "2.3.2",
          "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
          "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
          "hasInstallScript": true,
          "license": "MIT",
          "optional": true,
          "os": [
            "darwin"
          ],
          "engines": {
            "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
          }
        },
        "node_modules/playwright": {
          "version": "1.61.1",
          "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.61.1.tgz",
          "integrity": "sha512-DWnY5o3YbLWK4GovuAVwpqL+1VwGNdUGrRr++8j8PtQQzvAVZUIMjKQ90fY689sEJZJBbZVw1rXaOKSTitkzPQ==",
          "license": "Apache-2.0",
          "dependencies": {
            "playwright-core": "1.61.1"
          },
          "bin": {
            "playwright": "cli.js"
          },
          "engines": {
            "node": ">=18"
          },
          "optionalDependencies": {
            "fsevents": "2.3.2"
          }
        },
        "node_modules/playwright-core": {
          "version": "1.61.1",
          "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.61.1.tgz",
          "integrity": "sha512-h7Qlt6m4REp25qvIdvbDtVmD4LqVXfpRxhORv9L0jzETM05p4fuPJ3dKyuSXQxDSbXnmS79HAgi9589lGSpLkg==",
          "license": "Apache-2.0",
          "bin": {
            "playwright-core": "cli.js"
          },
          "engines": {
            "node": ">=18"
          }
        }
      }
    }
    
  • package.json 320 B
    {
      "name": "drive-local-webapp-skill",
      "private": true,
      "type": "module",
      "version": "1.0.0",
      "description": "Reusable Playwright command driver bundled with the drive-local-webapp skill.",
      "scripts": {
        "self-check": "node scripts/self-check.mjs"
      },
      "dependencies": {
        "playwright": "1.61.1"
      }
    }
    
  • SKILL.md 3.8 KB
    ---
    name: drive-local-webapp
    description: Launch or connect to a local development web server and drive it with a reusable headless-Chromium command interface. Use when asked to render, smoke-test, interact with, verify, or screenshot a local frontend or HTML mockup.
    ---
    
    # Drive a local web app
    
    Use the bundled Playwright driver instead of writing a one-off browser script.
    It keeps one page alive while reading commands from standard input and reports
    each command as `OK` or `FAIL`.
    
    ## One-time setup
    
    Resolve this installed skill's directory, then run:
    
    ```sh
    cd <drive-local-webapp-skill-directory>
    npm ci
    npx playwright install chromium
    ```
    
    Node.js 20 or newer is recommended. Browser binaries are cached by Playwright.
    Verify the installation reproducibly:
    
    ```sh
    npm run self-check
    ```
    
    ## Workflow
    
    1. Start the target application's normal development or demo server. Use
       throwaway fixtures, never production or personal data. Check that the chosen
       port is free before binding it.
    2. Run `node scripts/driver.mjs` from this skill directory and pipe one command
       per line:
    
       ```sh
       DRIVER_SCREENSHOT_DIR=/tmp/webapp-shots node scripts/driver.mjs <<'EOF'
       nav http://127.0.0.1:8766/
       wait-for text=Dashboard
       click button:text-is("Settings")
       fill input[placeholder="API token"] :: demo-token
       click button:text-is("Save")
       screenshot
       console --errors
       EOF
       ```
    
    3. Treat any `FAIL` line or non-zero exit as a failed check. Treat a non-empty
       `CONSOLE_ERRORS` array as a failed check unless the error is explicitly
       expected.
    4. Inspect the screenshot itself. File existence does not prove the intended UI
       rendered.
    
    If the host sandbox blocks Chromium process creation, rerun the same driver
    command with the client's narrowly scoped approval mechanism. Do not reinstall
    Chromium or alter the application to work around a host permission error.
    
    Only navigate to a local page you trust or a URL the user explicitly placed in
    scope. Headless Chromium is not a security boundary: page JavaScript can make
    network requests and exercise the permissions available to the browser process.
    Do not use this driver as a general-purpose browser for untrusted sites.
    
    ## Commands
    
    ```text
    nav <url>
    wait-for <selector>
    click <selector>
    mouse-click <x>,<y>
    fill <selector> :: <value>
    set <selector> :: <value>
    press <key>
    wait <milliseconds>
    eval <javascript-expression>
    screenshot [absolute-path]
    console --errors
    ```
    
    Use `:text-is("Label")` for exact text. Playwright's `:has-text()` is
    case-insensitive substring matching and can silently click the wrong control.
    
    Use `mouse-click` for a target with no addressable element, such as a canvas, an
    embedded map, or a region inside a chart. Prefer a selector wherever one exists;
    coordinates go stale as soon as the layout moves.
    
    Keep screenshots outside the target repository. The driver defaults to the
    system temporary directory, or use `DRIVER_SCREENSHOT_DIR`. It refuses to
    overwrite an existing screenshot path.
    
    ## Common failures
    
    - Selectors containing spaces require the literal ` :: ` separator for
      `fill` and `set`.
    - Hidden tab content may exist in the DOM; click the actual tab before waiting
      on its contents.
    - Charts initialized inside `display:none` containers may have zero width.
      Activate the tab, wait, and verify the app resizes or lazily initializes the
      chart.
    - A client-side token gate may leave the screen loading without a console
      error. Inspect the application's setup UI and use a demo token.
    - `screenshot` captures the full page, but `mouse-click` addresses the visible
      viewport. On a page taller than the viewport, a point measured off a screenshot
      is not the point that gets clicked, and a point past the viewport still reports
      `OK` while hitting nothing. Scroll the target into view first, and assert on the
      effect rather than on the `OK` line.
    

Comments (0)

Sign in to join the conversation.

No comments yet.

Reviews (0)

No reviews yet.

Related