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.

Datos de origen

Repositorio
NVIDIA/TensorRT
Última actividad en el origen
22 de septiembre de 2026 a las 19:37
Idioma detectado de SKILL.md
inglés
Estrellas
13.405
Forks
2414

Opciones de instalación

De forma predeterminada está seleccionado el prompt que primero revisa el origen. Puedes cambiar a un comando directo o descargar una copia local.

Revisa los archivos de origen

Lee SKILL.md y los archivos complementarios que muestra SkillsMP antes de decidir si quieres instalarlo.

Mostrando SKILL.md

SKILL.md
Instrucciones de origen · Vista previa de solo lectura
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() ```
Ver en GitHub