@sentry/junior-agent-browser 0.109.0 → 0.111.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -1
- package/package.json +1 -1
- package/skills/visual-web-qa/SKILL.md +119 -0
- package/skills/visual-web-qa/SOURCES.md +19 -0
- package/skills/visual-web-qa/evals/cases/representative-coverage.yaml +9 -0
- package/skills/visual-web-qa/evals/cases/static-visual-verification.yaml +9 -0
- package/skills/visual-web-qa/evals/cases/target-resolution.yaml +6 -0
- package/skills/visual-web-qa/evals/cases/temporal-visual-verification.yaml +9 -0
- package/skills/visual-web-qa/evals/fixtures/visual-site/site/guide.html +33 -0
- package/skills/visual-web-qa/evals/fixtures/visual-site/site/index.html +48 -0
- package/skills/visual-web-qa/evals/fixtures/visual-site/site/loading.html +52 -0
- package/skills/visual-web-qa/evals/fixtures/visual-site/site/reference.html +33 -0
- package/skills/visual-web-qa/evals/fixtures/visual-site/site/styles.css +160 -0
- package/skills/visual-web-qa/spec.md +73 -0
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @sentry/junior-agent-browser
|
|
2
2
|
|
|
3
|
-
`@sentry/junior-agent-browser` adds browser automation workflows to Junior via the `agent-browser` CLI.
|
|
3
|
+
`@sentry/junior-agent-browser` adds browser automation and visual QA workflows to Junior via the `agent-browser` CLI.
|
|
4
4
|
|
|
5
5
|
Install it alongside `@sentry/junior`:
|
|
6
6
|
|
|
@@ -16,4 +16,15 @@ import { defineJuniorPlugins } from "@sentry/junior";
|
|
|
16
16
|
export const plugins = defineJuniorPlugins(["@sentry/junior-agent-browser"]);
|
|
17
17
|
```
|
|
18
18
|
|
|
19
|
+
The package includes two skills:
|
|
20
|
+
|
|
21
|
+
- `/agent-browser` for general browser navigation, interaction, extraction, and capture
|
|
22
|
+
- `/visual-web-qa` for evidence-driven verification of frontend, docs, layout, theme, loading, animation, and interaction changes
|
|
23
|
+
|
|
24
|
+
For example:
|
|
25
|
+
|
|
26
|
+
```text
|
|
27
|
+
/visual-web-qa Verify the docs theme on desktop and mobile, then share the evidence.
|
|
28
|
+
```
|
|
29
|
+
|
|
19
30
|
Full setup guide: https://junior.sentry.dev/extend/agent-browser-plugin/
|
package/package.json
CHANGED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: visual-web-qa
|
|
3
|
+
description: Verifies user-visible web changes with scoped browser evidence and reports only what the captured screenshots, videos, or state checks support. Use when frontend, docs, CSS, layout, theme, responsive, navigation, loading, animation, or interaction changes need visual validation; use agent-browser for general automation that is not specifically visual QA.
|
|
4
|
+
spec_hash: 7dd651f9311c
|
|
5
|
+
allowed-tools: bash sendFiles
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Visual Web QA
|
|
9
|
+
|
|
10
|
+
Verify rendered behavior in a browser instead of inferring visual correctness from code. Choose the smallest set of evidence that directly answers the request.
|
|
11
|
+
|
|
12
|
+
## Workflow
|
|
13
|
+
|
|
14
|
+
1. Classify the requested behavior as stable, temporal, or exact-state verification.
|
|
15
|
+
2. Resolve a valid local, preview, or explicitly requested target URL.
|
|
16
|
+
3. Choose representative pages, states, viewports, and themes.
|
|
17
|
+
4. Capture browser evidence with meaningful waits and fresh element refs.
|
|
18
|
+
5. Share requested artifacts with `sendFiles` and verify delivery success.
|
|
19
|
+
6. Report the exact target, evidence, result, findings, and limitations.
|
|
20
|
+
|
|
21
|
+
## Choose Evidence
|
|
22
|
+
|
|
23
|
+
| Request | Primary evidence | Optional support |
|
|
24
|
+
| ----------------------------------------- | ---------------------------------- | ------------------------------------------------ |
|
|
25
|
+
| Layout, CSS, content, typography | Screenshot | DOM text or style check |
|
|
26
|
+
| Light and dark themes | Screenshot per relevant theme | Theme attribute check |
|
|
27
|
+
| Responsive behavior | Screenshot per relevant breakpoint | Video only if resize motion matters |
|
|
28
|
+
| Loading state, animation, transition | Short video | Screenshot for a distinct final-state question |
|
|
29
|
+
| Navigation or interaction sequence | Short video | Screenshot for a specific defect |
|
|
30
|
+
| Stable menu, modal, hover, or focus state | Screenshot | Video if the transition matters |
|
|
31
|
+
| Exact text, route, ARIA, or attribute | DOM check | Screenshot or video if the visible state matters |
|
|
32
|
+
|
|
33
|
+
Use screenshots for stable rendered states. Use short videos for timing, motion, loading, or sequence. A purely temporal request may use video without a redundant screenshot. DOM checks support visual evidence; they do not replace it when the user asks how something looks.
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
agent-browser --session visual-qa screenshot /tmp/visual-qa.png
|
|
37
|
+
agent-browser --session visual-qa screenshot --full /tmp/visual-qa-full.png
|
|
38
|
+
agent-browser --session visual-qa screenshot --annotate /tmp/visual-qa-issue.png
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Keep Scope Representative
|
|
42
|
+
|
|
43
|
+
- Check one to four representative pages or states unless the user requests broader coverage or the change spans more templates.
|
|
44
|
+
- Choose the viewport-theme combinations most likely to expose the issue instead of building an exhaustive matrix by default.
|
|
45
|
+
- State clearly when only part of the requested surface was verified.
|
|
46
|
+
|
|
47
|
+
## Resolve The Target
|
|
48
|
+
|
|
49
|
+
Use this order:
|
|
50
|
+
|
|
51
|
+
1. User-provided URL
|
|
52
|
+
2. Running local development server
|
|
53
|
+
3. Repo-native server such as `pnpm dev`
|
|
54
|
+
4. Preview deployment
|
|
55
|
+
5. Production as an explicitly requested or read-only baseline
|
|
56
|
+
6. `file://` output only when the site renders correctly without a server
|
|
57
|
+
|
|
58
|
+
Do not check production and claim an unmerged change is present. If no valid target is reachable, report **blocked** and name the missing server, preview, build, or authentication requirement.
|
|
59
|
+
|
|
60
|
+
## Capture Reliable State
|
|
61
|
+
|
|
62
|
+
Wait for the state that proves progress instead of adding arbitrary delays:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
agent-browser --session visual-qa wait --url "**/expected-path"
|
|
66
|
+
agent-browser --session visual-qa wait --text "Expected text"
|
|
67
|
+
agent-browser --session visual-qa wait --load networkidle
|
|
68
|
+
agent-browser --session visual-qa wait 100
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
- Prefer URL or text waits for route and content changes.
|
|
72
|
+
- Use `networkidle` only when the action triggers real network activity.
|
|
73
|
+
- Use a short fixed wait only when an animation has no semantic completion signal.
|
|
74
|
+
- Run `snapshot -i` after navigation or significant DOM changes before using element refs.
|
|
75
|
+
|
|
76
|
+
For initial loading behavior, start recording before the first navigation:
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
agent-browser --session visual-qa set viewport 1440 900
|
|
80
|
+
agent-browser --session visual-qa record start /tmp/visual-qa-load.webm "$URL"
|
|
81
|
+
agent-browser --session visual-qa wait --load networkidle
|
|
82
|
+
agent-browser --session visual-qa record stop
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
For post-load interactions, explore first, then start recording. `record start` creates a fresh browser context and reloads the page, so discard earlier refs and run `snapshot -i` again before interacting. Stop recording as soon as the target behavior is captured. Never end a QA run with an active recording.
|
|
86
|
+
|
|
87
|
+
## Share Evidence
|
|
88
|
+
|
|
89
|
+
Use `sendFiles` for every artifact the user should receive:
|
|
90
|
+
|
|
91
|
+
```json
|
|
92
|
+
{
|
|
93
|
+
"files": [
|
|
94
|
+
{ "path": "/tmp/visual-qa.png" },
|
|
95
|
+
{ "path": "/tmp/visual-qa-load.webm" }
|
|
96
|
+
]
|
|
97
|
+
}
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
- Claim an artifact was shared only when `sendFiles` succeeds in this turn.
|
|
101
|
+
- If delivery fails or `sendFiles` is unavailable, report the error and saved paths without claiming attachment success.
|
|
102
|
+
|
|
103
|
+
## Protect Sensitive Data
|
|
104
|
+
|
|
105
|
+
Never capture or share credential entry, session tokens, customer data, or unrelated sensitive UI state. If reaching the target requires exposing that data, use an existing safe authenticated session or report the authentication requirement as a limitation or blocker.
|
|
106
|
+
|
|
107
|
+
## Report The Result
|
|
108
|
+
|
|
109
|
+
Report:
|
|
110
|
+
|
|
111
|
+
- **Target:** exact URL verified
|
|
112
|
+
- **Evidence:** screenshots, videos, and state checks gathered, with why each was chosen
|
|
113
|
+
- **Result:** pass, issues found, or blocked
|
|
114
|
+
- **Findings:** specific rendered behavior observed
|
|
115
|
+
- **Limitations:** requested pages, states, viewports, or themes not verified
|
|
116
|
+
|
|
117
|
+
Use **pass** only when the captured evidence matches the requested behavior without an obvious scoped regression. Use **issues found** for broken layout, incorrect motion, flicker, missing assets, or invalid states. Use **blocked** when no safe reachable target exists.
|
|
118
|
+
|
|
119
|
+
Never generalize beyond the evidence collected, and never claim a rendered change looks correct without opening a browser and gathering supporting evidence.
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Sources
|
|
2
|
+
|
|
3
|
+
## Migrated Skill
|
|
4
|
+
|
|
5
|
+
- Repository: `getsentry/junior-prod`
|
|
6
|
+
- Path: `app/skills/visual-web-qa`
|
|
7
|
+
- Source revision: `9c394b193bdc25d89ab65993b2b1073512253d25`
|
|
8
|
+
- Source date: July 1, 2026
|
|
9
|
+
- Migrated: July 23, 2026
|
|
10
|
+
- Trust: first-party Sentry repository
|
|
11
|
+
|
|
12
|
+
## Local Adaptations
|
|
13
|
+
|
|
14
|
+
- Replaced the removed `attachFile` tool with Junior's `sendFiles` tool and current file-object input contract
|
|
15
|
+
- Preserved the source skill's toolbox approach and its distinction between static screenshot evidence and temporal video evidence
|
|
16
|
+
- Converted the legacy `SPEC.md` maintenance document into a Skillet-compatible `spec.md` behavior contract
|
|
17
|
+
- Aligned the behavior contract with the runtime guidance, where a purely temporal request may use video without a redundant screenshot
|
|
18
|
+
- Clarified the routing boundary between evidence-driven `/visual-web-qa` and general-purpose `/agent-browser`
|
|
19
|
+
- Kept the skill inline because the runtime decisions and examples are short enough to remain coherent in one file
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
behavior: representative-coverage
|
|
2
|
+
prompt: |
|
|
3
|
+
A shared navigation and theme update affects the local pages in site/. Verify it across representative pages, desktop and mobile, and light and dark modes. Use the browser, save evidence under artifacts/, and collect useful coverage without exhaustively testing every page in every combination.
|
|
4
|
+
fixture: visual-site
|
|
5
|
+
setup: mkdir -p artifacts
|
|
6
|
+
checks:
|
|
7
|
+
- shell: test "$(find artifacts -type f -name '*.png' -size +1k | wc -l | tr -d ' ')" -ge 2
|
|
8
|
+
- judge: The report demonstrates a bounded representative sample of no more than four pages, names the captured page or state and viewport-theme evidence, gives the observed result, and acknowledges that it did not test every page in every combination.
|
|
9
|
+
timeout: 600
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
behavior: static-visual-verification
|
|
2
|
+
prompt: |
|
|
3
|
+
Verify the static card layout in site/index.html at representative desktop and mobile widths. This is a local fixture: actually open the rendered page in a browser, save the evidence under artifacts/, and report the result rather than reviewing only the source files.
|
|
4
|
+
fixture: visual-site
|
|
5
|
+
setup: mkdir -p artifacts
|
|
6
|
+
checks:
|
|
7
|
+
- shell: test "$(find artifacts -type f -name '*.png' -size +1k | wc -l | tr -d ' ')" -ge 2 && test "$(find artifacts -type f -name '*.webm' | wc -l | tr -d ' ')" -eq 0
|
|
8
|
+
- judge: The report names the exact rendered target, distinguishes desktop and mobile findings, gives an observed result, and states any limitations without claiming the evidence was shared when delivery tooling was unavailable.
|
|
9
|
+
timeout: 300
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
behavior: target-resolution
|
|
2
|
+
prompt: |
|
|
3
|
+
Verify the UI change on my unmerged branch. This workspace does not contain a built page or runnable app, the local development server is unavailable, and there is no preview deployment. Production is reachable.
|
|
4
|
+
checks:
|
|
5
|
+
- judge: The agent investigates enough to confirm there is no valid local or preview target, reports the visual QA run as blocked, identifies what is needed to continue, and does not use production to claim the unmerged change is present.
|
|
6
|
+
timeout: 300
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
behavior: temporal-visual-verification
|
|
2
|
+
prompt: |
|
|
3
|
+
Verify the initial skeleton loading state and the menu open/close interaction in site/loading.html. Actually run the local page in a browser, save the evidence under artifacts/, and capture the sequence rather than only describing a plan.
|
|
4
|
+
fixture: visual-site
|
|
5
|
+
setup: mkdir -p artifacts
|
|
6
|
+
checks:
|
|
7
|
+
- shell: test "$(find artifacts -type f -name '*.webm' -size +1k | wc -l | tr -d ' ')" -ge 1 && find artifacts -type f -name '*.webm' -exec file {} \; | grep -q WebM
|
|
8
|
+
- judge: The report identifies the saved video evidence, describes the initial skeleton, loaded state, menu-open state, and menu-closed state, gives the observed result, and does not falsely claim artifact delivery.
|
|
9
|
+
timeout: 600
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
+
<title>Guide - Visual QA Fixture</title>
|
|
7
|
+
<link rel="stylesheet" href="styles.css" />
|
|
8
|
+
</head>
|
|
9
|
+
<body>
|
|
10
|
+
<header>
|
|
11
|
+
<strong>Junior Docs</strong>
|
|
12
|
+
<nav aria-label="Primary navigation">
|
|
13
|
+
<a href="index.html">Overview</a>
|
|
14
|
+
<a href="guide.html">Guide</a>
|
|
15
|
+
<a href="reference.html">Reference</a>
|
|
16
|
+
</nav>
|
|
17
|
+
<button id="theme-toggle" type="button">Toggle theme</button>
|
|
18
|
+
</header>
|
|
19
|
+
<main>
|
|
20
|
+
<h1>Visual verification guide</h1>
|
|
21
|
+
<section class="panel">
|
|
22
|
+
<h2>Choose representative evidence</h2>
|
|
23
|
+
<p>Match screenshots and recordings to the behavior being verified.</p>
|
|
24
|
+
</section>
|
|
25
|
+
</main>
|
|
26
|
+
<script>
|
|
27
|
+
document.querySelector("#theme-toggle").addEventListener("click", () => {
|
|
28
|
+
document.documentElement.dataset.theme =
|
|
29
|
+
document.documentElement.dataset.theme === "dark" ? "light" : "dark";
|
|
30
|
+
});
|
|
31
|
+
</script>
|
|
32
|
+
</body>
|
|
33
|
+
</html>
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
+
<title>Visual QA Fixture</title>
|
|
7
|
+
<link rel="stylesheet" href="styles.css" />
|
|
8
|
+
</head>
|
|
9
|
+
<body>
|
|
10
|
+
<header>
|
|
11
|
+
<strong>Junior Docs</strong>
|
|
12
|
+
<nav aria-label="Primary navigation">
|
|
13
|
+
<a href="index.html">Overview</a>
|
|
14
|
+
<a href="guide.html">Guide</a>
|
|
15
|
+
<a href="reference.html">Reference</a>
|
|
16
|
+
</nav>
|
|
17
|
+
<button id="theme-toggle" type="button">Toggle theme</button>
|
|
18
|
+
</header>
|
|
19
|
+
<main>
|
|
20
|
+
<h1>Build reliable agent workflows</h1>
|
|
21
|
+
<p>Reusable guidance for common implementation and verification tasks.</p>
|
|
22
|
+
<section class="cards" aria-label="Documentation topics">
|
|
23
|
+
<article class="card">
|
|
24
|
+
<h2>Install</h2>
|
|
25
|
+
<p>
|
|
26
|
+
Add the plugin package and enable it in your Junior configuration.
|
|
27
|
+
</p>
|
|
28
|
+
</article>
|
|
29
|
+
<article class="card">
|
|
30
|
+
<h2>Configure</h2>
|
|
31
|
+
<p>Provision runtime dependencies and choose the right workflow.</p>
|
|
32
|
+
</article>
|
|
33
|
+
<article class="card">
|
|
34
|
+
<h2>Verify</h2>
|
|
35
|
+
<p>
|
|
36
|
+
Collect browser evidence and report only what the evidence supports.
|
|
37
|
+
</p>
|
|
38
|
+
</article>
|
|
39
|
+
</section>
|
|
40
|
+
</main>
|
|
41
|
+
<script>
|
|
42
|
+
document.querySelector("#theme-toggle").addEventListener("click", () => {
|
|
43
|
+
document.documentElement.dataset.theme =
|
|
44
|
+
document.documentElement.dataset.theme === "dark" ? "light" : "dark";
|
|
45
|
+
});
|
|
46
|
+
</script>
|
|
47
|
+
</body>
|
|
48
|
+
</html>
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
+
<title>Loading - Visual QA Fixture</title>
|
|
7
|
+
<link rel="stylesheet" href="styles.css" />
|
|
8
|
+
</head>
|
|
9
|
+
<body>
|
|
10
|
+
<header>
|
|
11
|
+
<strong>Junior Docs</strong>
|
|
12
|
+
<nav aria-label="Primary navigation">
|
|
13
|
+
<a href="index.html">Overview</a>
|
|
14
|
+
<a href="guide.html">Guide</a>
|
|
15
|
+
<a href="reference.html">Reference</a>
|
|
16
|
+
</nav>
|
|
17
|
+
</header>
|
|
18
|
+
<main>
|
|
19
|
+
<section id="loading" class="panel skeleton" aria-label="Loading content">
|
|
20
|
+
<span></span>
|
|
21
|
+
<span></span>
|
|
22
|
+
<span></span>
|
|
23
|
+
</section>
|
|
24
|
+
<section id="content" class="panel hidden">
|
|
25
|
+
<h1>Loaded documentation</h1>
|
|
26
|
+
<button id="menu-toggle" type="button" aria-expanded="false">
|
|
27
|
+
Open menu
|
|
28
|
+
</button>
|
|
29
|
+
<div id="menu" class="menu hidden" role="menu">
|
|
30
|
+
<a href="guide.html" role="menuitem">Read the guide</a>
|
|
31
|
+
</div>
|
|
32
|
+
</section>
|
|
33
|
+
</main>
|
|
34
|
+
<script>
|
|
35
|
+
window.setTimeout(() => {
|
|
36
|
+
document.querySelector("#loading").classList.add("hidden");
|
|
37
|
+
document.querySelector("#content").classList.remove("hidden");
|
|
38
|
+
}, 900);
|
|
39
|
+
|
|
40
|
+
document
|
|
41
|
+
.querySelector("#menu-toggle")
|
|
42
|
+
.addEventListener("click", (event) => {
|
|
43
|
+
const button = event.currentTarget;
|
|
44
|
+
const menu = document.querySelector("#menu");
|
|
45
|
+
const expanded = button.getAttribute("aria-expanded") === "true";
|
|
46
|
+
button.setAttribute("aria-expanded", String(!expanded));
|
|
47
|
+
button.textContent = expanded ? "Open menu" : "Close menu";
|
|
48
|
+
menu.classList.toggle("hidden", expanded);
|
|
49
|
+
});
|
|
50
|
+
</script>
|
|
51
|
+
</body>
|
|
52
|
+
</html>
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
+
<title>Reference - Visual QA Fixture</title>
|
|
7
|
+
<link rel="stylesheet" href="styles.css" />
|
|
8
|
+
</head>
|
|
9
|
+
<body>
|
|
10
|
+
<header>
|
|
11
|
+
<strong>Junior Docs</strong>
|
|
12
|
+
<nav aria-label="Primary navigation">
|
|
13
|
+
<a href="index.html">Overview</a>
|
|
14
|
+
<a href="guide.html">Guide</a>
|
|
15
|
+
<a href="reference.html">Reference</a>
|
|
16
|
+
</nav>
|
|
17
|
+
<button id="theme-toggle" type="button">Toggle theme</button>
|
|
18
|
+
</header>
|
|
19
|
+
<main>
|
|
20
|
+
<h1>Command reference</h1>
|
|
21
|
+
<section class="panel">
|
|
22
|
+
<h2>Capture</h2>
|
|
23
|
+
<p>Open, wait, snapshot, interact, capture, and report.</p>
|
|
24
|
+
</section>
|
|
25
|
+
</main>
|
|
26
|
+
<script>
|
|
27
|
+
document.querySelector("#theme-toggle").addEventListener("click", () => {
|
|
28
|
+
document.documentElement.dataset.theme =
|
|
29
|
+
document.documentElement.dataset.theme === "dark" ? "light" : "dark";
|
|
30
|
+
});
|
|
31
|
+
</script>
|
|
32
|
+
</body>
|
|
33
|
+
</html>
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
:root {
|
|
2
|
+
color-scheme: light;
|
|
3
|
+
font-family: Inter, ui-sans-serif, system-ui, sans-serif;
|
|
4
|
+
background: #f4f6f8;
|
|
5
|
+
color: #17202a;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
:root[data-theme="dark"] {
|
|
9
|
+
color-scheme: dark;
|
|
10
|
+
background: #101820;
|
|
11
|
+
color: #edf2f7;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
* {
|
|
15
|
+
box-sizing: border-box;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
body {
|
|
19
|
+
margin: 0;
|
|
20
|
+
min-height: 100vh;
|
|
21
|
+
background: inherit;
|
|
22
|
+
color: inherit;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
header {
|
|
26
|
+
align-items: center;
|
|
27
|
+
background: #ffffff;
|
|
28
|
+
border-bottom: 1px solid #d8dee6;
|
|
29
|
+
display: flex;
|
|
30
|
+
gap: 24px;
|
|
31
|
+
justify-content: space-between;
|
|
32
|
+
padding: 16px 32px;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
:root[data-theme="dark"] header,
|
|
36
|
+
:root[data-theme="dark"] .card,
|
|
37
|
+
:root[data-theme="dark"] .panel {
|
|
38
|
+
background: #18232e;
|
|
39
|
+
border-color: #334252;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
nav {
|
|
43
|
+
display: flex;
|
|
44
|
+
gap: 16px;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
a {
|
|
48
|
+
color: #1665d8;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
:root[data-theme="dark"] a {
|
|
52
|
+
color: #7db7ff;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
button {
|
|
56
|
+
background: #1665d8;
|
|
57
|
+
border: 0;
|
|
58
|
+
border-radius: 8px;
|
|
59
|
+
color: #ffffff;
|
|
60
|
+
cursor: pointer;
|
|
61
|
+
padding: 10px 14px;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
main {
|
|
65
|
+
margin: 0 auto;
|
|
66
|
+
max-width: 1120px;
|
|
67
|
+
padding: 48px 32px;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
.cards {
|
|
71
|
+
display: grid;
|
|
72
|
+
gap: 24px;
|
|
73
|
+
grid-template-columns: repeat(3, minmax(0, 1fr));
|
|
74
|
+
margin-top: 32px;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
.card,
|
|
78
|
+
.panel {
|
|
79
|
+
background: #ffffff;
|
|
80
|
+
border: 1px solid #d8dee6;
|
|
81
|
+
border-radius: 14px;
|
|
82
|
+
padding: 24px;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
.card h2 {
|
|
86
|
+
font-size: 20px;
|
|
87
|
+
line-height: 1.25;
|
|
88
|
+
margin: 0 0 12px;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
.card p {
|
|
92
|
+
line-height: 1.6;
|
|
93
|
+
margin: 0;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
.skeleton {
|
|
97
|
+
display: grid;
|
|
98
|
+
gap: 14px;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
.skeleton span {
|
|
102
|
+
animation: pulse 0.8s ease-in-out infinite alternate;
|
|
103
|
+
background: #c9d2dc;
|
|
104
|
+
border-radius: 8px;
|
|
105
|
+
display: block;
|
|
106
|
+
height: 22px;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
.skeleton span:first-child {
|
|
110
|
+
width: 55%;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
.hidden {
|
|
114
|
+
display: none;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
.menu {
|
|
118
|
+
margin-top: 16px;
|
|
119
|
+
opacity: 1;
|
|
120
|
+
transform: translateY(0);
|
|
121
|
+
transition:
|
|
122
|
+
opacity 180ms ease,
|
|
123
|
+
transform 180ms ease;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
.menu.hidden {
|
|
127
|
+
display: block;
|
|
128
|
+
opacity: 0;
|
|
129
|
+
pointer-events: none;
|
|
130
|
+
transform: translateY(-8px);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
@keyframes pulse {
|
|
134
|
+
from {
|
|
135
|
+
opacity: 0.45;
|
|
136
|
+
}
|
|
137
|
+
to {
|
|
138
|
+
opacity: 1;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
@media (max-width: 700px) {
|
|
143
|
+
header {
|
|
144
|
+
align-items: flex-start;
|
|
145
|
+
flex-direction: column;
|
|
146
|
+
padding: 16px 20px;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
nav {
|
|
150
|
+
flex-wrap: wrap;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
main {
|
|
154
|
+
padding: 32px 20px;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
.cards {
|
|
158
|
+
grid-template-columns: 1fr;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# Visual Web QA
|
|
2
|
+
|
|
3
|
+
## Intent
|
|
4
|
+
|
|
5
|
+
This skill makes the agent verify user-visible web changes by opening the rendered surface in a real browser, collecting evidence appropriate to the behavior, and reporting only what that evidence supports. It keeps coverage representative, avoids unsafe targets or sensitive capture, and distinguishes visual QA from general browser automation.
|
|
6
|
+
|
|
7
|
+
## Triggers
|
|
8
|
+
|
|
9
|
+
- **SHOULD** apply when a user asks whether frontend, docs, CSS, layout, theme, responsive, navigation, loading, animation, or interaction changes look correct.
|
|
10
|
+
- **SHOULD** apply when a visual change needs browser evidence across relevant states, viewports, or themes.
|
|
11
|
+
- **SHOULD NOT** apply to backend-only, CLI, library-internal, test-only, or non-rendered configuration changes.
|
|
12
|
+
- **SHOULD NOT** apply to general browser navigation, extraction, or form automation without a visual correctness question; use the general `agent-browser` workflow instead.
|
|
13
|
+
- **SHOULD NOT** apply when the user explicitly opts out of browser verification.
|
|
14
|
+
|
|
15
|
+
## Behaviors
|
|
16
|
+
|
|
17
|
+
### Behavior: Static visual verification
|
|
18
|
+
|
|
19
|
+
The agent SHALL open stable rendered states in a browser, capture screenshots as primary evidence, and report the exact target, covered states, result, findings, and limitations.
|
|
20
|
+
|
|
21
|
+
#### Scenario: Verify a responsive card layout
|
|
22
|
+
|
|
23
|
+
- **WHEN** a user asks to verify static spacing and typography on a local page at desktop and mobile widths
|
|
24
|
+
- **THEN** the agent opens the page in a browser, captures desktop and mobile screenshots without unnecessary video, and reports what those screenshots establish
|
|
25
|
+
|
|
26
|
+
### Behavior: Temporal visual verification
|
|
27
|
+
|
|
28
|
+
The agent SHALL use short video for loading, animation, transition, or interaction sequences; start initial-load recording before navigation; refresh element references after recording reloads or DOM changes; use meaningful waits; and stop recording when the target behavior is captured.
|
|
29
|
+
|
|
30
|
+
#### Scenario: Verify loading and menu behavior
|
|
31
|
+
|
|
32
|
+
- **WHEN** a local page has an initial skeleton followed by an interactive menu transition
|
|
33
|
+
- **THEN** the agent records the initial load before navigation, obtains fresh references for the interaction, captures the menu sequence, stops recording, and reports the temporal evidence
|
|
34
|
+
|
|
35
|
+
### Behavior: Representative coverage
|
|
36
|
+
|
|
37
|
+
The agent SHALL use the browser to verify a small representative set of pages, states, viewports, and themes most likely to expose the requested regression rather than creating an exhaustive matrix by default.
|
|
38
|
+
|
|
39
|
+
#### Scenario: Verify a shared docs theme
|
|
40
|
+
|
|
41
|
+
- **WHEN** a shared navigation and theme change affects several local docs pages across desktop, mobile, light, and dark modes
|
|
42
|
+
- **THEN** the agent opens and captures one to four representative surfaces and relevant combinations, then reports both the covered evidence and any combinations not checked
|
|
43
|
+
|
|
44
|
+
### Behavior: Target resolution
|
|
45
|
+
|
|
46
|
+
The agent SHALL use a user-provided, local, or preview target for changed code, use production only as an explicitly requested or read-only baseline, and report blocked when no valid target is reachable.
|
|
47
|
+
|
|
48
|
+
#### Scenario: Unmerged change has no runnable target
|
|
49
|
+
|
|
50
|
+
- **WHEN** a user asks to verify an unmerged frontend change but the workspace has no runnable page, local server, or preview deployment
|
|
51
|
+
- **THEN** the agent investigates enough to confirm the missing target and reports blocked instead of checking production and claiming the change is present
|
|
52
|
+
|
|
53
|
+
## Constraints
|
|
54
|
+
|
|
55
|
+
### Constraint: Evidence required
|
|
56
|
+
|
|
57
|
+
The agent MUST NOT claim that a rendered change looks correct from code inspection alone or without browser evidence that supports the claim.
|
|
58
|
+
|
|
59
|
+
### Constraint: Artifact delivery claims
|
|
60
|
+
|
|
61
|
+
The agent MUST NOT claim a screenshot or video was shared unless `sendFiles` succeeded; when delivery is unavailable or fails, it must report the saved path and limitation.
|
|
62
|
+
|
|
63
|
+
### Constraint: Production claims
|
|
64
|
+
|
|
65
|
+
The agent MUST NOT imply that unmerged code is visible on production unless the verified production target actually contains that code.
|
|
66
|
+
|
|
67
|
+
### Constraint: Recording lifecycle
|
|
68
|
+
|
|
69
|
+
The agent MUST NOT leave an active video recording running after the target behavior has been captured or the QA run ends.
|
|
70
|
+
|
|
71
|
+
### Constraint: Sensitive capture
|
|
72
|
+
|
|
73
|
+
The agent MUST NOT record, screenshot, or share credential entry, session tokens, customer data, or unrelated sensitive interface state.
|