agents-cli-automation 1.0.6 → 1.0.8
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 +127 -44
- package/package.json +1 -1
- package/src/commands/init.js +54 -15
- package/src/templates/playwright-agent-csharp.md +521 -0
- package/src/templates/playwright-agent-java.md +471 -0
- package/src/templates/playwright-agent-js.md +461 -0
- package/src/templates/playwright-agent-ts.md +69 -0
- package/src/templates/playwright-agent.md +1353 -47
|
@@ -0,0 +1,471 @@
|
|
|
1
|
+
name: Create Playwright Framework - UI Testing (Java)
|
|
2
|
+
description: Creates a production-ready Playwright UI automation framework in Java with Maven, Junit5, and all required configurations.
|
|
3
|
+
argument-hint: "framework requirements, e.g., 'Java with Playwright tests'"
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Playwright UI Testing Framework - Java
|
|
8
|
+
|
|
9
|
+
This agent creates a production-ready Playwright framework in Java with Maven and JUnit 5 optimized for UI automation.
|
|
10
|
+
|
|
11
|
+
## Capabilities
|
|
12
|
+
- **Java 11+** - Chromium only with modern Maven setup
|
|
13
|
+
- **JUnit 5** - Latest testing framework
|
|
14
|
+
- **Maven** - Dependency management and build automation
|
|
15
|
+
- **Page Object Model (POM)** - Reusable page classes
|
|
16
|
+
- **Test Fixtures** - Setup and teardown management
|
|
17
|
+
- **Parallel execution** - Tests run simultaneously for speed
|
|
18
|
+
- **Test data support** - JSON, CSV, YAML loading
|
|
19
|
+
- **BDD Support** - Cucumber with Gherkin syntax
|
|
20
|
+
- **WebDriverWait** - Explicit waits for element handling
|
|
21
|
+
- **Scalable folder structure** with best practices
|
|
22
|
+
|
|
23
|
+
## Prerequisites
|
|
24
|
+
- Java 11 or higher installed
|
|
25
|
+
- Maven 3.8+ installed
|
|
26
|
+
- Git (optional)
|
|
27
|
+
|
|
28
|
+
## Setup Instructions
|
|
29
|
+
|
|
30
|
+
### 1. Create Maven Project Structure
|
|
31
|
+
```bash
|
|
32
|
+
mvn archetype:generate -DgroupId=com.test.automation -DartifactId=playwright-framework -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
|
|
33
|
+
cd playwright-framework
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### 2. Update pom.xml with Dependencies
|
|
37
|
+
```xml
|
|
38
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
39
|
+
<project xmlns="http://maven.apache.org/POM/4.0.0">
|
|
40
|
+
<modelVersion>4.0.0</modelVersion>
|
|
41
|
+
<groupId>com.test.automation</groupId>
|
|
42
|
+
<artifactId>playwright-framework</artifactId>
|
|
43
|
+
<version>1.0.0</version>
|
|
44
|
+
|
|
45
|
+
<properties>
|
|
46
|
+
<maven.compiler.source>11</maven.compiler.source>
|
|
47
|
+
<maven.compiler.target>11</maven.compiler.target>
|
|
48
|
+
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
|
49
|
+
<playwright.version>1.50.0</playwright.version>
|
|
50
|
+
<junit.version>5.10.1</junit.version>
|
|
51
|
+
</properties>
|
|
52
|
+
|
|
53
|
+
<dependencies>
|
|
54
|
+
<!-- Playwright -->
|
|
55
|
+
<dependency>
|
|
56
|
+
<groupId>com.microsoft.playwright</groupId>
|
|
57
|
+
<artifactId>playwright</artifactId>
|
|
58
|
+
<version>${playwright.version}</version>
|
|
59
|
+
</dependency>
|
|
60
|
+
|
|
61
|
+
<!-- JUnit 5 -->
|
|
62
|
+
<dependency>
|
|
63
|
+
<groupId>org.junit.jupiter</groupId>
|
|
64
|
+
<artifactId>junit-jupiter</artifactId>
|
|
65
|
+
<version>${junit.version}</version>
|
|
66
|
+
<scope>test</scope>
|
|
67
|
+
</dependency>
|
|
68
|
+
|
|
69
|
+
<!-- JSON -->
|
|
70
|
+
<dependency>
|
|
71
|
+
<groupId>com.google.code.gson</groupId>
|
|
72
|
+
<artifactId>gson</artifactId>
|
|
73
|
+
<version>2.10.1</version>
|
|
74
|
+
</dependency>
|
|
75
|
+
|
|
76
|
+
<!-- YAML -->
|
|
77
|
+
<dependency>
|
|
78
|
+
<groupId>org.yaml</groupId>
|
|
79
|
+
<artifactId>snakeyaml</artifactId>
|
|
80
|
+
<version>2.0</version>
|
|
81
|
+
</dependency>
|
|
82
|
+
|
|
83
|
+
<!-- CSV -->
|
|
84
|
+
<dependency>
|
|
85
|
+
<groupId>org.apache.commons</groupId>
|
|
86
|
+
<artifactId>commons-csv</artifactId>
|
|
87
|
+
<version>1.10.0</version>
|
|
88
|
+
</dependency>
|
|
89
|
+
|
|
90
|
+
<!-- Cucumber -->
|
|
91
|
+
<dependency>
|
|
92
|
+
<groupId>io.cucumber</groupId>
|
|
93
|
+
<artifactId>cucumber-java</artifactId>
|
|
94
|
+
<version>7.14.0</version>
|
|
95
|
+
</dependency>
|
|
96
|
+
<dependency>
|
|
97
|
+
<groupId>io.cucumber</groupId>
|
|
98
|
+
<artifactId>cucumber-junit-platform-engine</artifactId>
|
|
99
|
+
<version>7.14.0</version>
|
|
100
|
+
</dependency>
|
|
101
|
+
</dependencies>
|
|
102
|
+
|
|
103
|
+
<build>
|
|
104
|
+
<plugins>
|
|
105
|
+
<plugin>
|
|
106
|
+
<groupId>org.apache.maven.plugins</groupId>
|
|
107
|
+
<artifactId>maven-surefire-plugin</artifactId>
|
|
108
|
+
<version>3.0.0-M9</version>
|
|
109
|
+
</plugin>
|
|
110
|
+
</plugins>
|
|
111
|
+
</build>
|
|
112
|
+
</project>
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### 3. Project Structure
|
|
116
|
+
```
|
|
117
|
+
playwright-framework/
|
|
118
|
+
├── src/
|
|
119
|
+
│ ├── main/
|
|
120
|
+
│ │ └── java/
|
|
121
|
+
│ │ └── com/test/automation/
|
|
122
|
+
│ │ ├── pages/
|
|
123
|
+
│ │ │ ├── BasePage.java
|
|
124
|
+
│ │ │ ├── LoginPage.java
|
|
125
|
+
│ │ │ ├── InventoryPage.java
|
|
126
|
+
│ │ │ └── FormPage.java
|
|
127
|
+
│ │ ├── utils/
|
|
128
|
+
│ │ │ ├── DataReader.java
|
|
129
|
+
│ │ │ ├── FormHelper.java
|
|
130
|
+
│ │ │ └── TestDataManager.java
|
|
131
|
+
│ │ ├── fixtures/
|
|
132
|
+
│ │ │ └── TestFixtures.java
|
|
133
|
+
│ │ └── model/
|
|
134
|
+
│ │ ├── User.java
|
|
135
|
+
│ │ ├── FormData.java
|
|
136
|
+
│ │ └── Config.java
|
|
137
|
+
│ ├── test/
|
|
138
|
+
│ │ ├── java/
|
|
139
|
+
│ │ │ └── com/test/automation/
|
|
140
|
+
│ │ │ ├── tests/
|
|
141
|
+
│ │ │ │ ├── SauceDemoTest.java
|
|
142
|
+
│ │ │ │ └── FormTest.java
|
|
143
|
+
│ │ │ └── steps/
|
|
144
|
+
│ │ │ ├── LoginSteps.java
|
|
145
|
+
│ │ │ └── ShoppingSteps.java
|
|
146
|
+
│ │ └── resources/
|
|
147
|
+
│ │ ├── features/
|
|
148
|
+
│ │ │ ├── login.feature
|
|
149
|
+
│ │ │ └── shopping.feature
|
|
150
|
+
│ │ └── data/
|
|
151
|
+
│ │ ├── users.json
|
|
152
|
+
│ │ ├── formData.csv
|
|
153
|
+
│ │ └── config.yaml
|
|
154
|
+
└── pom.xml
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### 4. Base Page (src/main/java/pages/BasePage.java)
|
|
158
|
+
```java
|
|
159
|
+
package com.test.automation.pages;
|
|
160
|
+
|
|
161
|
+
import com.microsoft.playwright.Page;
|
|
162
|
+
import com.microsoft.playwright.Locator;
|
|
163
|
+
import java.util.concurrent.TimeoutException;
|
|
164
|
+
|
|
165
|
+
public class BasePage {
|
|
166
|
+
protected Page page;
|
|
167
|
+
protected static final int TIMEOUT = 5000;
|
|
168
|
+
|
|
169
|
+
public BasePage(Page page) {
|
|
170
|
+
this.page = page;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
public void navigateTo(String url) {
|
|
174
|
+
page.navigate(url);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
public void click(String selector) {
|
|
178
|
+
page.click(selector);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
public void fill(String selector, String text) {
|
|
182
|
+
page.fill(selector, text);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
public String getText(String selector) {
|
|
186
|
+
return page.textContent(selector);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
public void waitForElement(String selector) {
|
|
190
|
+
page.waitForSelector(selector, new Page.WaitForSelectorOptions().setTimeout(TIMEOUT));
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
public boolean isVisible(String selector) {
|
|
194
|
+
return page.locator(selector).isVisible();
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
public void selectDropdown(String selector, String optionText) {
|
|
198
|
+
page.click(selector);
|
|
199
|
+
page.click("text=" + optionText);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
public void selectRadioButton(String labelText) {
|
|
203
|
+
Locator label = page.locator("label:has-text(\"" + labelText + "\")");
|
|
204
|
+
String radioId = label.getAttribute("for");
|
|
205
|
+
page.click("#" + radioId);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
public void checkCheckbox(String labelText) {
|
|
209
|
+
Locator label = page.locator("label:has-text(\"" + labelText + "\")");
|
|
210
|
+
String checkboxId = label.getAttribute("for");
|
|
211
|
+
Locator checkbox = page.locator("#" + checkboxId);
|
|
212
|
+
if (!checkbox.isChecked()) {
|
|
213
|
+
checkbox.click();
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
### 5. Login Page (src/main/java/pages/LoginPage.java)
|
|
220
|
+
```java
|
|
221
|
+
package com.test.automation.pages;
|
|
222
|
+
|
|
223
|
+
import com.microsoft.playwright.Page;
|
|
224
|
+
|
|
225
|
+
public class LoginPage extends BasePage {
|
|
226
|
+
private static final String USERNAME_FIELD = "[data-test=\"username\"]";
|
|
227
|
+
private static final String PASSWORD_FIELD = "[data-test=\"password\"]";
|
|
228
|
+
private static final String LOGIN_BUTTON = "[data-test=\"login-button\"]";
|
|
229
|
+
private static final String APP_URL = "https://www.saucedemo.com/";
|
|
230
|
+
|
|
231
|
+
public LoginPage(Page page) {
|
|
232
|
+
super(page);
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
public void goTo() {
|
|
236
|
+
page.navigate(APP_URL);
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
public void login(String username, String password) {
|
|
240
|
+
page.fill(USERNAME_FIELD, username);
|
|
241
|
+
page.fill(PASSWORD_FIELD, password);
|
|
242
|
+
page.click(LOGIN_BUTTON);
|
|
243
|
+
page.waitForURL("**/inventory.html");
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
public boolean isLoaded() {
|
|
247
|
+
return page.locator(USERNAME_FIELD).isVisible();
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
### 6. Data Reader (src/main/java/utils/DataReader.java)
|
|
253
|
+
```java
|
|
254
|
+
package com.test.automation.utils;
|
|
255
|
+
|
|
256
|
+
import com.google.gson.Gson;
|
|
257
|
+
import com.google.gson.JsonObject;
|
|
258
|
+
import org.apache.commons.csv.CSVFormat;
|
|
259
|
+
import org.apache.commons.csv.CSVParser;
|
|
260
|
+
import org.apache.commons.csv.CSVRecord;
|
|
261
|
+
import org.yaml.snakeyaml.Yaml;
|
|
262
|
+
|
|
263
|
+
import java.io.FileReader;
|
|
264
|
+
import java.io.IOException;
|
|
265
|
+
import java.nio.file.Files;
|
|
266
|
+
import java.nio.file.Path;
|
|
267
|
+
import java.nio.file.Paths;
|
|
268
|
+
import java.util.*;
|
|
269
|
+
|
|
270
|
+
public class DataReader {
|
|
271
|
+
private static final String DATA_DIR = "src/test/resources/data";
|
|
272
|
+
|
|
273
|
+
public static JsonObject readJSON(String filename) throws IOException {
|
|
274
|
+
String content = new String(Files.readAllBytes(Paths.get(DATA_DIR, filename)));
|
|
275
|
+
return new Gson().fromJson(content, JsonObject.class);
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
public static Map<String, Object> readYAML(String filename) throws IOException {
|
|
279
|
+
String content = new String(Files.readAllBytes(Paths.get(DATA_DIR, filename)));
|
|
280
|
+
Yaml yaml = new Yaml();
|
|
281
|
+
return yaml.load(content);
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
public static List<Map<String, String>> readCSV(String filename) throws IOException {
|
|
285
|
+
List<Map<String, String>> records = new ArrayList<>();
|
|
286
|
+
CSVParser csvParser = CSVFormat.DEFAULT.withFirstRecordAsHeader()
|
|
287
|
+
.parse(new FileReader(Paths.get(DATA_DIR, filename).toFile()));
|
|
288
|
+
|
|
289
|
+
for (CSVRecord record : csvParser) {
|
|
290
|
+
records.add(record.toMap());
|
|
291
|
+
}
|
|
292
|
+
return records;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
public static Map<String, String> getRecordByKey(List<Map<String, String>> data, String key, String value) {
|
|
296
|
+
return data.stream()
|
|
297
|
+
.filter(record -> value.equals(record.get(key)))
|
|
298
|
+
.findFirst()
|
|
299
|
+
.orElse(null);
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
### 7. Form Helper (src/main/java/utils/FormHelper.java)
|
|
305
|
+
```java
|
|
306
|
+
package com.test.automation.utils;
|
|
307
|
+
|
|
308
|
+
import com.microsoft.playwright.Page;
|
|
309
|
+
import com.microsoft.playwright.Locator;
|
|
310
|
+
import java.util.List;
|
|
311
|
+
|
|
312
|
+
public class FormHelper {
|
|
313
|
+
private Page page;
|
|
314
|
+
|
|
315
|
+
public FormHelper(Page page) {
|
|
316
|
+
this.page = page;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
public void fillInput(String selector, String value) {
|
|
320
|
+
page.fill(selector, value);
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
public void fillTextArea(String selector, String value) {
|
|
324
|
+
page.locator(selector).clear();
|
|
325
|
+
page.locator(selector).type(value, new Locator.TypeOptions().setDelay(50));
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
public void selectDropdown(String dropdownSelector, String optionText) {
|
|
329
|
+
page.click(dropdownSelector);
|
|
330
|
+
page.click("text=" + optionText);
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
public void selectRadioButton(String labelText) {
|
|
334
|
+
Locator label = page.locator("label:has-text(\"" + labelText + "\")");
|
|
335
|
+
String radioId = label.getAttribute("for");
|
|
336
|
+
page.click("#" + radioId);
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
public void checkCheckbox(String labelText) {
|
|
340
|
+
Locator label = page.locator("label:has-text(\"" + labelText + "\")");
|
|
341
|
+
String checkboxId = label.getAttribute("for");
|
|
342
|
+
Locator checkbox = page.locator("#" + checkboxId);
|
|
343
|
+
if (!checkbox.isChecked()) {
|
|
344
|
+
checkbox.click();
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
public void checkMultiple(List<String> labels) {
|
|
349
|
+
for (String label : labels) {
|
|
350
|
+
checkCheckbox(label);
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
public String getInputValue(String selector) {
|
|
355
|
+
return page.inputValue(selector);
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
public boolean isCheckboxChecked(String labelText) {
|
|
359
|
+
Locator label = page.locator("label:has-text(\"" + labelText + "\")");
|
|
360
|
+
String checkboxId = label.getAttribute("for");
|
|
361
|
+
return page.locator("#" + checkboxId).isChecked();
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
### 8. Simple Test (src/test/java/tests/SauceDemoTest.java)
|
|
367
|
+
```java
|
|
368
|
+
package com.test.automation.tests;
|
|
369
|
+
|
|
370
|
+
import com.microsoft.playwright.*;
|
|
371
|
+
import com.test.automation.pages.LoginPage;
|
|
372
|
+
import org.junit.jupiter.api.Test;
|
|
373
|
+
import org.junit.jupiter.api.BeforeAll;
|
|
374
|
+
import org.junit.jupiter.api.AfterAll;
|
|
375
|
+
import static org.junit.jupiter.api.Assertions.assertTrue;
|
|
376
|
+
|
|
377
|
+
public class SauceDemoTest {
|
|
378
|
+
static Playwright playwright;
|
|
379
|
+
static Browser browser;
|
|
380
|
+
BrowserContext context;
|
|
381
|
+
Page page;
|
|
382
|
+
|
|
383
|
+
@BeforeAll
|
|
384
|
+
static void launchBrowser() {
|
|
385
|
+
playwright = Playwright.create();
|
|
386
|
+
browser = playwright.chromium().launch();
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
@AfterAll
|
|
390
|
+
static void closeBrowser() {
|
|
391
|
+
playwright.close();
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
@Test
|
|
395
|
+
public void testLoginWithValidCredentials() {
|
|
396
|
+
context = browser.newContext();
|
|
397
|
+
page = context.newPage();
|
|
398
|
+
|
|
399
|
+
LoginPage loginPage = new LoginPage(page);
|
|
400
|
+
loginPage.goTo();
|
|
401
|
+
loginPage.login("standard_user", "secret_sauce");
|
|
402
|
+
|
|
403
|
+
assertTrue(page.url().contains("inventory.html"));
|
|
404
|
+
context.close();
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
```
|
|
408
|
+
|
|
409
|
+
### 9. Run Tests
|
|
410
|
+
|
|
411
|
+
```bash
|
|
412
|
+
# Run all tests
|
|
413
|
+
mvn test
|
|
414
|
+
|
|
415
|
+
# Run specific test class
|
|
416
|
+
mvn test -Dtest=SauceDemoTest
|
|
417
|
+
|
|
418
|
+
# Run specific test method
|
|
419
|
+
mvn test -Dtest=SauceDemoTest#testLoginWithValidCredentials
|
|
420
|
+
|
|
421
|
+
# Run with parallel execution
|
|
422
|
+
mvn test -DthreadCount=4
|
|
423
|
+
|
|
424
|
+
# Run BDD scenarios
|
|
425
|
+
mvn test -Dcucumber.options="classpath:features"
|
|
426
|
+
|
|
427
|
+
# View report
|
|
428
|
+
# Open target/surefire-reports/index.html
|
|
429
|
+
```
|
|
430
|
+
|
|
431
|
+
### 10. Test Data Files
|
|
432
|
+
|
|
433
|
+
**src/test/resources/data/users.json**
|
|
434
|
+
```json
|
|
435
|
+
{
|
|
436
|
+
"users": [
|
|
437
|
+
{
|
|
438
|
+
"id": "1",
|
|
439
|
+
"username": "standard_user",
|
|
440
|
+
"password": "secret_sauce",
|
|
441
|
+
"email": "user@example.com",
|
|
442
|
+
"firstName": "John",
|
|
443
|
+
"lastName": "Doe"
|
|
444
|
+
}
|
|
445
|
+
]
|
|
446
|
+
}
|
|
447
|
+
```
|
|
448
|
+
|
|
449
|
+
**src/test/resources/data/config.yaml**
|
|
450
|
+
```yaml
|
|
451
|
+
app:
|
|
452
|
+
url: https://www.saucedemo.com/
|
|
453
|
+
timeout: 30000
|
|
454
|
+
users:
|
|
455
|
+
standard:
|
|
456
|
+
username: standard_user
|
|
457
|
+
password: secret_sauce
|
|
458
|
+
```
|
|
459
|
+
|
|
460
|
+
## Best Practices
|
|
461
|
+
✅ **Page Object Model** - All selectors in page classes
|
|
462
|
+
✅ **Fixtures** - Static setup/teardown with BeforeAll/AfterAll
|
|
463
|
+
✅ **Test Data** - Externalize in JSON, CSV, YAML
|
|
464
|
+
✅ **Form Helpers** - Handle all form interactions
|
|
465
|
+
✅ **Parallel Execution** - Maven threadCount option
|
|
466
|
+
✅ **Chromium Only** - Single browser for consistency
|
|
467
|
+
✅ **Java 11+** - Modern Java features
|
|
468
|
+
✅ **JUnit 5** - Latest testing framework
|
|
469
|
+
✅ **Maven** - Standard Java build tool
|
|
470
|
+
|
|
471
|
+
**Note:** This framework uses Java 11+, Chromium only, and Maven for build management. Use `mvn clean install` to download dependencies and run tests with `mvn test`.
|