cuj-screenshots
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseCUJ Screenshots Skill
CUJ 截图技能
Automate visual documentation of web app user journeys using headless browser automation.
通过无头浏览器自动化实现Web应用用户旅程的视觉文档自动化。
When to Use This
适用场景
Always run CUJ captures after UI changes. This is part of the dev loop, not just documentation.
UI变更后务必运行CUJ捕获。 这是开发流程的一部分,而非仅用于文档记录。
Triggered By:
触发场景:
- Any frontend component change
- CSS/styling updates
- New features that affect user flow
- Bug fixes that change visible behavior
- Before sharing work with humans ("here's what it looks like now")
- 任何前端组件变更
- CSS/样式更新
- 影响用户流程的新功能
- 改变可见行为的Bug修复
- 与他人分享工作前("这是当前的效果")
The Loop:
流程循环:
Make UI change → Run CUJs → Review screenshots →
├─ Looks good? → Update GIFs, commit, share link
└─ Looks wrong? → Fix bug, repeatMake UI change → Run CUJs → Review screenshots →
├─ Looks good? → Update GIFs, commit, share link
└─ Looks wrong? → Fix bug, repeatProactive Use:
主动使用方式:
When finishing UI work, don't just say "done" — capture CUJs, update the GIFs, and share:
"Updated the task card styling. Here's the new CUJ: https://github.com/user/repo/blob/main/docs/CUJs.md"
This gives your human instant visual feedback without them needing to run the app.
完成UI工作后,不要只说"完成了" —— 捕获CUJ,更新GIF并分享:
"更新了任务卡片样式。这是新的CUJ: https://github.com/user/repo/blob/main/docs/CUJs.md"
这样无需对方运行应用,就能立刻给他们提供直观的视觉反馈。
What It Does
功能说明
- Launches headless Chromium via Playwright
- Navigates through a defined user journey
- Captures screenshots at each step
- Stitches screenshots into an animated GIF
- Outputs to a docs folder for commit
- 通过Playwright启动无头Chromium
- 按照定义的用户旅程导航
- 在每个步骤捕获截图
- 将截图拼接为动画GIF
- 输出到docs文件夹以便提交
Requirements
环境要求
- Playwright:
uv run --with playwright python script.py - Chromium: Auto-installed by Playwright on first run
- ImageMagick: For GIF creation (command)
convert
Install Playwright browsers (one-time):
bash
uv run --with playwright playwright install chromium- Playwright:
uv run --with playwright python script.py - Chromium: 首次运行时由Playwright自动安装
- ImageMagick: 用于生成GIF(命令)
convert
安装Playwright浏览器(仅需一次):
bash
uv run --with playwright playwright install chromiumQuick Start
快速开始
1. Define Your CUJ
1. 定义你的CUJ
Create a Python script for each journey:
python
import asyncio
from playwright.async_api import async_playwright
import os
async def capture_my_cuj():
output_dir = "/tmp/cuj-screenshots/my-cuj"
os.makedirs(output_dir, exist_ok=True)
async with async_playwright() as p:
browser = await p.chromium.launch(headless=True)
context = await browser.new_context(
viewport={"width": 390, "height": 844}, # Mobile
device_scale_factor=2 # Retina
)
page = await context.new_page()
# Step 1
await page.goto("http://localhost:5173")
await page.wait_for_timeout(1500)
await page.screenshot(path=f"{output_dir}/01-initial.png")
# Step 2: Interact
await page.click("button:has-text('Submit')")
await page.wait_for_timeout(1000)
await page.screenshot(path=f"{output_dir}/02-submitted.png")
# ... more steps
await browser.close()
if __name__ == "__main__":
asyncio.run(capture_my_cuj())为每个用户旅程创建Python脚本:
python
import asyncio
from playwright.async_api import async_playwright
import os
async def capture_my_cuj():
output_dir = "/tmp/cuj-screenshots/my-cuj"
os.makedirs(output_dir, exist_ok=True)
async with async_playwright() as p:
browser = await p.chromium.launch(headless=True)
context = await browser.new_context(
viewport={"width": 390, "height": 844}, # Mobile
device_scale_factor=2 # Retina
)
page = await context.new_page()
# Step 1
await page.goto("http://localhost:5173")
await page.wait_for_timeout(1500)
await page.screenshot(path=f"{output_dir}/01-initial.png")
# Step 2: Interact
await page.click("button:has-text('Submit')")
await page.wait_for_timeout(1000)
await page.screenshot(path=f"{output_dir}/02-submitted.png")
# ... more steps
await browser.close()
if __name__ == "__main__":
asyncio.run(capture_my_cuj())2. Run Capture
2. 运行捕获
bash
uv run --with playwright python my_cuj.pybash
uv run --with playwright python my_cuj.py3. Create GIF
3. 生成GIF
bash
convert -delay 150 -loop 0 /tmp/cuj-screenshots/my-cuj/*.png output.gif- = 1.5 seconds per frame (hundredths of a second)
-delay 150 - = infinite loop
-loop 0
bash
convert -delay 150 -loop 0 /tmp/cuj-screenshots/my-cuj/*.png output.gif- = 每帧1.5秒(单位:百分之一秒)
-delay 150 - = 无限循环
-loop 0
4. Commit & Share
4. 提交并分享
bash
mv output.gif docs/gifs/my-cuj.gif
git add docs/gifs/my-cuj.gif docs/CUJs.md
git commit -m "docs: add my-cuj GIF"
git pushbash
mv output.gif docs/gifs/my-cuj.gif
git add docs/gifs/my-cuj.gif docs/CUJs.md
git commit -m "docs: add my-cuj GIF"
git pushViewport Presets
视口预设
| Device | Width | Height | Scale |
|---|---|---|---|
| iPhone 12 Pro | 390 | 844 | 2 |
| iPhone SE | 375 | 667 | 2 |
| Pixel 5 | 393 | 851 | 2.75 |
| Desktop | 1280 | 720 | 1 |
| Desktop HD | 1920 | 1080 | 1 |
| 设备 | 宽度 | 高度 | 缩放比例 |
|---|---|---|---|
| iPhone 12 Pro | 390 | 844 | 2 |
| iPhone SE | 375 | 667 | 2 |
| Pixel 5 | 393 | 851 | 2.75 |
| Desktop | 1280 | 720 | 1 |
| Desktop HD | 1920 | 1080 | 1 |
Common Interactions
常见交互操作
python
undefinedpython
undefinedClick button by text
Click button by text
await page.click("button:has-text('Submit')")
await page.click("button:has-text('Submit')")
Fill input
Fill input
await page.fill("input[name='email']", "test@example.com")
await page.fill("input[name='email']", "test@example.com")
Select dropdown
Select dropdown
await page.select_option("select#plan", "premium")
await page.select_option("select#plan", "premium")
Wait for element
Wait for element
await page.wait_for_selector(".success-message")
await page.wait_for_selector(".success-message")
Scroll
Scroll
await page.evaluate("window.scrollBy(0, 300)")
await page.evaluate("window.scrollBy(0, 300)")
Keyboard shortcut
Keyboard shortcut
await page.keyboard.press("Escape")
undefinedawait page.keyboard.press("Escape")
undefinedFull Workflow Example
完整工作流示例
See for a complete example that:
scripts/capture-cujs.py- Starts backend + frontend servers
- Captures multiple CUJs
- Generates GIFs
- Updates CUJs.md
查看获取完整示例,该示例可以:
scripts/capture-cujs.py- 启动后端+前端服务器
- 捕获多个CUJs
- 生成GIF
- 更新CUJs.md
Tips
小贴士
- Wait times: Use after interactions for animations
wait_for_timeout(1000) - Selectors: Prefer or
text=over fragile CSS selectorshas-text() - Error handling: Wrap interactions in try/except, screenshot on error
- Naming: Use numbered prefixes (,
01-) for sort order02- - GIF size: Keep under 500KB for GitHub README display
- 等待时间:交互后使用等待动画完成
wait_for_timeout(1000) - 选择器:优先使用或
text=而非脆弱的CSS选择器has-text() - 错误处理:将交互操作包裹在try/except中,出错时捕获截图
- 命名规范:使用数字前缀(,
01-)保证排序正确02- - GIF大小:保持在500KB以下以便在GitHub README中正常显示
CUJs.md Documentation
CUJs.md 文档规范
Create a file to document each journey with embedded GIFs:
docs/CUJs.mdmarkdown
undefined创建文件,嵌入GIF来记录每个用户旅程:
docs/CUJs.mdmarkdown
undefinedCritical User Journeys (CUJs)
Critical User Journeys (CUJs)
CUJ 1: App Tour
CUJ 1: App Tour
Goal: Navigate the main app layout.
Steps:
- Open app → Activity tab
- Switch to Live tab
- Return to Activity

Goal: Navigate the main app layout.
Steps:
- Open app → Activity tab
- Switch to Live tab
- Return to Activity

CUJ 2: Create Task
CUJ 2: Create Task
Goal: Create a new plan and task.
Steps:
- Click "+ Plan"
- Enter name, submit
- Click "+ Task"
- Enter name, submit

This serves as both documentation and visual regression baseline.Goal: Create a new plan and task.
Steps:
- Click "+ Plan"
- Enter name, submit
- Click "+ Task"
- Enter name, submit

这份文档既是使用说明,也是视觉回归测试的基准。Verifying UI Changes
验证UI变更
After making UI changes:
- Run the CUJ capture scripts
- Review the new screenshots (you can read image files!)
- If they look correct, update GIFs and commit
- Update if steps changed
CUJs.md - If something's wrong, you caught a bug!
完成UI变更后:
- 运行CUJ捕获脚本
- 查看新截图(AI Agent可以识别这些图片!)
- 如果显示正常,更新GIF并提交
- 如果步骤有变化,更新
CUJs.md - 如果出现问题,说明你发现了一个Bug!
Full Workflow
完整工作流
bash
undefinedbash
undefined1. Make UI changes
1. Make UI changes
2. Start servers
2. Start servers
3. Capture CUJs
3. Capture CUJs
uv run --with playwright python scripts/capture-cujs.py
uv run --with playwright python scripts/capture-cujs.py
4. Review screenshots (agent can view these)
4. Review screenshots (agent can view these)
5. Create GIFs
5. Create GIFs
convert -delay 150 -loop 0 /tmp/cuj-screenshots/cuj1/*.png docs/gifs/cuj1.gif
convert -delay 150 -loop 0 /tmp/cuj-screenshots/cuj1/*.png docs/gifs/cuj1.gif
6. Update CUJs.md with new steps/descriptions
6. Update CUJs.md with new steps/descriptions
7. Commit everything
7. Commit everything
git add docs/CUJs.md docs/gifs/
git commit -m "docs: update CUJ screenshots after UI changes"
git push
undefinedgit add docs/CUJs.md docs/gifs/
git commit -m "docs: update CUJ screenshots after UI changes"
git push
undefined