@zhiweiliu/playwright-generator 1.0.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/LICENSE +21 -0
- package/README.md +344 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +111 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/generate.d.ts +7 -0
- package/dist/commands/generate.d.ts.map +1 -0
- package/dist/commands/generate.js +113 -0
- package/dist/commands/generate.js.map +1 -0
- package/dist/commands/init.d.ts +2 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +183 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/config.d.ts +24 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +57 -0
- package/dist/config.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +28 -0
- package/dist/index.js.map +1 -0
- package/dist/llm/claude.d.ts +9 -0
- package/dist/llm/claude.d.ts.map +1 -0
- package/dist/llm/claude.js +81 -0
- package/dist/llm/claude.js.map +1 -0
- package/dist/llm/copilot.d.ts +9 -0
- package/dist/llm/copilot.d.ts.map +1 -0
- package/dist/llm/copilot.js +65 -0
- package/dist/llm/copilot.js.map +1 -0
- package/dist/llm/index.d.ts +6 -0
- package/dist/llm/index.d.ts.map +1 -0
- package/dist/llm/index.js +30 -0
- package/dist/llm/index.js.map +1 -0
- package/dist/llm/provider.d.ts +17 -0
- package/dist/llm/provider.d.ts.map +1 -0
- package/dist/llm/provider.js +25 -0
- package/dist/llm/provider.js.map +1 -0
- package/package.json +64 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Zhiwei Liu
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,344 @@
|
|
|
1
|
+
# Playwright LLM Test Case Generator
|
|
2
|
+
|
|
3
|
+
This module streamlines the generation of Playwright test cases by integrating with Large Language Models. While there are many AI-based test frameworks that allow test cases to be written in natural language, the following drawbacks are commonly found with these approaches.
|
|
4
|
+
|
|
5
|
+
## Table of Contents
|
|
6
|
+
|
|
7
|
+
- [Drawbacks of Current AI-Based Test Frameworks](#drawbacks-of-current-ai-based-test-frameworks)
|
|
8
|
+
- [Why Playwright + AI Test Case Generator?](#why-playwright--ai-test-case-generator)
|
|
9
|
+
- [Features](#features)
|
|
10
|
+
- [Prerequisites](#prerequisites)
|
|
11
|
+
- [Installation & Quick Start](#installation--quick-start)
|
|
12
|
+
- [Project Structure](#project-structure)
|
|
13
|
+
- [Configuration](#configuration)
|
|
14
|
+
- [Environment Variables (.env)](#environment-variables-env)
|
|
15
|
+
- [Preset Test Framework](#preset-test-framework)
|
|
16
|
+
- [Test Cases Written in Natural Language](#test-cases-written-in-natural-language)
|
|
17
|
+
- [Generation](#generation)
|
|
18
|
+
- [Test Results & Reporting](#test-results--reporting)
|
|
19
|
+
- [Execution and Debugging](#execution-and-debugging)
|
|
20
|
+
- [Advanced Features](#advanced-features)
|
|
21
|
+
- [CI/CD Integration](#cicd-integration)
|
|
22
|
+
- [Best Practices](#best-practices)
|
|
23
|
+
- [Troubleshooting](#troubleshooting)
|
|
24
|
+
- [GitHub Integration](#github-integration)
|
|
25
|
+
- [Contributing](#contributing)
|
|
26
|
+
- [Development Setup](#development-setup)
|
|
27
|
+
- [License](#license)
|
|
28
|
+
- [Support](#support)
|
|
29
|
+
|
|
30
|
+
## Drawbacks of Current AI-Based Test Frameworks
|
|
31
|
+
|
|
32
|
+
1. **Lack of Precision and Accuracy**: AI-generated tests may not accurately capture complex user interactions, edge cases, or application-specific logic, leading to false positives or missed bugs.
|
|
33
|
+
|
|
34
|
+
2. **Maintenance Overhead**: As applications evolve, AI-generated tests often require manual updates and refactoring, negating some of the time-saving benefits.
|
|
35
|
+
|
|
36
|
+
3. **Reliability Issues**: Large Language Models can hallucinate or generate incorrect test logic, especially for dynamic web applications with complex state management.
|
|
37
|
+
|
|
38
|
+
4. **Limited Integration**: Many AI-based frameworks lack seamless integration with existing CI/CD pipelines, version control systems, and testing infrastructure.
|
|
39
|
+
|
|
40
|
+
5. **Cost and Resource Intensity**: Frequent API calls to LLM services can become expensive, and there's a dependency on external services that may have rate limits or downtime.
|
|
41
|
+
|
|
42
|
+
6. **Security Concerns**: Sharing application details with external AI services raises potential security risks, especially for proprietary or sensitive codebases.
|
|
43
|
+
|
|
44
|
+
## Why Playwright + AI Test Case Generator?
|
|
45
|
+
|
|
46
|
+
Playwright combined with AI offers a powerful solution that addresses these drawbacks:
|
|
47
|
+
|
|
48
|
+
1. **Robust Web Testing Foundation**: Playwright provides a reliable, battle-tested framework for end-to-end web testing, handling modern web applications with features like auto-waiting, network interception, and cross-browser support.
|
|
49
|
+
|
|
50
|
+
2. **Enhanced Test Generation**: AI integration allows for natural language test case descriptions, accelerating test creation while maintaining the precision and reliability of Playwright's code generation.
|
|
51
|
+
|
|
52
|
+
3. **Maintainable Code**: Generated Playwright tests are actual code that can be easily reviewed, modified, and maintained by developers, unlike some AI frameworks that produce abstract test descriptions.
|
|
53
|
+
|
|
54
|
+
4. **Seamless Integration**: Playwright integrates well with existing development workflows, CI/CD pipelines, and can be enhanced with AI without compromising existing infrastructure.
|
|
55
|
+
|
|
56
|
+
5. **Cost-Effective**: By generating high-quality Playwright code upfront, this approach reduces the need for continuous AI API calls during test maintenance and execution.
|
|
57
|
+
|
|
58
|
+
6. **Security-First**: The AI integration can be implemented with local models or controlled API usage, minimizing security risks associated with external AI services.
|
|
59
|
+
|
|
60
|
+
## Features
|
|
61
|
+
|
|
62
|
+
This project implements an npx command in TypeScript and is released as an NPM module `@zhiweiliu/playwright-generator`. After installing the command, you can easily set up a Playwright framework with AI support by running a command.
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
npx playwright-generator init
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
The installed module will have amazing features to facilitate your day-to-day test automation tasks.
|
|
69
|
+
|
|
70
|
+
## Prerequisites
|
|
71
|
+
|
|
72
|
+
- **Node.js**: Version 16.0 or higher
|
|
73
|
+
- **npm**: Version 7.0 or higher
|
|
74
|
+
- **Git**: For version control integration
|
|
75
|
+
- **LLM API Access** (optional): Depending on your AI model choice
|
|
76
|
+
- Copilot: GitHub Copilot API credentials
|
|
77
|
+
- Claude: Anthropic API key
|
|
78
|
+
|
|
79
|
+
## Installation & Quick Start
|
|
80
|
+
|
|
81
|
+
1. **Install the generator**:
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
npm install -g @zhiweiliu/playwright-generator
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
2. **Initialize a new project**:
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
npx playwright-generator init
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
3. **Configure your environment**:
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
cp .env.example .env
|
|
97
|
+
# Edit .env with your API credentials
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
4. **Write your first test case** in the `tests/` folder
|
|
101
|
+
|
|
102
|
+
5. **Generate Playwright code**:
|
|
103
|
+
```bash
|
|
104
|
+
npx playwright-generator generate --tc TC-0001
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
## Project Structure
|
|
108
|
+
|
|
109
|
+
```
|
|
110
|
+
project-root/
|
|
111
|
+
├── tests/ # Natural language test cases
|
|
112
|
+
│ └── *.test.md
|
|
113
|
+
├── generated/ # Generated Playwright test code
|
|
114
|
+
│ └── generated.test.ts
|
|
115
|
+
├── page-objects/ # Page Object Models (optional)
|
|
116
|
+
│ └── *.po.ts
|
|
117
|
+
├── utils/ # Helper utilities
|
|
118
|
+
│ └── *.ts
|
|
119
|
+
├── audit/ # Screenshots and artifacts from failed tests
|
|
120
|
+
│ └── screenshots/
|
|
121
|
+
├── .env # Environment variables (local only, ignored by Git)
|
|
122
|
+
├── .env.example # Example environment file
|
|
123
|
+
├── playwright.config.ts # Playwright configuration
|
|
124
|
+
└── package.json
|
|
125
|
+
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
## Configuration
|
|
129
|
+
|
|
130
|
+
### Environment Variables (.env)
|
|
131
|
+
|
|
132
|
+
```env
|
|
133
|
+
# AI Model Configuration
|
|
134
|
+
AI_MODEL=copilot # Options: copilot, claude
|
|
135
|
+
COPILOT_API_KEY=your_key_here # Required if using Copilot
|
|
136
|
+
CLAUDE_API_KEY=your_key_here # Required if using Claude
|
|
137
|
+
|
|
138
|
+
# Playwright Configuration
|
|
139
|
+
BROWSER=chromium # Options: chromium, firefox, webkit
|
|
140
|
+
HEADLESS=true # Run in headless mode
|
|
141
|
+
BASE_URL=http://localhost:3000 # Application under test URL
|
|
142
|
+
|
|
143
|
+
# Execution Configuration
|
|
144
|
+
TIMEOUT=30000 # Test timeout in milliseconds
|
|
145
|
+
RETRIES=1 # Number of retries on failure
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### Preset Test Framework
|
|
149
|
+
|
|
150
|
+
- A fully working Playwright test automation framework is already set up
|
|
151
|
+
|
|
152
|
+
### Test Cases Written in Natural Language
|
|
153
|
+
|
|
154
|
+
- Test cases are stored in the `tests/` folder under the project root using `.test.md` files
|
|
155
|
+
- Tags with format `[TAG-NAME]` can be applied to natural language test cases to allow grouping and running related tests
|
|
156
|
+
- Each test case must have a unique ID tag in format `[TC-xxxx]` (e.g., `[TC-0001]`), which enables running specific test cases
|
|
157
|
+
- You can specify an output file in the `generated/` folder; otherwise, generated code will output to `generated.test.ts`
|
|
158
|
+
- Natural language descriptions should be clear and specific to improve AI-generated code quality
|
|
159
|
+
|
|
160
|
+
**Example Test Case File (tests/login.test.md)**:
|
|
161
|
+
|
|
162
|
+
```
|
|
163
|
+
[TC-0001] [SMOKE] [LOGIN]
|
|
164
|
+
User logs in with valid credentials
|
|
165
|
+
Given the user is on the login page
|
|
166
|
+
When the user enters valid username and password
|
|
167
|
+
And clicks the login button
|
|
168
|
+
Then the user should be redirected to the dashboard
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### Generation
|
|
172
|
+
|
|
173
|
+
Playwright test automation code is generated by running a command, with generated code placed in the `generated/` folder under the project root.
|
|
174
|
+
|
|
175
|
+
- Generated Playwright code is in TypeScript
|
|
176
|
+
- The test case ID tag must be specified with the generation command, allowing generation of one test case at a time
|
|
177
|
+
- If an output file is specified, the command will either append the generated test case to the file or update it if it already exists
|
|
178
|
+
- If no output file is specified, the command will either append to `generated.test.ts` or update the test case if it exists
|
|
179
|
+
- The following AI models are supported (specify with generation command; Copilot is used by default):
|
|
180
|
+
- **Copilot**: GitHub Copilot API
|
|
181
|
+
- **Claude**: Anthropic Claude API
|
|
182
|
+
- Credentials (LLM API keys, usernames, passwords) are retrieved from environment variables in the `.env` file for local development; the `.env` file should be ignored by Git
|
|
183
|
+
|
|
184
|
+
**Generation Commands**:
|
|
185
|
+
|
|
186
|
+
```bash
|
|
187
|
+
# Generate with default model (Copilot)
|
|
188
|
+
npx playwright-generator generate --tc TC-0001
|
|
189
|
+
|
|
190
|
+
# Generate with specific model
|
|
191
|
+
npx playwright-generator generate --tc TC-0001 --model claude
|
|
192
|
+
|
|
193
|
+
# Generate to specific output file
|
|
194
|
+
npx playwright-generator generate --tc TC-0001 --output login.test.ts
|
|
195
|
+
|
|
196
|
+
# Generate multiple test cases
|
|
197
|
+
npx playwright-generator generate --tc TC-0001,TC-0002,TC-0003
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
### Test Results & Reporting
|
|
201
|
+
|
|
202
|
+
- Test execution produces detailed reports with pass/fail status
|
|
203
|
+
- HTML reports are generated in the `reports/` folder
|
|
204
|
+
- Screenshots for failed test cases are automatically captured and stored in the `audit/` folder
|
|
205
|
+
- Videos for failed test cases can be captured (disabled by default; enable with `--video` option)
|
|
206
|
+
- Test results can be exported in multiple formats (JSON, XML, HTML)
|
|
207
|
+
- Audit artifacts help with debugging and root cause analysis of test failures
|
|
208
|
+
|
|
209
|
+
### Execution and Debugging
|
|
210
|
+
|
|
211
|
+
Various npm scripts are provided to run and debug Playwright test cases.
|
|
212
|
+
|
|
213
|
+
**Available Commands**:
|
|
214
|
+
|
|
215
|
+
```bash
|
|
216
|
+
# Run all tests
|
|
217
|
+
npm test
|
|
218
|
+
|
|
219
|
+
# Run tests by specific tag
|
|
220
|
+
npm run test:tag -- --tag SMOKE
|
|
221
|
+
|
|
222
|
+
# Run a specific test case
|
|
223
|
+
npm run test:case -- --tc TC-0001
|
|
224
|
+
|
|
225
|
+
# Debug mode (opens inspector)
|
|
226
|
+
npm run test:debug -- --tag SMOKE
|
|
227
|
+
|
|
228
|
+
# Run tests in headed mode (see browser UI)
|
|
229
|
+
npm run test:headed
|
|
230
|
+
|
|
231
|
+
# Run tests with specific browser
|
|
232
|
+
npm run test:browser -- --browser firefox
|
|
233
|
+
|
|
234
|
+
# Run tests with video recording enabled for failed cases
|
|
235
|
+
npm test -- --video on-failure
|
|
236
|
+
|
|
237
|
+
# Generate HTML report
|
|
238
|
+
npm run report
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
### Advanced Features
|
|
242
|
+
|
|
243
|
+
**Page Object Models (POM)**:
|
|
244
|
+
|
|
245
|
+
- Create reusable page objects in the `page-objects/` folder to improve test maintainability
|
|
246
|
+
- Example: `page-objects/login.po.ts` for login page interactions
|
|
247
|
+
- Reference page objects in your natural language test cases for better structure
|
|
248
|
+
|
|
249
|
+
**Test Utilities**:
|
|
250
|
+
|
|
251
|
+
- Helper functions available in `utils/` for common operations (wait strategies, error handling, etc.)
|
|
252
|
+
- Custom assertions and reporters can be added for specialized testing needs
|
|
253
|
+
|
|
254
|
+
**Parallel Execution**:
|
|
255
|
+
|
|
256
|
+
- Configure parallel test execution in `playwright.config.ts`
|
|
257
|
+
- Default: runs 4 tests in parallel
|
|
258
|
+
- Adjust with `fullyParallel` and `workers` settings
|
|
259
|
+
|
|
260
|
+
**Cross-Browser Testing**:
|
|
261
|
+
|
|
262
|
+
- Configure browsers in `playwright.config.ts`
|
|
263
|
+
- Default: Chromium
|
|
264
|
+
- Supported: Chromium, Firefox, WebKit
|
|
265
|
+
|
|
266
|
+
### CI/CD Integration
|
|
267
|
+
|
|
268
|
+
GitHub Actions workflow files are created to run Playwright tests automatically:
|
|
269
|
+
|
|
270
|
+
- **On merge to main**: Runs full test suite
|
|
271
|
+
- **Scheduled daily**: Runs at midnight UTC every day
|
|
272
|
+
- **On-demand**: Manual trigger available in GitHub Actions UI
|
|
273
|
+
|
|
274
|
+
Workflow file location: `.github/workflows/playwright-tests.yml`
|
|
275
|
+
|
|
276
|
+
### Best Practices
|
|
277
|
+
|
|
278
|
+
1. **Test Case Naming**: Use clear, descriptive names that explain what is being tested
|
|
279
|
+
2. **Tags Strategy**: Organize tests with tags (SMOKE, REGRESSION, SANITY, etc.)
|
|
280
|
+
3. **AI Prompting**: Write natural language descriptions with:
|
|
281
|
+
- Given-When-Then format for clarity
|
|
282
|
+
- Specific selectors or UI elements mentioned
|
|
283
|
+
- Expected outcomes clearly stated
|
|
284
|
+
4. **Code Review**: Always review generated code before committing
|
|
285
|
+
5. **Page Objects**: Use POM for maintainability as your test suite grows
|
|
286
|
+
6. **Assertions**: Be explicit about what you're asserting
|
|
287
|
+
7. **Wait Strategies**: Use Playwright's built-in auto-waiting; avoid hardcoded waits
|
|
288
|
+
|
|
289
|
+
### Troubleshooting
|
|
290
|
+
|
|
291
|
+
**Common Issues**:
|
|
292
|
+
|
|
293
|
+
| Issue | Solution |
|
|
294
|
+
| ----------------------------------- | ------------------------------------------------------------------------------------- |
|
|
295
|
+
| `API key not found` | Verify `.env` file exists and `COPILOT_API_KEY` or `CLAUDE_API_KEY` is set |
|
|
296
|
+
| `Tests timing out` | Increase `TIMEOUT` in `.env` or use explicit waits in test cases |
|
|
297
|
+
| `Generated code doesn't compile` | Review the natural language description for clarity; regenerate with a refined prompt |
|
|
298
|
+
| `Tests pass locally but fail in CI` | Check `BASE_URL` environment variable and add debugging with screenshots |
|
|
299
|
+
| `Selector not found` | Ensure selectors are unique and reference current UI state |
|
|
300
|
+
|
|
301
|
+
### GitHub Integration
|
|
302
|
+
|
|
303
|
+
- GitHub Actions workflows automatically run Playwright tests when code is merged to the main branch
|
|
304
|
+
- Tests also run on a scheduled basis (daily at midnight UTC)
|
|
305
|
+
- Workflow status badges can be added to the README to display test status
|
|
306
|
+
|
|
307
|
+
## Contributing
|
|
308
|
+
|
|
309
|
+
Contributions are welcome! Please follow these guidelines:
|
|
310
|
+
|
|
311
|
+
1. Fork the repository
|
|
312
|
+
2. Create a feature branch: `git checkout -b feature/my-feature`
|
|
313
|
+
3. Make your changes and write tests
|
|
314
|
+
4. Commit with clear messages: `git commit -m "Add feature: description"`
|
|
315
|
+
5. Push to your fork and submit a Pull Request
|
|
316
|
+
|
|
317
|
+
### Development Setup
|
|
318
|
+
|
|
319
|
+
```bash
|
|
320
|
+
# Clone the repository
|
|
321
|
+
git clone https://github.com/yourusername/playwright-generator.git
|
|
322
|
+
cd playwright-generator
|
|
323
|
+
|
|
324
|
+
# Install dependencies
|
|
325
|
+
npm install
|
|
326
|
+
|
|
327
|
+
# Build the project
|
|
328
|
+
npm run build
|
|
329
|
+
|
|
330
|
+
# Run tests
|
|
331
|
+
npm test
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
## License
|
|
335
|
+
|
|
336
|
+
MIT License - See LICENSE file for details
|
|
337
|
+
|
|
338
|
+
## Support
|
|
339
|
+
|
|
340
|
+
For issues, questions, or suggestions, please open an issue on GitHub or contact the maintainers.
|
|
341
|
+
|
|
342
|
+
---
|
|
343
|
+
|
|
344
|
+
**Happy Testing! 🎭**
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
|
+
};
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
const commander_1 = require("commander");
|
|
8
|
+
const init_1 = require("./commands/init");
|
|
9
|
+
const generate_1 = require("./commands/generate");
|
|
10
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
11
|
+
const program = new commander_1.Command();
|
|
12
|
+
program
|
|
13
|
+
.name("playwright-generator")
|
|
14
|
+
.description("Generate Playwright test cases from natural language using LLM")
|
|
15
|
+
.version("1.0.0");
|
|
16
|
+
// Init command
|
|
17
|
+
program
|
|
18
|
+
.command("init [projectPath]")
|
|
19
|
+
.description("Initialize a new Playwright test project")
|
|
20
|
+
.action(async (projectPath) => {
|
|
21
|
+
const targetPath = projectPath || process.cwd();
|
|
22
|
+
try {
|
|
23
|
+
await (0, init_1.initializeProject)(targetPath);
|
|
24
|
+
}
|
|
25
|
+
catch (error) {
|
|
26
|
+
process.exit(1);
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
// Generate command
|
|
30
|
+
program
|
|
31
|
+
.command("generate")
|
|
32
|
+
.description("Generate Playwright test code from natural language test cases")
|
|
33
|
+
.option("-tc, --tc <testCaseIds>", "Comma-separated test case IDs (e.g., TC-0001,TC-0002)")
|
|
34
|
+
.option("-m, --model <model>", "LLM model to use (copilot or claude)", "copilot")
|
|
35
|
+
.option("-o, --output <outputFile>", "Output file name (relative to generated/ folder)")
|
|
36
|
+
.action(async (options) => {
|
|
37
|
+
try {
|
|
38
|
+
if (!options.tc) {
|
|
39
|
+
console.error(chalk_1.default.red("Error: Test case IDs are required"));
|
|
40
|
+
console.log("Usage: playwright-generator generate --tc TC-0001 [--tc TC-0002 ...]");
|
|
41
|
+
process.exit(1);
|
|
42
|
+
}
|
|
43
|
+
const testCaseIds = options.tc.split(",").map((id) => id.trim());
|
|
44
|
+
const projectRoot = process.cwd();
|
|
45
|
+
await (0, generate_1.generateTestCode)(projectRoot, {
|
|
46
|
+
testCaseIds,
|
|
47
|
+
model: options.model,
|
|
48
|
+
outputFile: options.output,
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
catch (error) {
|
|
52
|
+
console.error(chalk_1.default.red("Generation failed"), error instanceof Error ? error.message : error);
|
|
53
|
+
process.exit(1);
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
// Help for test case format
|
|
57
|
+
program
|
|
58
|
+
.command("help:testcases")
|
|
59
|
+
.description("Show help about test case format")
|
|
60
|
+
.action(() => {
|
|
61
|
+
console.log(chalk_1.default.cyan(`
|
|
62
|
+
Test Case Format
|
|
63
|
+
================
|
|
64
|
+
|
|
65
|
+
Test cases should be written in Markdown format in the tests/ directory.
|
|
66
|
+
File name: *.test.md
|
|
67
|
+
|
|
68
|
+
Format:
|
|
69
|
+
-------
|
|
70
|
+
# [TC-XXXX] [TAG1] [TAG2]
|
|
71
|
+
|
|
72
|
+
## Test: Clear description of what is being tested
|
|
73
|
+
|
|
74
|
+
Given the initial state or precondition
|
|
75
|
+
When the user performs an action
|
|
76
|
+
And additional actions
|
|
77
|
+
Then expected result should occur
|
|
78
|
+
And another expected result
|
|
79
|
+
|
|
80
|
+
Example:
|
|
81
|
+
--------
|
|
82
|
+
# [TC-0001] [SMOKE] [LOGIN]
|
|
83
|
+
|
|
84
|
+
## Test: User logs in with valid credentials
|
|
85
|
+
|
|
86
|
+
Given the user is on the login page
|
|
87
|
+
When the user enters username and password
|
|
88
|
+
And clicks the login button
|
|
89
|
+
Then the user should see the dashboard
|
|
90
|
+
And the welcome message should contain the user name
|
|
91
|
+
|
|
92
|
+
Tags:
|
|
93
|
+
-----
|
|
94
|
+
- [TC-XXXX] - Required: Unique test case identifier
|
|
95
|
+
- [TAG-NAME] - Optional: Tag for grouping tests (SMOKE, REGRESSION, etc.)
|
|
96
|
+
|
|
97
|
+
Tips for better AI-generated code:
|
|
98
|
+
----------------------------------
|
|
99
|
+
1. Use clear, specific language
|
|
100
|
+
2. Mention element types (button, input, link, etc.)
|
|
101
|
+
3. Include exact text or identifiers when possible
|
|
102
|
+
4. Use Given-When-Then structure for clarity
|
|
103
|
+
5. Keep test cases focused on one feature
|
|
104
|
+
6. Review generated code before committing
|
|
105
|
+
`));
|
|
106
|
+
});
|
|
107
|
+
program.parse(process.argv);
|
|
108
|
+
if (!process.argv.slice(2).length) {
|
|
109
|
+
program.outputHelp();
|
|
110
|
+
}
|
|
111
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";;;;;;AAEA,yCAAoC;AAEpC,0CAAoD;AACpD,kDAAuD;AACvD,kDAA0B;AAE1B,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,sBAAsB,CAAC;KAC5B,WAAW,CAAC,gEAAgE,CAAC;KAC7E,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,eAAe;AACf,OAAO;KACJ,OAAO,CAAC,oBAAoB,CAAC;KAC7B,WAAW,CAAC,0CAA0C,CAAC;KACvD,MAAM,CAAC,KAAK,EAAE,WAAW,EAAE,EAAE;IAC5B,MAAM,UAAU,GAAG,WAAW,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;IAChD,IAAI,CAAC;QACH,MAAM,IAAA,wBAAiB,EAAC,UAAU,CAAC,CAAC;IACtC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC,CAAC;AAEL,mBAAmB;AACnB,OAAO;KACJ,OAAO,CAAC,UAAU,CAAC;KACnB,WAAW,CAAC,gEAAgE,CAAC;KAC7E,MAAM,CACL,yBAAyB,EACzB,uDAAuD,CACxD;KACA,MAAM,CACL,qBAAqB,EACrB,sCAAsC,EACtC,SAAS,CACV;KACA,MAAM,CACL,2BAA2B,EAC3B,kDAAkD,CACnD;KACA,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;IACxB,IAAI,CAAC;QACH,IAAI,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC;YAChB,OAAO,CAAC,KAAK,CAAC,eAAK,CAAC,GAAG,CAAC,mCAAmC,CAAC,CAAC,CAAC;YAC9D,OAAO,CAAC,GAAG,CACT,sEAAsE,CACvE,CAAC;YACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,MAAM,WAAW,GAAG,OAAO,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,EAAU,EAAE,EAAE,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC;QACzE,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;QAElC,MAAM,IAAA,2BAAgB,EAAC,WAAW,EAAE;YAClC,WAAW;YACX,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,UAAU,EAAE,OAAO,CAAC,MAAM;SAC3B,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CACX,eAAK,CAAC,GAAG,CAAC,mBAAmB,CAAC,EAC9B,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAC/C,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC,CAAC;AAEL,4BAA4B;AAC5B,OAAO;KACJ,OAAO,CAAC,gBAAgB,CAAC;KACzB,WAAW,CAAC,kCAAkC,CAAC;KAC/C,MAAM,CAAC,GAAG,EAAE;IACX,OAAO,CAAC,GAAG,CACT,eAAK,CAAC,IAAI,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KA4CZ,CAAC,CACD,CAAC;AACJ,CAAC,CAAC,CAAC;AAEL,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;AAE5B,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;IAClC,OAAO,CAAC,UAAU,EAAE,CAAC;AACvB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../src/commands/generate.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,eAAe;IAC9B,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,KAAK,CAAC,EAAE,SAAS,GAAG,QAAQ,CAAC;IAC7B,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,wBAAsB,gBAAgB,CACpC,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC,IAAI,CAAC,CA6Ff"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.generateTestCode = generateTestCode;
|
|
7
|
+
const path_1 = __importDefault(require("path"));
|
|
8
|
+
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
9
|
+
const glob_1 = require("glob");
|
|
10
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
11
|
+
const llm_1 = require("../llm");
|
|
12
|
+
async function generateTestCode(projectRoot, options) {
|
|
13
|
+
try {
|
|
14
|
+
if (!options.testCaseIds || options.testCaseIds.length === 0) {
|
|
15
|
+
throw new Error("Please specify at least one test case ID with --tc flag");
|
|
16
|
+
}
|
|
17
|
+
const llmProvider = llm_1.LLMFactory.createProvider();
|
|
18
|
+
// Validate LLM connection
|
|
19
|
+
console.log(chalk_1.default.blue("Validating LLM connection..."));
|
|
20
|
+
const isConnected = await llmProvider.validateConnection();
|
|
21
|
+
if (!isConnected) {
|
|
22
|
+
console.warn(chalk_1.default.yellow("⚠ Warning: Could not validate LLM connection"));
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
console.log(chalk_1.default.green("✓ LLM connection validated"));
|
|
26
|
+
}
|
|
27
|
+
const testsDir = path_1.default.join(projectRoot, "tests");
|
|
28
|
+
const generatedDir = path_1.default.join(projectRoot, "generated");
|
|
29
|
+
// Ensure generated directory exists
|
|
30
|
+
await fs_extra_1.default.ensureDir(generatedDir);
|
|
31
|
+
let outputFilePath = options.outputFile
|
|
32
|
+
? path_1.default.join(generatedDir, options.outputFile)
|
|
33
|
+
: path_1.default.join(generatedDir, "generated.test.ts");
|
|
34
|
+
// Ensure output file exists with imports if it's new
|
|
35
|
+
if (!fs_extra_1.default.existsSync(outputFilePath)) {
|
|
36
|
+
const header = `import { test, expect } from '@playwright/test';\n\n`;
|
|
37
|
+
await fs_extra_1.default.writeFile(outputFilePath, header);
|
|
38
|
+
}
|
|
39
|
+
for (const testCaseId of options.testCaseIds) {
|
|
40
|
+
console.log(chalk_1.default.blue(`\\nGenerating test case: ${testCaseId}...`));
|
|
41
|
+
// Find the test case file
|
|
42
|
+
const testCaseFile = await findTestCaseFile(testsDir, testCaseId);
|
|
43
|
+
if (!testCaseFile) {
|
|
44
|
+
console.error(chalk_1.default.red(`✗ Test case file not found for: ${testCaseId}`));
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
console.log(chalk_1.default.gray(`Found: ${path_1.default.relative(projectRoot, testCaseFile)}`));
|
|
48
|
+
// Read test case content
|
|
49
|
+
const testCaseContent = await fs_extra_1.default.readFile(testCaseFile, "utf-8");
|
|
50
|
+
// Extract tags
|
|
51
|
+
const tags = extractTags(testCaseContent);
|
|
52
|
+
// Create LLM prompt
|
|
53
|
+
const prompt = {
|
|
54
|
+
testCase: testCaseContent,
|
|
55
|
+
testCaseId: testCaseId,
|
|
56
|
+
tags: tags,
|
|
57
|
+
};
|
|
58
|
+
// Generate code
|
|
59
|
+
const generatedCode = await llmProvider.generateTestCode(prompt);
|
|
60
|
+
// Append to output file
|
|
61
|
+
await appendTestCodeToFile(outputFilePath, generatedCode.code, testCaseId);
|
|
62
|
+
console.log(chalk_1.default.green(`✓ Generated test case: ${testCaseId}`));
|
|
63
|
+
}
|
|
64
|
+
console.log(chalk_1.default.green.bold(`\\n✓ Code generation completed!`));
|
|
65
|
+
console.log(chalk_1.default.cyan(`Generated file: ${path_1.default.relative(projectRoot, outputFilePath)}`));
|
|
66
|
+
console.log(chalk_1.default.cyan("Next: Review the generated code and run: npm test"));
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
console.error(chalk_1.default.red("Error generating test code:"), error);
|
|
70
|
+
throw error;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
async function findTestCaseFile(testsDir, testCaseId) {
|
|
74
|
+
try {
|
|
75
|
+
const files = await (0, glob_1.glob)(path_1.default.join(testsDir, "**/*.test.md"));
|
|
76
|
+
for (const file of files) {
|
|
77
|
+
const content = await fs_extra_1.default.readFile(file, "utf-8");
|
|
78
|
+
if (content.includes(`[${testCaseId}]`)) {
|
|
79
|
+
return file;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
catch (error) {
|
|
85
|
+
console.error("Error finding test case file:", error);
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
function extractTags(testCaseContent) {
|
|
90
|
+
const tagRegex = /\[([A-Z0-9\-]+)\]/g;
|
|
91
|
+
const matches = testCaseContent.match(tagRegex) || [];
|
|
92
|
+
return matches.map((tag) => tag.slice(1, -1)).filter((tag) => tag.length > 0);
|
|
93
|
+
}
|
|
94
|
+
async function appendTestCodeToFile(filePath, generatedCode, testCaseId) {
|
|
95
|
+
let currentContent = await fs_extra_1.default.readFile(filePath, "utf-8");
|
|
96
|
+
// Check if test case already exists
|
|
97
|
+
const testCaseRegex = new RegExp(`test\\(['\`"].*?${testCaseId}.*?['\`"].*?\\)\\s*=>\\s*{[^}]*}`, "s");
|
|
98
|
+
if (testCaseRegex.test(currentContent)) {
|
|
99
|
+
// Replace existing test case
|
|
100
|
+
const updatedContent = currentContent.replace(testCaseRegex, generatedCode);
|
|
101
|
+
await fs_extra_1.default.writeFile(filePath, updatedContent);
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
// Append new test case
|
|
105
|
+
const code = generatedCode.trim();
|
|
106
|
+
if (!currentContent.endsWith("\\n\\n")) {
|
|
107
|
+
currentContent += "\\n\\n";
|
|
108
|
+
}
|
|
109
|
+
currentContent += code + "\\n";
|
|
110
|
+
await fs_extra_1.default.writeFile(filePath, currentContent);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=generate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate.js","sourceRoot":"","sources":["../../src/commands/generate.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAKA,wBAAsB,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA2M1E"}
|