К основному содержанию
скилл официальный · GitHub

ui-screenshots — скилл для GitHub Copilot: скриншоты UI

Скилл снимает скриншоты веб-приложений и десктопных окон, чтобы показать изменения интерфейса до и после правок кода.

Установить в GitHub Copilot · Через Skills CLI (Vercel) Все способы и платформы ↓
npx skills add github/awesome-copilot --skill ui-screenshots
Открыть на GitHub

Что делает ui-screenshots

Основа — Playwright: агент открывает страницу в Chromium, ждёт загрузки и снимает полный скриншот высокого вьюпорта. Дальше кадр режется библиотекой Pillow, причём повторять снимок не нужно — вернуть нужный фрагмент можно мгновенным кропом.

Внутри описаны отдельные шаги: как снять состояние с наведением или выделением, как вырезать шапку и основную часть из одного изображения. Для приложений, до которых Playwright не добирается, есть обходной путь через mss и ctypes: окно ищется по заголовку, снимается видимая область. Электрон захватывают через Node.js Playwright по CDP, это работает даже при свёрнутом окне.

Перед первым запуском нужен Python и пакеты: pip install playwright Pillow -q, затем playwright install chromium. Для оконного варианта — pip install mss pillow. Скриншот «до» надо снимать до правок, иначе восстанавливать файлы через git checkout HEAD~1. Ещё пара ограничений: окно, снимаемое через mss, должно быть на виду, а сравнение до/после ломается, если ширина вьюпорта или границы кропа разные.

Какие задачи решает

  • снять состояние интерфейса до и после правки кода
  • зафиксировать всплывающие подсказки и состояния при наведении
  • вырезать шапку и основную часть из одного снимка
  • поставить браузер для Playwright и запустить первую съёмку
  • снять окно настольного приложения, когда Playwright не подходит

Примеры запросов агенту

  • Сними текущее состояние страницы http://localhost:3000 и сохрани в before.png
  • Сделай скриншот с открытым тултипом при наведении на кнопку, потом убери мышь и сними выделенное состояние
  • Вырежи из screenshot-raw.png шапку и основную секцию в два отдельных файла

Как установить ui-screenshots

1Через Skills CLI (Vercel)

npx skills add github/awesome-copilot --skill ui-screenshots

2GitHub CLI

gh skill install github/awesome-copilot ui-screenshots

3Вручную: положить файлы

.github/skills/ui-screenshots/SKILL.md

По шагам, с командами для каждой платформы: Как установить скилл в Claude Code: пять способов

Вопросы о ui-screenshots

Как установить ui-screenshots в GitHub Copilot?

Через менеджер скиллов: npx skills add github/awesome-copilot --skill ui-screenshots. Второй способ — gh skill install github/awesome-copilot ui-screenshots. После установки файл скилла лежит в .github/skills/ui-screenshots/SKILL.md.

Что делает ui-screenshots?

Показывает агенту, как снимать страницы через Playwright и резать кадр в Pillow. Отдельные инструкции покрывают интерактивные состояния и захват окон настольных приложений.

Что нужно для работы скилла?

Python с пакетами playwright и Pillow, плюс браузер из playwright install chromium. Для оконного захвата нужен mss, а для Electron — Node.js Playwright.

Исходный текст

SKILL.md · MIT
---
name: ui-screenshots
description: 'Capture screenshots of web apps during development using Playwright and PIL. Supports full-page captures, interactive states, and an iterate-on-crop workflow that avoids slow re-screenshots.'
---

# UI Screenshots

Capture screenshots of web apps and graphical UIs during development to document visual changes.

## When to Use This Skill

Use this skill when you need to:

- Capture the current state of a running web app
- Document a UI before and after a code change
- Screenshot interactive states (tooltips, hovers, selected elements)
- Capture specific sections of a page without re-screenshotting

## Prerequisites

```bash
pip install playwright Pillow -q
playwright install chromium
```

## Core Workflow

### 1. Take a raw full-page screenshot

```python
from playwright.async_api import async_playwright

async def capture(url="http://localhost:3000", out="screenshot-raw.png", width=1400, height=5000):
    async with async_playwright() as p:
        browser = await p.chromium.launch()
        page = await browser.new_page(viewport={"width": width, "height": height})
        await page.goto(url, wait_until="networkidle")
        await page.wait_for_timeout(4000)  # let charts/animations render
        await page.screenshot(path=out, full_page=True)
        await browser.close()
```

- Use a **tall viewport** (height=5000) so the page renders everything without scrolling
- `wait_until="networkidle"` + `wait_for_timeout(4000)` ensures async charts load
- `full_page=True` captures the entire scrollable content

### 2. View the raw image, then crop with PIL

**Do NOT try to get perfect crops via Playwright's `clip` parameter.** It's unreliable with full-page captures.

```python
from PIL import Image

img = Image.open("screenshot-raw.png")
cropped = img.crop((left, top, right, bottom))  # adjust based on what you see
cropped.save("screenshot-final.png")
```

1. Take the raw screenshot
2. View it to see actual pixel positions
3. Crop with PIL based on what you see
4. View the result — if not right, re-crop (instant, no re-screenshot needed)

### 3. Iterate on crop, not on capture

- Re-screenshotting is slow (browser launch + page load + render wait)
- Re-cropping is instant (just PIL)
- Get one good raw capture, then slice it as many ways as needed

### 4. Interactive states

```python
element = page.locator("selector").first
await element.hover()
await page.wait_for_timeout(1000)  # let tooltip appear
await page.screenshot(path="screenshot-hover.png", full_page=True)
```

For "selected" state without hover effect, move the mouse away after clicking:

```python
await element.click()
await page.mouse.move(300, 300)  # move away so hover doesn't show
await page.wait_for_timeout(500)
await page.screenshot(path="screenshot-selected.png", full_page=True)
```

### 5. Section-specific captures

Crop different sections from a single full-page screenshot:

```python
img.crop((0, 200, 920, 900)).save("screenshot-header.png")
img.crop((0, 900, 920, 1600)).save("screenshot-main.png")
```

## Guidelines

1. **Always capture before state BEFORE making any changes** — if you forget, you have to revert code to get a before shot
2. **Before/after pairs must use the same viewport width and crop** — otherwise the comparison is useless
3. **To get a "before" after you already changed code**: use `git checkout HEAD~1 -- <files>` to revert, screenshot, then `git checkout HEAD -- <files>` to restore
4. **For interactive states**: capture before AND after for each state — don't assume the "normal" before covers all cases
5. **Use `device_scale_factor=1`** in Playwright to force 1x pixels so screenshots match what users see at 100% zoom
6. **Charts need extra wait time** — Plotly, D3, etc. render asynchronously; 4s minimum after networkidle
7. **Narrow viewport reveals rendering bugs** — some border/alignment issues only appear at specific widths

## Non-Web App Screenshots

For desktop apps (VS, WPF, WinForms, console apps, terminals) where Playwright can't reach.

### mss + ctypes (recommended for desktop windows)

Find a window by title via Win32 API, capture its region with `mss`. Tested at ~33ms per capture.

```python
import ctypes
from ctypes import c_int, Structure, byref, windll
import mss
from PIL import Image

user32 = windll.user32

def find_window(title_contains):
    """Find visible windows matching a title substring."""
    results = []
    WNDENUMPROC = ctypes.WINFUNCTYPE(ctypes.c_bool, ctypes.c_void_p, ctypes.c_void_p)
    def cb(hwnd, _):
        if user32.IsWindowVisible(hwnd):
            buf = ctypes.create_unicode_buffer(256)
            user32.GetWindowTextW(hwnd, buf, 256)
            if title_contains.lower() in buf.value.lower():
                results.append((hwnd, buf.value))
        return True
    user32.EnumWindows(WNDENUMPROC(cb), 0)
    return results

def capture_window(title_contains, output_path):
    """Capture a window by title substring."""
    windows = find_window(title_contains)
    if not windows:
        raise ValueError(f"No window matching '{title_contains}'")
    hwnd = windows[0][0]

    class RECT(Structure):
        _fields_ = [('left', c_int), ('top', c_int), ('right', c_int), ('bottom', c_int)]
    rect = RECT()
    user32.GetWindowRect(hwnd, byref(rect))
    w, h = rect.right - rect.left, rect.bottom - rect.top

    with mss.mss() as sct:
        shot = sct.grab({'left': rect.left, 'top': rect.top, 'width': w, 'height': h})
        img = Image.frombytes('RGB', shot.size, shot.rgb)
        img.save(output_path)
        return img

# Usage:
capture_window('Visual Studio Code', 'vscode-capture.png')
```

**Prerequisites:** `pip install mss pillow`
**Limitation:** Window must be visible (not behind other windows or minimized).

### Electron apps (VS Code, etc.)

**Node.js Playwright only** — Python Playwright has no `electron` API. Captures via CDP (Chrome DevTools Protocol), not from the screen — works even while minimized.

```javascript
const { _electron: electron } = require('playwright');
const app = await electron.launch({
    executablePath: 'C:\\Program Files\\Microsoft VS Code\\Code.exe',
    args: ['--new-window', '--disable-extensions', '--user-data-dir=' + tmpDir]
});
const window = await app.firstWindow();
await window.waitForLoadState('domcontentloaded');

// Minimize immediately — captures still work via CDP
await app.evaluate(({ BrowserWindow }) => {
    BrowserWindow.getAllWindows()[0].minimize();
});

await window.screenshot({ path: 'capture.png' }); // works while minimized!
await app.close();
```

**Critical**: `--user-data-dir=<temp>` is required or VS Code hands off to the existing instance and the launched process exits immediately.

### Decision tree

| Scenario | Tool | Notes |
|---|---|---|
| Web app (localhost) | Playwright | Proven, full DOM access |
| Electron app (VS Code) | Playwright Electron (Node.js) | Works minimized via CDP |
| Desktop app, visible window | mss + ctypes (find by title) | ~33ms per capture |
| Desktop app, behind windows | Windows Graphics Capture API | Complex setup, Win10 1903+ |
| Quick full-screen | mss | ~68ms |

## Limitations

- Web capture requires a locally running app or accessible URL
- Desktop capture (mss) requires the window to be visible and unobstructed
- Electron capture requires Node.js Playwright (not Python)
- Some SPAs with heavy client-side rendering may need custom wait logic beyond networkidle

© github · MIT · github/awesome-copilot

Похожие скиллы

Всё по теме «Фронтенд и UI» →
frontend-design официальный anthropics Скилл задаёт осмысленное визуальное направление для новых интерфейсов и редизайна. Подойдёт, когда стандартный шаблонный UI не устраивает. 1 025 790установок design-taste-frontend Leonxlnx Скилл задаёт арт-дирекцию для публичных страниц и рабочих экранов, а затем проверяет результат в браузере по скриншотам. Нужен, когда интерфейс выглядит шаблонным или недоработанным. CX Codex +1 678 700установок prototype Matt Pocock Создаёт временный прототип, чтобы проверить логику, модель состояния или вид интерфейса до работы над основным кодом. 986 201установок hyperframes heygen-com Скилл задаёт агенту правила рендера HTML-кода в видео через HyperFrames. Помогает собирать проморолики, эксплейнеры и титры прямо в коде проекта. CX Codex +1 1 200 000установок hyperframes-cli heygen-com Управляет проектами HyperFrames через терминал: собирает таймлайн, проверяет контраст кадров, запускает предпросмотр и рендерит видео локально или в облаке. CX Codex +1 1 300 000установок webapp-testing официальный anthropics Скилл запускает проверки локальных веб-приложений через Playwright: помогает отлаживать UI, делать скриншоты и смотреть логи браузера. 186 758установок

Из того же набора732

Весь набор →
codebase-memory-mcp Скилл помогает ориентироваться в незнакомой кодовой базе: искать символы, связи и потоки данных. Пригодится для оценки влияния изменений и проверки сложного кода. 259установок conventional-branch Скилл помогает создавать и проверять ветки Git по спецификации Conventional Branch. Пригодится для соблюдения единых префиксов вроде feature/ или bugfix/. 243установок mongodb-performance-advisor Анализирует запросы к MongoDB в кодовой базе и собирает метрики через MCP-сервер в режиме чтения. Помогает найти медленные пайплайны и оптимизировать индексы. 223установок apify-integration-expert Помогает встроить акторы Apify в проект на JavaScript или Python. Находит нужного актора, генерирует код вызова и настраивает сохранение результатов. 222установок diagnose Скилл проверяет AI-workflow по пяти измерениям и выдаёт оценки с приоритетными действиями. Подойдёт для аудита агента до запуска и после заметных изменений. 209установок technical-content-evaluator Субагент вычитывает технические курсы и документацию: точность кода, логика изложения, реальность упражнений. Нужен, когда перед публикацией надо понять, учат ли материалы или только шлют по ссылкам. 209установок batch-files Добавляет в GitHub Copilot знание синтаксиса cmd.exe для написания, отладки и поддержки файлов .bat и .cmd. Пригодится для автоматизации задач в Windows и скриптов планировщика. 206установок power-platform-architect Скилл превращает бизнес-требования, кейсы и расшифровки встреч в архитектуру решения на Power Platform. Пригодится для выбора компонентов и схемы Mermaid.js. 205установок

Спонсоры проекта

Компании, которые помогают держать аналитику открытой