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.

Quellinformationen

Repository
NVIDIA/TensorRT
Letzte Quellaktivität
22. September 2026 um 19:37
Erkannte Sprache von SKILL.md
Englisch
Sterne
13.428
Forks
2.416

Installationsoptionen

Standardmäßig ist der Prompt ausgewählt, der zuerst die Quelle prüft. Sie können zu einem direkten Befehl wechseln oder eine lokale Kopie herunterladen.

Quelldateien prüfen

Lesen Sie SKILL.md und alle von SkillsMP angezeigten Begleitdateien, bevor Sie sich für eine Installation entscheiden.

SKILL.md wird angezeigt

SKILL.md
Quellanweisungen · Schreibgeschützte Vorschau
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() ```
Auf GitHub ansehen