Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .claude-plugin/marketplace.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@
"description": "Generate Playwright integration tests for Vaadin views using the DramaFinder library."
},
{
"name": "visual-verification",
"source": "./skills/visual-verification",
"description": "Visually verify Vaadin UI changes with a temporary DramaFinder test that batch-captures screenshots against the running app."
"name": "vaadin-playwright-screenshot",
"source": "./skills/vaadin-playwright-screenshot",
"description": "Capture screenshots of a running Vaadin app with a temporary DramaFinder test that batch-captures every key visual state in one run."
}
]
}
84 changes: 84 additions & 0 deletions .github/workflows/agent-api-reference.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
name: Agent API Reference

# Keeps skills/vaadin-playwright-screenshot/agent-api-reference.md in lock-step
# with the org.vaadin.addons.dramafinder.agent helpers.
#
# - On push (master / issue branches): regenerate and commit the result back to
# the branch, so the reference updates itself with no manual step.
# - On pull_request: regenerate and FAIL if the committed file is stale. Push
# events from a fork have a read-only token and cannot auto-commit, so this
# verify-only job is what catches an out-of-date reference in a fork PR.
#
# The push path filter excludes agent-api-reference.md itself, so the bot's own
# commit does not re-trigger the workflow (no loop).

on:
push:
branches:
- master
- 'issue-**'
paths:
- 'src/main/java/org/vaadin/addons/dramafinder/agent/**'
- 'tools/generate-agent-api-reference.java'
- '.github/workflows/agent-api-reference.yml'
pull_request:
branches: [ master ]
paths:
- 'src/main/java/org/vaadin/addons/dramafinder/agent/**'
- 'tools/generate-agent-api-reference.java'
- '.github/workflows/agent-api-reference.yml'

permissions:
contents: write

jobs:
update-agent-api-reference:
# Auto-commit path — only on push (needs write access to the branch).
if: github.event_name == 'push'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.ref_name }}
- name: Set up JDK 21
uses: actions/setup-java@v4
with:
java-version: '21'
distribution: 'temurin'
- name: Set up JBang
uses: jbangdev/setup-jbang@main
- name: Regenerate agent API reference
run: jbang tools/generate-agent-api-reference.java
- name: Commit the regenerated reference if it changed
run: |
if git diff --quiet skills/vaadin-playwright-screenshot/agent-api-reference.md; then
echo "agent-api-reference.md is already up to date."
else
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git add skills/vaadin-playwright-screenshot/agent-api-reference.md
git commit -m "Regenerate agent-api-reference.md [skip ci]"
git push origin HEAD:${{ github.ref_name }}
fi

verify-agent-api-reference:
# Verify-only path — for pull requests (incl. forks, whose token is read-only).
if: github.event_name == 'pull_request'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up JDK 21
uses: actions/setup-java@v4
with:
java-version: '21'
distribution: 'temurin'
- name: Set up JBang
uses: jbangdev/setup-jbang@main
- name: Regenerate agent API reference
run: jbang tools/generate-agent-api-reference.java
- name: Fail if the committed reference is out of date
run: |
if ! git diff --exit-code skills/vaadin-playwright-screenshot/agent-api-reference.md; then
echo "::error::agent-api-reference.md is stale. Run 'jbang tools/generate-agent-api-reference.java' and commit the result."
exit 1
fi
14 changes: 0 additions & 14 deletions .github/workflows/tessl-publish.yml

This file was deleted.

15 changes: 0 additions & 15 deletions .github/workflows/tessl-review.yml

This file was deleted.

5 changes: 5 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -261,5 +261,10 @@ public static ButtonElement getByText(Locator locator, String text) { ... }
- `api-reference.md` is generated — never edit it by hand. After changing any
element's public API, regenerate it (`jbang tools/generate-api-reference.java`)
and commit the result; CI fails if it is stale.
- The `org.vaadin.addons.dramafinder.agent` helpers (`VisualVerificationTest`,
`AgentReporting`, …) have their own generated reference at
`skills/vaadin-playwright-screenshot/agent-api-reference.md`
(`tools/generate-agent-api-reference.java`; same never-edit-by-hand, CI-enforced
rule). After changing that package's public API, regenerate and commit it.
- Refer to `docs/specifications/` for the prose docs on components with
non-obvious behaviour (Grid, TreeGrid, VirtualList, and extension guidance).
14 changes: 7 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,17 @@ This repository ships two Claude Code skills. Install them as plugins:
```
/plugin marketplace add parttio/dramafinder
/plugin install vaadin-playwright-test@dramafinder
/plugin install visual-verification@dramafinder
/plugin install vaadin-playwright-screenshot@dramafinder
```

- **vaadin-playwright-test** — generates Playwright integration tests for
Vaadin views using Drama Finder.
- **visual-verification** — visually verifies UI changes by writing a temporary
Drama Finder test that batch-captures screenshots against the running app,
then reviewing them. Backed by the `org.vaadin.addons.dramafinder.agent`
helpers (`VisualVerificationTest`, `AgentReporting`, `ComponentSnapshot`), which
write a screenshot, semantic component snapshot, and stack trace to
`target/agent-report/` on failure.
- **vaadin-playwright-screenshot** — captures screenshots of UI changes by
writing a temporary Drama Finder test that batch-captures every key visual
state against the running app in one run. Backed by the
`org.vaadin.addons.dramafinder.agent` helpers (`VisualVerificationTest`,
`AgentReporting`, `ComponentSnapshot`), which write a screenshot, semantic
component snapshot, and stack trace to `target/agent-report/` on failure.

To get later updates, run `/plugin marketplace update dramafinder`.

Expand Down
10 changes: 10 additions & 0 deletions skills/vaadin-playwright-screenshot/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"name": "vaadin-playwright-screenshot",
"description": "Capture screenshots of a running Vaadin app by writing a temporary DramaFinder test that batch-captures every key visual state in one run — a cheap alternative to interactive Playwright MCP.",
"version": "0.1.0",
"author": {
"name": "jcgueriaud1"
},
"homepage": "https://github.com/parttio/dramafinder",
"repository": "https://github.com/parttio/dramafinder"
}
133 changes: 133 additions & 0 deletions skills/vaadin-playwright-screenshot/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
---
name: vaadin-playwright-screenshot
description: Capture screenshots of a running DramaFinder/Vaadin app by writing a temporary Java/Playwright test that batch-captures every key visual state in one run. Pass the acceptance criteria to screenshot as the argument. Use after implementing UI changes when you need screenshots to review.
---

# Vaadin Playwright Screenshot

> **Invoke this skill via the Skill tool — do not just read this `SKILL.md`.**
> Invoking is what loads this guidance (and anything it references) into
> context.

To capture what the user sees, **do not drive the browser interactively via MCP
by default** — write a temporary DramaFinder test that performs the whole flow
and captures all screenshots in one batch run. One run replaces dozens of MCP
round-trips and avoids accessibility-tree dumps entirely. Then review the
captured images.

## Input: the acceptance criteria to screenshot

This skill takes **acceptance criteria** as its argument — the testable
statements the UI must satisfy. Each criterion tells you *what to screenshot*:
one screenshot that proves it holds. The argument may be either:

- **Inline criteria**, e.g. "Login page shows email + password fields",
"Invalid login shows an error notification", "After login, the order list is
visible"; or
- **A reference** to where the criteria live — a spec file
(`docs/specs/checkout.md`), a ticket ID, a section heading. Read the reference
and extract the criteria before writing the test.

If nothing is provided, ask for the criteria (or derive them from the spec /
ticket for the change under test) before writing the test — the criteria are
what the capture run must cover, one screenshot each. Map every criterion to at
least one `shot(...)`, and use the criterion text to name the shot.

Unless a criterion specifies otherwise, use a **1920x1080** viewport.

## Prerequisite: the DramaFinder agent helpers must be available

This skill relies on the `org.vaadin.addons.dramafinder.agent` helpers
(`VisualVerificationTest`, `AgentReporting`), which ship inside DramaFinder
**1.1.6 and later**. They're on the classpath of any project that depends on a
recent enough DramaFinder — no per-project setup. If `VisualVerificationTest`
won't resolve, the project is on an older DramaFinder (or doesn't depend on it):
stop and say so rather than hand-rolling an equivalent base class.

## Prerequisite: the application must be running

The temp test connects to an **already running** application — it never boots
the app itself. Keeping the app out of the test run is what makes iterations
cheap. Before running the capture test:

1. Check whether the app already responds on its URL.
2. If it doesn't, start it the way this project runs its app. Start it in the
background, wait for it to answer, and remember that you started it so you
can stop it afterwards.

## The capture loop

1. Ensure the app is running with the required state (see prerequisite above
and "Reaching the state" below).
2. Write the temp test at
`src/test/java/<project-package>/agent/AgentVerifyIT.java`
(fixed name, fixed `agent` sub-package — overwrite the previous one, never
commit it). Extend
`org.vaadin.addons.dramafinder.agent.VisualVerificationTest`,
which already wires in the `AgentReporting` extension. Capture one screenshot
per acceptance criterion.
3. Run only that test with the project's build tool, with quiet output:
- Maven: `mvn -q surefire:test -Dtest=AgentVerifyIT`
- Gradle: `./gradlew test --tests '*.AgentVerifyIT' --console=plain -q`
If a `scripts/agent-verify.*` wrapper exists in the project, prefer it —
it
prints only pass/fail, assertion messages, and the report path.
Point the test at a non-default host/port with
`-Ddramafinder.agent.baseUrl=http://localhost:9000` (or the
`DRAMAFINDER_BASE_URL` env var). Run with `-Dheadless=false` to watch it.
4. Read the report directory — `target/agent-report/` (Maven) or
`build/agent-report/` (Gradle): it holds each numbered screenshot
(`01-…png`, `02-…png`, …). On failure the `AgentReporting` extension also
writes `failure.txt` (assertion message + trimmed stack trace + URL),
`failure.png` (full-page screenshot), and `component-snapshot.txt` (semantic
component snapshot). Review the captured images against the acceptance
criteria.
5. Record, per criterion, whether its screenshot confirms it. Delete or
overwrite the temp test when done.

## Writing the temp test

Write the test as a normal DramaFinder test. For how to locate Vaadin components
and assert on them, **invoke the `vaadin-playwright-test` skill via the Skill
tool** (don't just read its `SKILL.md` — invoking is what loads its bundled API
reference). This skill only adds the visual-capture concerns on top of it:

- Extend `org.vaadin.addons.dramafinder.agent.VisualVerificationTest` (not the
usual base class) — it connects to the already-running app, wires in the
`AgentReporting` extension, and sets a 1920x1080 viewport. Override the
viewport per test, and add 375x812 and 768x1024 passes when a criterion has
responsive requirements.
- For the exact API of `VisualVerificationTest` and the other agent helpers
(`open`, `shot`, `baseUrl`, the report/snapshot types), read the bundled
**`agent-api-reference.md`** next to this file — **do not unzip the DramaFinder
sources jar**. In a consumer project where the skill isn't checked out, fetch
it (one request) from
`https://raw.githubusercontent.com/parttio/dramafinder/master/skills/vaadin-playwright-screenshot/agent-api-reference.md`.
- `shot("name")` for each acceptance criterion and each **unique visual state**
along the way — named after the criterion (`01-login-fields`,
`02-invalid-login-error`, `03-order-list`). Screenshots are auto-numbered into
the report directory.
- Assert behavior only lightly (enough to know the flow progressed). Behaviour
is covered by the behavioral tests (pyramid layer 3) — don't duplicate those
assertions here. Screenshots that prove each criterion are the deliverable.

## Reaching the state

- **Deep-link with stable selectors** where possible; drive elements by
DramaFinder locators, button text, `aria-label`, or stable `name` attributes.
- If a criterion needs data or a logged-in user, script the minimal setup steps
inside the same temp test — still one batch run, never set up state
interactively via MCP. Screenshot only the states the criteria call for, not
the setup steps.

## Steps

All steps must be done; thoroughness over speed.

1. Acceptance criteria in hand (provided as the argument, or gathered from the
spec/ticket)
2. App running (started by you if needed) with the required state
3. Temp test reaches the state each criterion describes and captures one
screenshot per criterion (plus any unique intermediate states)
4. Screenshots reviewed against the acceptance criteria
5. Results recorded — note, per criterion, pass/fail and any visual issues
71 changes: 71 additions & 0 deletions skills/vaadin-playwright-screenshot/agent-api-reference.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# DramaFinder Agent Helpers API Reference

> **Auto-generated from source — do not edit by hand.** Regenerate with `jbang tools/generate-agent-api-reference.java`.
> DramaFinder 1.1.6-SNAPSHOT — 5 agent helper types.

Public API of the `org.vaadin.addons.dramafinder.agent` helpers used by the **vaadin-playwright-screenshot** skill. Method one-liners come from Javadoc.

**Do not download or unzip the DramaFinder jar to discover this API — it is all here.**

A temp verification test extends `VisualVerificationTest`; the other types are its supporting cast (the failure-report writer, the JUnit extension, and the semantic component snapshot).

## Types

[VisualVerificationTest](#visualverificationtest) · [AgentReport](#agentreport) · [AgentReportProvider](#agentreportprovider) · [AgentReporting](#agentreporting) · [ComponentSnapshot](#componentsnapshot)

## VisualVerificationTest

Base class for temporary, agent-driven visual verification tests that run against an <strong>already running</strong> application.

*abstract class* · **implements** AgentReportProvider

**Methods:**

- `String baseUrl()` — The base URL the test connects to.
- `void open(String path)` — Navigate to a path relative to the configured base URL and wait for Vaadin to finish loading.
- `void shot(String name)` — Capture a numbered screenshot into the report directory.

## AgentReport

Writes agent-oriented verification artifacts for a single test into a report directory (target/agent-report/ for Maven, build/agent-report/ for Gradle).

**Constructors:**

- `AgentReport(Page page)` — Create a report writing into the build-tool default directory.
- `AgentReport(Page page, Path directory)` — Create a report writing into the given directory.

**Static methods:**

- `Path defaultReportDirectory()` — Resolve the default report directory for the current build tool: build/agent-report when a Gradle build file is present, otherwise target/agent-report (Maven).

**Methods:**

- `void captureFailure(Throwable error)` — Write the failure bundle for a failed test: failure.txt (message + trimmed stack trace + page URL), failure.png (full-page screenshot), and component-snapshot.txt (semantic snapshot).
- `Path directory()` — The directory this report writes to.
- `Path shot(String name)` — Capture a numbered screenshot of the current page state.

## AgentReportProvider

Implemented by tests that want the AgentReporting extension to write a failure bundle using a specific page and report instance.

*interface*

**Methods:**

- `Page agentPage()` — The page the extension should screenshot and inspect on failure.
- `AgentReport agentReport()` — The report the extension should write the failure bundle into.

## AgentReporting

JUnit 5 extension that, on test failure, writes an agent-oriented report to target/agent-report/ (Maven) or build/agent-report/ (Gradle): a failure.txt with the assertion message and a trimmed stack trace, a screenshot of the page at failure time, and a semantic ComponentSnapshot component snapshot.

**implements** AfterTestExecutionCallback

## ComponentSnapshot

Produces a compact, human- and agent-readable summary of the Vaadin components currently present on a page.

**Static methods:**

- `String capture(Page page)` — Capture a compact snapshot of all meaningful Vaadin components on the page.

Loading
Loading