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: 6 additions & 0 deletions .github/workflows/api-reference.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,18 @@ on:
- 'issue-**'
paths:
- 'src/main/java/org/vaadin/addons/dramafinder/element/**'
# The root-package types (AbstractBasePlaywrightIT, HasTestView) are in
# the reference's "Test setup" section, so they trigger it too.
- 'src/main/java/org/vaadin/addons/dramafinder/*.java'
- 'tools/generate-api-reference.java'
- '.github/workflows/api-reference.yml'
pull_request:
branches: [ master ]
paths:
- 'src/main/java/org/vaadin/addons/dramafinder/element/**'
# The root-package types (AbstractBasePlaywrightIT, HasTestView) are in
# the reference's "Test setup" section, so they trigger it too.
- 'src/main/java/org/vaadin/addons/dramafinder/*.java'
- 'tools/generate-api-reference.java'
- '.github/workflows/api-reference.yml'

Expand Down
26 changes: 18 additions & 8 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -307,14 +307,24 @@ public static ButtonElement getByText(Locator locator, String text) { ... }
- Follow this file's conventions for any edits. Keep patches minimal and
focused.
- Use `*IT.java` only for end-to-end tests executed by Failsafe.
- **Never download or unzip the DramaFinder jar/sources to discover its API.**
The complete public API (every element, signatures, one-line descriptions) is
in `skills/vaadin-playwright-test/api-reference.md`, auto-generated from source
by `tools/generate-api-reference.java`. To look something up, **grep that file
for the element name and read only its `### <Name>Element` section** — don't
read the whole file. In a consumer project where it isn't checked out, fetch
it (one request) from
`https://raw.githubusercontent.com/parttio/dramafinder/master/skills/vaadin-playwright-test/api-reference.md`.
- **Never decompile the DramaFinder jar to discover its API.**
The complete public API (test setup, every element, signatures, one-line
descriptions) is in `skills/vaadin-playwright-test/api-reference.md`,
auto-generated from source by `tools/generate-api-reference.java`. To look
something up, **grep that file for the element name and read only its
`### <Name>Element` section** — don't read the whole file. In a consumer
project where it isn't checked out, fetch it (one request) from
`https://raw.githubusercontent.com/parttio/dramafinder/master/skills/vaadin-playwright-test/api-reference.md`,
or, with no network, read the copy bundled in the jar:
`unzip -p ~/.m2/repository/org/vaadin/addons/dramafinder/*/dramafinder-*.jar META-INF/dramafinder/api-reference.md`.
- The build copies `api-reference.md` and `agent-api-reference.md` into the jar
under `META-INF/dramafinder/` (see `maven-resources-plugin` in `pom.xml`), next
to the hand-written `src/main/resources/META-INF/dramafinder/START-HERE.md`.
That bundled set is the only documentation an offline agent can reach — Maven
puts nothing but the jar and the pom in `~/.m2` — so keep it working:
`DocumentationBundledInJarTest` fails if a file stops being bundled, and
`START-HERE.md` needs a manual look whenever the setup API or the pitfalls
change.
- `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.
Expand Down
6 changes: 4 additions & 2 deletions GEMINI.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,14 @@ mvn -Pit verify

## Available Element Classes

> **Never download or unzip the DramaFinder jar/sources to discover its API.**
> **Never decompile the DramaFinder jar to discover its API.**
> The complete, always-current public API (every element, its methods,
> signatures and one-line descriptions) is in
> `skills/vaadin-playwright-test/api-reference.md`, auto-generated from source.
> Read that file — in a consumer project, fetch it from
> `https://raw.githubusercontent.com/parttio/dramafinder/master/skills/vaadin-playwright-test/api-reference.md`.
> `https://raw.githubusercontent.com/parttio/dramafinder/master/skills/vaadin-playwright-test/api-reference.md`,
> or, with no network, read the copy bundled in the jar:
> `unzip -p ~/.m2/repository/org/vaadin/addons/dramafinder/*/dramafinder-*.jar META-INF/dramafinder/api-reference.md`.
> The table below is a component→class overview only.

Each element class wraps a Playwright `Locator` and provides typed helpers (getters, actions, assertions) for a specific Vaadin component. They all extend `VaadinElement` and are annotated with `@PlaywrightElement`.
Expand Down
17 changes: 17 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,23 @@

The documentation can be found in this repository and also deployed on https://parttio-dramafinder.mintlify.app/ if you find some errors please file an issue.

### API reference (and offline agents)

The complete public API — test setup, every element wrapper, every signature —
is generated from source into
[skills/vaadin-playwright-test/api-reference.md](skills/vaadin-playwright-test/api-reference.md).

The same file ships **inside the jar**, so it is readable with no network and no
checkout. That is the copy to reach for in a consumer project, and the reason
there is never a need to run `javap` on the classes:

```
JAR=$(ls ~/.m2/repository/org/vaadin/addons/dramafinder/*/dramafinder-*.jar | tail -1)
unzip -p "$JAR" META-INF/dramafinder/START-HERE.md # short guide, ~4 KB
unzip -p "$JAR" META-INF/dramafinder/api-reference.md # every signature
unzip -p "$JAR" META-INF/dramafinder/agent-api-reference.md # screenshot helpers
```

## Claude Code skills

This repository ships two Claude Code skills. Install them as plugins:
Expand Down
18 changes: 15 additions & 3 deletions llms.txt
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,21 @@ descriptions) is auto-generated from source into a single file:

- [api-reference.md](https://raw.githubusercontent.com/parttio/dramafinder/master/skills/vaadin-playwright-test/api-reference.md)

**Do not download or unzip the DramaFinder jar/sources to find its API — fetch
the file above (one request) instead.** It is regenerated on every release and
cannot drift from the shipped code.
**Do not decompile the DramaFinder jar to find its API — read the file above
(one request) instead.** It is regenerated on every release and cannot drift
from the shipped code.

**No network?** The same file ships inside the jar, which is already in `~/.m2`
once the dependency resolves:

```
JAR=$(ls ~/.m2/repository/org/vaadin/addons/dramafinder/*/dramafinder-*.jar | tail -1)
unzip -p "$JAR" META-INF/dramafinder/START-HERE.md # short guide, ~4 KB
unzip -p "$JAR" META-INF/dramafinder/api-reference.md # every signature, ~100 KB
```

Start with `START-HERE.md`: it has a working test skeleton, the tag-to-wrapper
naming rule, and the handful of things that are easy to get wrong.

## Documentation

Expand Down
67 changes: 66 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,13 @@
<url>https://github.com/parttio/dramafinder</url>

<name>Drama Finder</name>
<description>Playwright utility classes for Vaadin</description>
<!-- The pom is one of only two DramaFinder files a dependency resolve puts
in ~/.m2, so it is where an offline reader looks first. Point them at
the docs bundled in the jar rather than let them decompile it. -->
<description>Playwright utility classes for Vaadin. The full API reference is bundled in the jar
at META-INF/dramafinder/api-reference.md, with a short guide beside it at
META-INF/dramafinder/START-HERE.md — read those instead of decompiling the classes.
</description>

<properties>
<vaadin.version>25.3.0-beta1</vaadin.version>
Expand Down Expand Up @@ -117,6 +123,65 @@
</dependencies>
<build>
<plugins>
<!-- Bundle the generated agent-facing docs into the jar.

An agent working offline has only the jar and the pom: Maven
does not resolve -sources or any other classifier unless asked,
so a separate docs artifact would never arrive. Shipping the
references inside the main jar is what stops agents reaching
for `jar xf` + `javap` to discover the API. They stay generated
into skills/ (the copy that travels with the Claude Code
plugin) and are copied from there, so there is one source of
truth and no duplicate committed to git. -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>3.3.1</version>
<executions>
<execution>
<id>bundle-agent-docs</id>
<phase>generate-resources</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${project.build.outputDirectory}/META-INF/dramafinder</outputDirectory>
<resources>
<resource>
<directory>${project.basedir}/skills/vaadin-playwright-test</directory>
<includes>
<include>api-reference.md</include>
</includes>
<filtering>false</filtering>
</resource>
<resource>
<directory>${project.basedir}/skills/vaadin-playwright-screenshot</directory>
<includes>
<include>agent-api-reference.md</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
<!-- Name the bundled docs in the manifest, so `unzip -p <jar>
META-INF/MANIFEST.MF` also leads to them. -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.4.2</version>
<configuration>
<archive>
<manifestEntries>
<Dramafinder-Start-Here>META-INF/dramafinder/START-HERE.md</Dramafinder-Start-Here>
<Dramafinder-Api-Reference>META-INF/dramafinder/api-reference.md</Dramafinder-Api-Reference>
<Dramafinder-Agent-Api-Reference>META-INF/dramafinder/agent-api-reference.md</Dramafinder-Agent-Api-Reference>
</manifestEntries>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
Expand Down
10 changes: 6 additions & 4 deletions skills/vaadin-playwright-screenshot/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,10 +99,12 @@ reference). This skill only adds the visual-capture concerns on top of it:
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`.
**`agent-api-reference.md`** next to this file — **do not decompile the
DramaFinder 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`,
or, with no network, read the copy bundled in the jar:
`unzip -p ~/.m2/repository/org/vaadin/addons/dramafinder/*/dramafinder-*.jar META-INF/dramafinder/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
Expand Down
10 changes: 7 additions & 3 deletions skills/vaadin-playwright-test/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ description: Generate Playwright integration tests for Vaadin 25 views using the
> [TESTING.md](TESTING.md) — are bundled beside this file and only load into
> context when the skill is *invoked*, not when you open `SKILL.md` by hand. If
> you are reading this file directly, stop and invoke the skill instead. This is
> also *why* the rule below ("never unzip the jar to discover the API") holds:
> when invoked, the API reference is already in front of you.
> also *why* the rule below ("never decompile the jar to discover the API")
> holds: when invoked, the API reference is already in front of you.

## Best practices

Expand Down Expand Up @@ -95,13 +95,17 @@ the project pins an older `<dramafinder.version>`, a method documented there may
not exist yet — if a call fails to compile, check the project's version before
looking for alternatives.

> **Never download or unzip the DramaFinder jar/sources to discover its API.**
> **Never decompile the DramaFinder jar to discover its API.**
> The complete, always-current signature reference is bundled beside this skill
> in [api-reference.md](api-reference.md) (auto-generated from source). If a
> method isn't there, it doesn't exist in this version — do not guess or dig
> into the jar. The few components with non-obvious behaviour also have prose
> docs in the [specifications folder](https://github.com/parttio/dramafinder/tree/master/docs/specifications).
>
> If you somehow have neither this skill nor a network, the same reference ships
> inside the jar — read it, don't decompile:
> `unzip -p ~/.m2/repository/org/vaadin/addons/dramafinder/*/dramafinder-*.jar META-INF/dramafinder/api-reference.md`
>
> To look up an element, **grep `api-reference.md` for the element name and read
> only that section** (each is a `### <Name>Element` heading) — don't read the
> whole file. Shared mixin methods are documented once under "Shared mixins".
Expand Down
75 changes: 73 additions & 2 deletions skills/vaadin-playwright-test/api-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,76 @@

Complete public API of every DramaFinder element wrapper. Each element lists the shared mixin interfaces it implements; those interfaces' methods are documented once under **Shared mixins** at the end (not repeated per element) — except where an element overrides one to change its behaviour, in which case the element lists it again with the behaviour that applies there. Method one-liners come from Javadoc.

**Do not download or unzip the DramaFinder jar to discover its API — it is all here.**
**Do not decompile the DramaFinder jar to discover its API — it is all here.** This same file ships *inside* the jar, so it is readable with no network:

```
unzip -p ~/.m2/repository/org/vaadin/addons/dramafinder/*/dramafinder-*.jar \
META-INF/dramafinder/api-reference.md
```

## Test setup

A DramaFinder test extends `AbstractBasePlaywrightIT`, which opens a Playwright `Page`, navigates it to `getUrl() + getView()`, waits for Vaadin to go idle, and closes it again. The `page` field is what every element factory below takes.

```java
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class MyViewIT extends AbstractBasePlaywrightIT {

@LocalServerPort
private int port;

@Override
public String getUrl() {
return "http://localhost:" + port;
}

@Override
public String getView() {
return "/my-view"; // appended to getUrl() before each test
}

@Test
public void filtersTheGrid() {
TextFieldElement.getByLabel(page, "Name").setValue("ada");
GridElement.get(page).assertRowCount(1);
}
}
```

Notes:

- The browser runs headless unless the `headless` system property or the `HEADLESS` environment variable says otherwise.
- `setup()` / `cleanup()` are `@BeforeAll` / `@AfterAll` and `setupTest()` / `cleanupTest()` are `@BeforeEach` / `@AfterEach`. Overriding one means calling `super` — the `page` field is null otherwise.
- Playwright's own browser binaries must already be installed.

### AbstractBasePlaywrightIT

*abstract* **Implements:** HasTestView

**Constants:** `String WAIT_FOR_VAADIN_SCRIPT = …`

**Inherited fields:** `Page page`

**Static methods:**

- `void cleanup()`
- `void setup()`
- `protected boolean isHeadless()`

**Methods:**

- `void setupTest()`
- `void cleanupTest()`
- `protected Page getPage()`
- `protected Browser getBrowser()`
- `protected Playwright getPlaywright()`

### HasTestView

**Methods:**

- `String getUrl()`
- `String getView()`

## Element index

Expand Down Expand Up @@ -635,7 +704,7 @@ PlaywrightElement for <vaadin-date-time-picker>.
**Extends:** VaadinElement
**Implements:** HasInputFieldElement, HasValidationPropertiesElement, HasClearButtonElement, HasPlaceholderElement, HasThemeElement, FocusableElement, HasAriaLabelElement, HasEnabledElement, HasTooltipElement, HasLabelElement, HasHelperElement

**Constants:** `String FIELD_TAG_NAME = "vaadin-date-time-picker"`, `DateTimeFormatter ISO_LOCAL_DATE_TIME = new DateTimeFormatterBuilder().parseCaseInsensitive().append(ISO_LOCAL_DATE).appendLiteral('T').append(TimePickerElement.LOCAL_TIME).toFormatter()`
**Constants:** `String FIELD_TAG_NAME = "vaadin-date-time-picker"`, `DateTimeFormatter ISO_LOCAL_DATE_TIME = …`

**Constructors:**

Expand Down Expand Up @@ -837,6 +906,8 @@ Represents a cell in the grid, providing access to the table cell (td or th), th
- `Locator getTableCellLocator()` — Get the locator for the table cell (td or th).
- `int getColumnIndex()` — Get the column index (0-based) of this cell.
- `Locator getCellContentLocator()` — Get the locator for the cell content (vaadin-grid-cell-content) assigned to this cell.
- `String getText()` — Get the rendered text of the cell content.
- `void assertText(String expected)` — Assert that the cell content has the given text.
- `String getContentSlotName()` — Get the name of the slot used for the cell content.
- `void click()` — Click the cell content.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1218,6 +1218,24 @@ public Locator getCellContentLocator() {
return cellContent;
}

/**
* Get the rendered text of the cell content.
*
* @return the text of the cell content
*/
public String getText() {
return cellContent.innerText();
}

/**
* Assert that the cell content has the given text.
*
* @param expected the expected cell text content
*/
public void assertText(String expected) {
assertThat(cellContent).hasText(expected);
}

/**
* Get the name of the slot used for the cell content. This is used for accessing the cell content in the grid's shadow DOM.
*
Expand Down
Loading
Loading