Skip to content

Commit db993dc

Browse files
committed
Update Skill
1 parent a9e8a8f commit db993dc

3 files changed

Lines changed: 176 additions & 86 deletions

File tree

skills/vaadin-playwright-test/SKILL.md

Lines changed: 91 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -7,100 +7,153 @@ description: Generate Playwright integration tests for Vaadin 25 views using the
77

88
## Best practices
99

10-
Always follow the guidelines in [@TESTING.md](TESTING.md) when generating tests. Key rules:
11-
12-
- **One test, one assert** — each test method covers a single piece of functionality
13-
- **User-facing locators** — prefer label, `aria-label`, `aria-role`, or `data-testid` over CSS classes or generated IDs
14-
- **DramaFinder elements for all interactions** — never interact with raw locators when a wrapper exists
15-
- **No `Thread.sleep()`** — use Playwright auto-waiting or `waitFor` methods instead
16-
- **Assert on user-visible state** — check visibility, text, or enabled/disabled, not internal CSS or component state
10+
Always follow [@TESTING.md](TESTING.md) when generating tests. Key rules:
11+
12+
- **One test, one assert** — each test method covers a single piece of
13+
functionality
14+
- **User-facing locators** — prefer label, `aria-label`, `aria-role`, or
15+
`data-testid` over CSS classes or generated IDs
16+
- **DramaFinder elements for all interactions** — never interact with raw
17+
locators when a wrapper exists
18+
- **No `Thread.sleep()`** — use Playwright auto-waiting or `waitFor` methods
19+
instead
20+
- **Assert on user-visible state** — check visibility, text, or
21+
enabled/disabled, not internal CSS or component state
1722

1823
## Step 1 — Assess project state
1924

2025
Run these checks in parallel before doing anything else:
2126

22-
1. **DramaFinder on classpath?** — grep `pom.xml` for `dramafinder` or `org.vaadin.addons`
23-
2. **Spring Boot app?** — grep `pom.xml` for `spring-boot-starter` or `vaadin-spring-boot-starter`
24-
3. **Existing IT tests?** — look for `*IT.java` files under `src/test/java`
27+
1. **DramaFinder on classpath?** — grep `pom.xml` for
28+
`<artifactId>dramafinder</artifactId>`.
29+
2. **Spring Boot app?** — grep `pom.xml` for `spring-boot-starter`.
30+
3. **Existing IT tests?** — look for `*IT.java` files under `src/test/java`.
31+
4. **`SpringPlaywrightIT` already in project?**
32+
`find src/test/java -name SpringPlaywrightIT.java`.
33+
34+
### DramaFinder not found — propose setup, then run it
2535

26-
### DramaFinder not found
36+
Resolve the latest version (Step 1 of [setup.md](setup.md)) and propose the
37+
following in a single confirmation:
2738

28-
Show the user this message and stop:
39+
- Add `org.vaadin.addons:dramafinder:<VERSION>` and
40+
`com.microsoft.playwright:playwright` (test scope) to `pom.xml` with
41+
`<dramafinder.version>` in `<properties>`.
42+
- **Spring Boot only:** also create
43+
`src/test/java/<basePackage>/it/support/SpringPlaywrightIT.java`.
2944

30-
> DramaFinder is not on the classpath. Follow the [setup guide](setup.md) to add the required dependencies, then come back to generate tests.
45+
On confirmation, execute [setup.md](setup.md) end-to-end, then continue with
46+
Step 2.
3147

3248
### DramaFinder found — follow existing patterns
3349

34-
If existing `*IT.java` files are found, read one or two of them to understand the project's conventions (base class, package structure, assertion style, helper methods). Use those as the template for generated tests.
50+
If existing `*IT.java` files are found, read one or two to understand the
51+
project's conventions (base class, package structure, assertion style, helper
52+
methods) and use them as the template.
3553

3654
If no existing IT tests exist, use the default structure in Step 3.
3755

56+
### `SpringPlaywrightIT` location
57+
58+
- 1 hit → use that fully-qualified class name.
59+
- 0 hits + Spring Boot detected → run setup (it will create the file).
60+
- More than 1 hit → ask the user which one to use.
61+
3862
## Step 2 — Map view components to DramaFinder elements
3963

4064
Read the target view source provided by the user. Extract:
4165

42-
- `@Route("value")` → URL path (default: class name lowercased, stripped of "View" suffix)
66+
- `@Route("value")` → URL path (default: class name lowercased, stripped of
67+
`View` suffix, e.g. `PersonView``/person`).
4368
- `@PageTitle("...")` → expected page title
44-
- All Vaadin component field declarations and `add(...)` calls → map to DramaFinder elements
69+
- Every interactive component → its DramaFinder wrapper (see table below).
70+
- Form fields → label text used as locator.
71+
- Grids → column headers and row content to assert against.
72+
- Navigation triggers → button labels or menu items that cause route changes.
4573

46-
See [element-mapping.md](element-mapping.md) for the full component → element class table. Each element also has detailed documentation with examples in the [specifications folder](https://github.com/parttio/dramafinder/tree/master/docs/specifications).
74+
See [element-mapping.md](element-mapping.md) for the full component → element
75+
class table. Each element also has detailed documentation with examples in
76+
the [specifications folder](https://github.com/parttio/dramafinder/tree/master/docs/specifications).
4777

48-
For components with **no DramaFinder wrapper**, use a plain Playwright locator. For more complex needs, you can create your own element class extending `VaadinElement`, or [open an issue](https://github.com/vaadin/dramafinder/issues) in the DramaFinder repository to request one.
78+
For components with **no DramaFinder wrapper**, use a plain Playwright locator.
79+
For more complex needs, you can create your own element class extending
80+
`VaadinElement`,
81+
or [open an issue](https://github.com/vaadin/dramafinder/issues) in the
82+
DramaFinder repository to request one.
4983

5084
## Step 3 — Generate the test class
5185

5286
### Default structure (no existing tests to mirror)
5387

5488
```java
55-
package <same.package.as.view>; // mirror src/test/java structure
89+
package
90+
91+
<same.package.as.view>; // mirror src/test/java structure
5692

5793
import org.junit.jupiter.api.Test;
5894
import org.springframework.boot.test.context.SpringBootTest;
5995
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
6096
import org.vaadin.addons.dramafinder.element.TextFieldElement; // import only used elements
61-
import org.vaadin.addons.dramafinder.tests.it.SpringPlaywrightIT; // or AbstractBasePlaywrightIT
97+
98+
import <basePackage>.it.support.SpringPlaywrightIT; // Spring projects: actual location from Step 1
99+
// import org.vaadin.addons.dramafinder.AbstractBasePlaywrightIT; // non-Spring projects
62100

63101
import static com.microsoft.playwright.assertions.PlaywrightAssertions.assertThat;
64102
import static org.junit.jupiter.api.Assertions.assertEquals;
65103

66-
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) // omit if not Spring Boot
67-
public class <ViewName>IT extends SpringPlaywrightIT { // or AbstractBasePlaywrightIT
104+
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
105+
// omit if not Spring Boot
106+
public class <ViewName>IT extends
107+
108+
SpringPlaywrightIT { // or AbstractBasePlaywrightIT
68109

69110
@Override
70-
public String getView() {
111+
public String getView () {
71112
return "/<route-path>";
72113
}
73114

74115
@Test
75-
public void testTitle() {
116+
public void testTitle () {
76117
assertThat(page).hasTitle("<PageTitle value>");
77118
}
78119

79120
// ... component tests below
80121
}
81122
```
82123

83-
Use `SpringPlaywrightIT` if Spring Boot is detected, `AbstractBasePlaywrightIT` otherwise.
124+
Use `SpringPlaywrightIT` if Spring Boot is detected, `AbstractBasePlaywrightIT`
125+
otherwise.
84126

85127
### Component test patterns
86128

87129
**Smoke test (one per component):**
88130

89131
```java
90-
@Test
91-
public void test<ComponentLabel>() {
92-
TextFieldElement field = TextFieldElement.getByLabel(page, "My Label");
93-
field.assertVisible();
94-
field.assertLabel("My Label");
95-
field.assertValue("");
96-
field.setValue("test value");
97-
field.assertValue("test value");
132+
@Test
133+
public void test<ComponentLabel>(){
134+
TextFieldElement field = TextFieldElement.getByLabel(page, "My Label");
135+
field.
136+
137+
assertVisible();
138+
field.
139+
140+
assertLabel("My Label");
141+
field.
142+
143+
assertValue("");
144+
field.
145+
146+
setValue("test value");
147+
field.
148+
149+
assertValue("test value");
98150
}
99151
```
100152

101153
**Form with validation:**
102154

103155
```java
156+
104157
@Test
105158
public void testFormSubmitWithInvalidInput() {
106159
TextFieldElement nameField = TextFieldElement.getByLabel(page, "Name");
@@ -124,6 +177,7 @@ public void testFormSubmitWithValidInput() {
124177
**Grid data loading:**
125178

126179
```java
180+
127181
@Test
128182
public void testGridLoadsData() {
129183
GridElement grid = GridElement.get(page);
@@ -138,12 +192,14 @@ Display the full generated test class in a code block. Then ask:
138192

139193
> Shall I write this to `src/test/java/<package>/<ViewName>IT.java`?
140194
141-
Only write the file after explicit confirmation. Place it in `src/test/java` mirroring the view's package under `src/main/java`.
195+
Only write the file after explicit confirmation. Place it in `src/test/java`
196+
mirroring the view's package under `src/main/java`.
142197

143198
## Step 5 — Offer to run the test
144199

145200
After writing, ask:
146201

147202
> Do you want me to run this test now with `mvn verify -Dit.test=<ViewName>IT`?
148203
149-
**Warn the user**: the first Vaadin frontend build takes 3–5 minutes. Subsequent runs are ~25 seconds.
204+
**Warn the user**: the first Vaadin frontend build takes 3–5 minutes. Subsequent
205+
runs are ~25 seconds.
Lines changed: 70 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,82 +1,101 @@
11
---
22
name: DramaFinder Setup
3-
description: How to add DramaFinder and Playwright to a Vaadin 25 Spring Boot project.
3+
description: Runbook for adding DramaFinder + Playwright to a Vaadin 25 project. Executed by Claude after the user confirms the setup plan.
44
---
55

6-
# Setting Up DramaFinder in Your Vaadin Project
6+
# DramaFinder Setup Runbook
77

8-
## 1. Add dependencies to `pom.xml`
8+
This file is a runbook for Claude to execute after the user confirms the setup
9+
plan in SKILL.md Step 1. Do not relay it to the user as documentation — perform
10+
the steps.
11+
12+
## Constants
13+
14+
- `KNOWN_LATEST = 1.1.1` — fallback version if Maven Central lookup fails. Bump
15+
when the library releases.
16+
17+
## Step 1 — Resolve the latest version
18+
19+
Run:
20+
21+
```bash
22+
curl -s "https://repo1.maven.org/maven2/org/vaadin/addons/dramafinder/maven-metadata.xml" \
23+
| grep -o '<release>[^<]*</release>' | sed 's/<[^>]*>//g'
24+
```
25+
26+
If the command returns a non-empty version string, use it. Otherwise, use
27+
`KNOWN_LATEST`.
28+
29+
## Step 2 — Edit `pom.xml`
30+
31+
Two edits, both in `pom.xml`:
32+
33+
### 2a. Add the version property
34+
35+
Inside `<properties>`, add:
36+
37+
```xml
38+
39+
<dramafinder.version>RESOLVED_VERSION</dramafinder.version>
40+
```
41+
42+
Replace `RESOLVED_VERSION` with the value from Step 1. If a
43+
`<dramafinder.version>` property already exists, leave it alone.
44+
45+
### 2b. Add the dependencies
46+
47+
Inside `<dependencies>`, add (skip whichever is already present):
948

1049
```xml
11-
<!-- Playwright runtime -->
50+
1251
<dependency>
1352
<groupId>com.microsoft.playwright</groupId>
1453
<artifactId>playwright</artifactId>
1554
<scope>test</scope>
1655
</dependency>
1756

18-
<!-- DramaFinder element wrappers -->
1957
<dependency>
20-
<groupId>org.vaadin.addons.dramafinder</groupId>
21-
<artifactId>dramafinder</artifactId>
22-
<version>LATEST</version>
23-
<scope>test</scope>
58+
<groupId>org.vaadin.addons</groupId>
59+
<artifactId>dramafinder</artifactId>
60+
<version>${dramafinder.version}</version>
61+
<scope>test</scope>
2462
</dependency>
2563
```
2664

27-
Check the latest version at [GitHub releases](https://github.com/vaadin/dramafinder/releases).
65+
Note the groupId is `org.vaadin.addons` (not `org.vaadin.addons.dramafinder`).
2866

29-
## 2. Base test class
67+
## Step 3 — Copy `SpringPlaywrightIT` (Spring Boot projects only)
3068

31-
All IT tests extend `SpringPlaywrightIT` (Spring Boot) or `AbstractBasePlaywrightIT` (plain):
69+
Skip this step entirely if the project is not a Spring Boot project.
3270

33-
```java
34-
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
35-
public class MyViewIT extends SpringPlaywrightIT {
71+
If `find src/test/java -name SpringPlaywrightIT.java` already returns a result,
72+
skip — the file exists and will be used as-is.
3673

37-
@Override
38-
public String getView() {
39-
return "/my-route";
40-
}
74+
Otherwise:
4175

42-
@Test
43-
public void testTitle() {
44-
assertThat(page).hasTitle("Expected Title");
45-
}
46-
}
47-
```
76+
1. **Find the base package** by locating the class annotated with
77+
`@SpringBootApplication` under `src/main/java`. Take its package (e.g.,
78+
`com.example.app`).
79+
2. **Target package** is `<basePackage>.it.support` (e.g.,
80+
`com.example.app.it.support`).
81+
3. **Read** `templates/SpringPlaywrightIT.java.tmpl` from this skill directory.
82+
4. **Substitute** `{{PACKAGE}}` with the target package.
83+
5. **Write** the result to
84+
`src/test/java/<basePackage-as-path>/it/support/SpringPlaywrightIT.java`.
4885

49-
## 3. Run tests
86+
## Step 4 — Confirm dependencies resolve
5087

51-
```bash
52-
# Run all IT tests
53-
mvn verify
88+
Optional but recommended: run `mvn -q dependency:resolve` to surface any pom
89+
syntax errors before generating tests. Skip if the user wants to proceed without
90+
compile-time verification.
5491

55-
# Run a specific IT test
56-
mvn verify -Dit.test=MyViewIT
57-
```
58-
59-
> **Note:** The first Vaadin frontend build takes 3–5 minutes. Subsequent runs take ~25 seconds.
92+
## Debugging with a visible browser (informational)
6093

61-
## 4. Debugging with a visible browser
62-
63-
To disable headless mode and watch the browser during a test run, use the `headless` property or add a `debug-ui` profile:
94+
To run tests with a visible browser, pass `-Dheadless=false`:
6495

6596
```bash
66-
# Via system property
6797
mvn -Dit.test=MyViewIT -Dheadless=false verify
68-
69-
# Via profile (if added to pom.xml)
70-
mvn -Pdebug-ui -Dit.test=MyViewIT verify
7198
```
7299

73-
Add this profile to your `pom.xml` to enable the `-Pdebug-ui` shorthand:
74-
75-
```xml
76-
<profile>
77-
<id>debug-ui</id>
78-
<properties>
79-
<headless>false</headless>
80-
</properties>
81-
</profile>
82-
```
100+
A `debug-ui` profile can be added to `pom.xml` for shorthand `-Pdebug-ui`.
101+
Mention this only if the user asks about debugging.
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package {{PACKAGE}};
2+
3+
import org.springframework.boot.test.web.server.LocalServerPort;
4+
import org.vaadin.addons.dramafinder.AbstractBasePlaywrightIT;
5+
6+
public abstract class SpringPlaywrightIT extends AbstractBasePlaywrightIT {
7+
8+
@LocalServerPort
9+
private int port;
10+
11+
@Override
12+
public String getUrl() {
13+
return String.format("http://localhost:%d/", port);
14+
}
15+
}

0 commit comments

Comments
 (0)