@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 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,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=cli.d.ts.map
@@ -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
@@ -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,7 @@
1
+ export interface GenerateOptions {
2
+ testCaseIds?: string[];
3
+ model?: "copilot" | "claude";
4
+ outputFile?: string;
5
+ }
6
+ export declare function generateTestCode(projectRoot: string, options: GenerateOptions): Promise<void>;
7
+ //# sourceMappingURL=generate.d.ts.map
@@ -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,2 @@
1
+ export declare function initializeProject(projectPath: string): Promise<void>;
2
+ //# sourceMappingURL=init.d.ts.map
@@ -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"}