pr-screenshots
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChinesePR Screenshots
PR 截图
Screenshots in a PR are QA evidence. Each one shows what the real product
renders at one location, framed so a reviewer who has never opened the page can
tell what changed.
PR 中的截图是 QA 证据。每张截图都展示真实产品
在某个位置呈现的效果,并通过恰当取景,让从未打开过该页面的评审者
也能看出发生了什么变化。
Step 1: List the Locations
第 1 步:列出位置
List every place in the product that the diff reaches: each page, drawer,
modal, or widget that renders a changed component, found by tracing its
callers and consumers. Then add the states the change affects at each of them,
such as loading, error, empty, hover, selected, menu open, expanded, scrolled,
narrow viewport, and light or dark theme.
Never group surfaces into one row: for example,
"GridEditable, as in Discover, dashboards and insights" is three rows.
列出 diff 触及的每个产品位置:每个渲染了变更组件的页面、抽屉、
模态框或小组件,方法是追踪其调用方和消费方。然后列出变更在每个位置
所影响的状态,例如加载、错误、空状态、悬停、选中、菜单打开、展开、
已滚动、窄视口,以及浅色或深色主题。
切勿将多个界面合并到同一行。例如,
“在 Discover、dashboards 和 insights 中的 GridEditable”对应三行。
Step 2: Capture From the Real Product
第 2 步:从真实产品中捕获
| Rule | Detail |
|---|---|
| Real build only | Screenshot the running app on the PR branch for "after" and on the base branch for "before". Never screenshot a story, mock page, or harness built for the PR, unless the change is to that story. |
| No injected changes | Never inject CSS or change the DOM to imitate the change. Stubbing API responses is fine; the frontend code must be the real code. |
| Seed missing data | If a state needs data no account has, create it in a local environment. Do not report a location as impossible to screenshot until seeding has been tried, and then say exactly what failed. |
| Identical framing | Capture the same region at the same dimensions for both shots of a pair, even when one state is taller. Emulate a fixed viewport instead of resizing the user's own browser window. |
| Context | Keep the heading or label that names the thing, nearby rows or controls, and a little padding on every side. For a hover, focus, or open-menu state, keep the trigger and the overlay in one frame. When the bug only makes sense in its page, show more of the page. |
| No empty bands | Crop out browser chrome, app navigation, and regions the change does not touch. For full-width layouts, shrink the viewport instead of leaving wide blank space beside short content. |
| 规则 | 说明 |
|---|---|
| 仅使用真实构建 | “after”截图应取自 PR 分支上运行的应用,“before”截图应取自基础分支。除非变更本身针对某个 story,否则切勿截取 story、mock 页面或为该 PR 构建的 harness。 |
| 禁止注入变更 | 切勿注入 CSS 或修改 DOM 来模拟变更。可以对 API 响应进行打桩(stub),前端代码必须是真实代码。 |
| 填充缺失数据 | 如果某个状态需要任何账号都没有的数据,请在本地环境中创建它。在尝试填充数据之前,不要声称某位置无法截图;如果尝试后仍失败,请准确说明具体失败原因。 |
| 一致取景 | 即使其中一个状态更高,也要以相同的尺寸捕获一对截图中的相同区域。模拟固定视口,不要调整用户自己的浏览器窗口大小。 |
| 保留上下文 | 保留标识该内容的标题或标签、附近的数据行或控件,并在四周留出少量边距。对于悬停、焦点或菜单打开状态,应让触发元素和浮层出现在同一画面中。当某个 bug 只有放在其所属页面中才有意义时,应展示更多页面内容。 |
| 去除空白带状区域 | 裁掉浏览器界面、应用导航以及变更未触及的区域。对于全宽布局,应缩小视口,而不是在短内容旁留下大片空白。 |
Step 3: Redact and Audit
第 3 步:脱敏与审查
- Blur only private values: emails, usernames, customer or organization names
and slugs, IDs, and internal hostnames. Keep keys, labels, and non-sensitive
values readable, such as →
browser.name.chrome - Paint over each region before blurring it so the blur can't be reversed. Never use solid black or dark boxes, and never blur whole tables or rows.
- Read every image before uploading it and check for credentials: tokens, auth headers, cookies, signed URLs, secret keys, and webhook endpoints. Remove real leaks. Do not treat a public client DSN as a leak.
- 仅模糊私有值:电子邮件地址、用户名、客户或组织名称及 slug、ID 和内部主机名。键、标签和其他非敏感值应保持可读,例如 →
browser.name。chrome - 在模糊每个区域之前,先用涂抹方式将其遮盖,确保模糊效果无法被还原。切勿使用纯黑色或深色方块,也不得模糊整个表格或数据行。
- 上传前逐一检查每张图片,查找凭据:token、auth header、cookie、signed URL、secret key 和 webhook endpoint。移除真实的泄漏内容。不要将公开的 client DSN 视为泄漏。
Step 4: Choose the Table Shape
第 4 步:选择表格形式
| Change | Shape |
|---|---|
| Visual change to existing UI | Changed table, plus an Unchanged table for locations the diff reaches that render the same. |
| New page or feature | No before/after. A few "after" screenshots, each introduced by a short sentence. When the new UI appears in several locations, use a |
| Alternatives with no "before", such as prototype treatments or design options | |
| A change that differs by theme | Add a light and a dark row for each location, such as |
Pixel-diff every before/after pair. Move a pair with no
visible difference, including anti-aliasing noise, to Unchanged with one
image. Leave out a table that would be empty.
markdown
**Changed**
| Location | Before | After |
| --- | --- | --- |
| Explore › Logs |  |  |
| Explore › Logs, loading |  |  |
**Unchanged**
| Location | Before & After |
| --- | --- |
| Trace view › Logs |  |Formatting rules:
- Name the first column , or
Locationfor alternatives. Never leave its header empty.Treatment - Write each location as a breadcrumb of what the reader clicks through, then a comma and the state:
›.Monitors › cron monitor details › Check-Ins, loading - Use only the columns shown above. Never add a "What changed" or notes column; the screenshots show the change.
- Give each image alt text naming its row and side, such as
.
Explore › Logs before - Label the tables with bold and
**Changed**lines. Do not add an intro sentence describing where or how the screenshots were taken.**Unchanged** - Use Markdown tables by default, because rewrites only Markdown image references. Switch to an HTML table only when cells must span rows, such as a light and dark row under one location (
gh --attachwithLocation | Theme | Before | Afteron the location cell). Do not addrowspan="2"attributes.align
| 变更类型 | 形式 |
|---|---|
| 对现有 UI 的视觉变更 | 使用 Changed 表格,并为 diff 触及但渲染结果未变的位置使用 Unchanged 表格。 |
| 新页面或新功能 | 不需要 before/after。提供少量“after”截图,每张截图前加一句简短说明。当新 UI 出现在多个位置时,改用 `Location |
| 没有“before”的备选方案,例如原型处理方案或设计选项 | 使用 `Treatment |
| 变更因主题而异 | 为每个位置添加浅色和深色两行,例如 |
对每一组 before/after 截图进行像素差异比较。如果一对截图没有可见差异(包括抗锯齿噪点),则将其移至 Unchanged,只保留一张图片。不要加入会为空的表格。
markdown
**Changed**
| Location | Before | After |
| --- | --- | --- |
| Explore › Logs |  |  |
| Explore › Logs, loading |  |  |
**Unchanged**
| Location | Before & After |
| --- | --- |
| Trace view › Logs |  |格式规则:
- 将第一列命名为 ,备选方案则命名为
Location。切勿留空表头。Treatment - 将每个位置写为读者依次点击的 面包屑路径,后接逗号和状态,例如
›。Monitors › cron monitor details › Check-Ins, loading - 仅使用上文所示的列。切勿添加“What changed”或备注列;截图本身已经展示变更。
- 为每张图片设置能标明所在行和对应一侧的替代文本,例如 。
Explore › Logs before - 使用粗体的 和
**Changed**行标记表格。不要添加介绍截图拍摄位置或方式的句子。**Unchanged** - 默认使用 Markdown 表格,因为 只会重写 Markdown 图片引用。仅当单元格需要跨行时才切换到 HTML 表格,例如在同一个位置下设置浅色和深色两行(
gh --attach,并在位置单元格上设置Location | Theme | Before | After)。不要添加rowspan="2"属性。align
Step 5: Upload With gh
第 5 步:使用 gh 上传
gh pr creategh pr editgh pr commentgh issue--attach '<path>#<alt text>'ghWrite the body file with relative Markdown image references, then pass the same
paths to . gh uploads each file and rewrites the matching reference
to the uploaded URL in place:
--attachbash
gh pr edit 123 --body-file pr-body.md \
--attach './shots/logs-before.png' --attach './shots/logs-after.png'| Behavior | Detail |
|---|---|
| Paths | Resolve against the current directory, and must match the body's references exactly. |
| Unreferenced attachments | Get appended to the end of the body as |
| No body flag | |
| HTML tables | |
Before writing a body the user may have edited, fetch it again and compare it
with the version you last read. Keep the user's wording and table edits, swap in
only your rows and URLs, and keep the body's line endings. Removing an image
from the body does not delete the uploaded file.
gh pr creategh pr editgh pr commentgh issue--attach '<path>#<alt text>'gh使用相对 Markdown 图片引用编写正文文件,然后将相同路径传给 。gh 会上传每个文件,并就地重写正文中对应的引用:
--attachbash
gh pr edit 123 --body-file pr-body.md \
--attach './shots/logs-before.png' --attach './shots/logs-after.png'| 行为 | 说明 |
|---|---|
| 路径 | 相对于当前目录进行解析,并且必须与正文中的引用完全匹配。 |
| 未引用的附件 | 会以 |
| 未提供正文参数 | |
| HTML 表格 | |
在写入用户可能已经编辑过的正文之前,再次获取正文,并与上次读取的版本进行比较。保留用户的措辞和表格编辑,仅替换相关行和 URL,并保持正文的换行符不变。从正文中移除图片不会删除已上传的文件。
Step 6: Keep Screenshots Current
第 6 步:保持截图同步更新
When a later commit changes what a screenshot shows, retake the affected pairs,
re-check which pairs belong in Changed and Unchanged, and update the
body without waiting to be asked.
当后续 commit 改变了截图所展示的内容时,重新拍摄受影响的截图对,再次检查哪些截图对应归入 Changed 或 Unchanged,并在无需等待用户指示的情况下更新正文。