Skip to main content

headless-screenshots

Use this skill when asked to take browser screenshots of web pages or web-based tools in a headless/automated way — especially when the page uses HTML canvas (e.g. Cytoscape.js, WebGL, Chart.js) and the screenshots need to show canvas-rendered content like graph nodes, edge labels, or drawn shapes. Also use when asked to automate multi-step browser interactions (clicks, drags, form fills) before screenshotting.

소스 정보

저장소
NVIDIA/TensorRT
최근 소스 활동
2026년 9월 22일 19:37
감지된 SKILL.md 언어
영어
스타
13,405
포크
2,414

설치 방법

기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.

소스 파일 검토

설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.

SKILL.md 표시 중

SKILL.md
소스 지침 · 읽기 전용 미리보기
name
headless-screenshots
description
Use this skill when asked to take browser screenshots of web pages or web-based tools in a headless/automated way — especially when the page uses HTML canvas (e.g. Cytoscape.js, WebGL, Chart.js) and the screenshots need to show canvas-rendered content like graph nodes, edge labels, or drawn shapes. Also use when asked to automate multi-step browser interactions (clicks, drags, form fills) before screenshotting.
# Headless Browser Screenshots with Playwright ## Stack - **Playwright** (Python) — `pip install playwright && python3 -m playwright install chromium` - **Chromium headless shell** — installed by the command above ## Critical: Canvas rendering requires software rendering Headless Chromium GPU-composites canvas off-screen by default. `canvas.getContext('2d').getImageData()` returns all-zero pixels, and canvas-rendered content (text labels, shapes drawn via `fillText`/`strokeRect`, etc.) does **not** appear in `page.screenshot()`. **Fix: always launch with `--use-gl=swiftshader`** ```python browser = pw.chromium.launch( headless=True, args=["--disable-gpu", "--use-gl=swiftshader"], ) ``` This forces software rendering so canvas content is fully composited into screenshots. ### How to tell you need this - DOM-rendered content (divs, HTML overlays) shows up fine in screenshots - Canvas-drawn content (graph edges, IO node labels, chart axes) is missing - `canvas.getContext('2d').getImageData(x, y, 1, 1).data` returns `[0, 0, 0, 0]` everywhere ## Serving pages Serve HTML via a local HTTP server — snap-confined browsers and sandboxed environments block `file://` paths: ```python srv = subprocess.Popen( ["python3", "-m", "http.server", "8765"], cwd="/tmp/my_assets", stdout=subprocess.PIPE, stderr=subprocess.PIPE, ) # wait for it to be ready import socket, time def wait_for_port(port, timeout=10): deadline = time.time() + timeout while time.time() < deadline: try: socket.create_connection(("127.0.0.1", port), 0.5).close(); return True except OSError: time.sleep(0.2) ``` ## Wait times for JS-heavy pages After `wait_until="networkidle"`, add extra sleep for pages that run layout algorithms (e.g. Cytoscape dagre, D3 force-directed): ```python page.goto(url, wait_until="networkidle") time.sleep(3.5) # let JS layout finish rendering ``` ## Accessing Cytoscape.js instances `window.cy` is shadowed by the `#cy` DOM element (browser auto-creates globals from element IDs). Use the internal registry instead: ```python GET_CY = "document.getElementById('cy')._cyreg.cy" # Get rendered node positions positions = page.evaluate(f""" () => {{ var cy = {GET_CY}; var result = []; cy.nodes('.op').forEach(function(n) {{ var pos = n.renderedPosition(); result.push({{x: pos.x, y: pos.y}}); }}); return result; }} """) ``` `renderedPosition()` returns pixel coordinates relative to the canvas container div (not the page). ## Box-select / drag interactions ```python canvas_box = page.locator("#cy").bounding_box() cx, cy_y = canvas_box["x"], canvas_box["y"] page.mouse.move(cx + x1, cy_y + y1) page.mouse.down() page.mouse.move(cx + x2, cy_y + y2, steps=12) # steps for smooth drag page.mouse.up() time.sleep(1.5) # let selection + panel update ``` ## Avoiding identifying paths in screenshots If a page displays the model/file path in its UI (e.g. in a command preview), copy the file to a neutral temp location before serving: ```python import shutil, pathlib shutil.copy(src_model, "/tmp/polygraphy_docs/model.onnx") # serve from /tmp/polygraphy_docs so displayed path is non-identifying ``` ## Full boilerplate ```python import subprocess, time, socket, glob, os from pathlib import Path from playwright.sync_api import sync_playwright CHROMIUM_ARGS = ["--disable-gpu", "--use-gl=swiftshader"] VIEWPORT = {"width": 1600, "height": 900} def wait_for_server(port, timeout=15): deadline = time.time() + timeout while time.time() < deadline: try: socket.create_connection(("127.0.0.1", port), 0.5).close(); return True except OSError: time.sleep(0.2) return False with sync_playwright() as pw: browser = pw.chromium.launch(headless=True, args=CHROMIUM_ARGS) page = browser.new_page(viewport=VIEWPORT) page.goto("http://127.0.0.1:PORT/", wait_until="networkidle") time.sleep(3.5) page.screenshot(path="output.png") browser.close() ```
GitHub에서 보기