endorphin-ai 0.1.0 โ†’ 0.2.1

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 CHANGED
@@ -1,19 +1,29 @@
1
1
  <div align="center">
2
- <img src="./doc/images/endorphin.jpg" alt="Endorphin Logo" width="200" />
2
+ <img src="./doc/images/endorphin-ai-logo-no-bg.png" alt="Endorphin Logo" width="200" />
3
3
 
4
- <h1 style="font-size: 4rem; font-weight: bold; margin: 30px 0 10px 0; color: #8A2BE2;">ENDORPHIN</h1>
4
+ # ๐Ÿ’œ ENDORPHIN
5
5
 
6
- <h2 style="font-size: 1.5rem; margin: 10px 0 30px 0;">E2E Testing Reinvented with AI</h2>
6
+ ## E2E Testing Reinvented with AI
7
7
  </div>
8
8
 
9
9
  Write tests in plain English. Let AI generate, validate, and fix them automatically.
10
10
 
11
+ <div align="center">
12
+ <img src="./doc/images/playwright-logo.png" alt="Playwright" height="40" />
13
+ <span style="margin: 10px 15px; font-size: 24px; display: inline-block; vertical-align: middle;">+</span>
14
+ <img src="./doc/images/langchain-logo.png" alt="LangChain" height="40" />
15
+ </div>
16
+
11
17
  A powerful, modular browser automation framework using AI-powered testing with LangChain, OpenAI GPT-4o, and Playwright. Provides intelligent browser automation with automatic element detection, visual validation, and comprehensive test management.
12
18
 
13
19
  ## ๐Ÿš€ Quick Start
14
20
 
15
21
  ### Installation
16
22
  ```bash
23
+ # Local installation (recommended)
24
+ npm install endorphin-ai
25
+
26
+ # Global installation (optional)
17
27
  npm install -g endorphin-ai
18
28
  ```
19
29
 
@@ -23,17 +33,28 @@ npm install -g endorphin-ai
23
33
  mkdir my-test-project && cd my-test-project
24
34
  ```
25
35
 
26
- 2. Set up your `.env` file with your OpenAI API key:
36
+ 2. Initialize with ES modules:
37
+ ```bash
38
+ npm init -y
39
+ npm pkg set type="module"
40
+ ```
41
+
42
+ 3. Install Endorphin AI:
43
+ ```bash
44
+ npm install endorphin-ai
45
+ ```
46
+
47
+ 4. Set up your `.env` file with your OpenAI API key:
27
48
  ```env
28
49
  OPENAI_API_KEY=your_api_key_here
29
50
  ```
30
51
 
31
- 3. Create tests directory:
52
+ 5. Create tests directory:
32
53
  ```bash
33
54
  mkdir tests
34
55
  ```
35
56
 
36
- 4. Create your first test file `tests/login-test.js`:
57
+ 6. Create your first test file `tests/login-test.js`:
37
58
  ```javascript
38
59
  export const QE001 = {
39
60
  id: "QE-001",
@@ -55,64 +76,74 @@ npm install -g endorphin-ai
55
76
  };
56
77
  ```
57
78
 
79
+ 7. Add scripts to your `package.json`:
80
+ ```json
81
+ {
82
+ "scripts": {
83
+ "test": "endorphin run test all",
84
+ "test:smoke": "endorphin run test --tag smoke",
85
+ "test:auth": "endorphin run test --tag authentication",
86
+ "test:single": "endorphin run test",
87
+ "test:record": "endorphin run test-recorder"
88
+ }
89
+ }
90
+ ```
91
+
58
92
  ### Usage Commands
59
93
 
60
94
  #### ๐Ÿงช Run Specific Test
61
95
  ```bash
96
+ # Using npm scripts (recommended)
97
+ npm run test:single QE-001
98
+
99
+ # Using npx
100
+ npx endorphin run test QE-001
101
+
102
+ # Global installation
62
103
  endorphin run test QE-001
63
104
  ```
64
105
 
65
106
  #### ๐Ÿท๏ธ Run Tests by Category
66
107
  ```bash
67
- # Authentication tests
68
- endorphin run test --tag authentication
69
-
70
- # High priority tests
71
- endorphin run test --priority High
108
+ # Using npm scripts
109
+ npm run test:smoke
110
+ npm run test:auth
72
111
 
73
- # Smoke tests
74
- endorphin run test --tag smoke
112
+ # Using npx/global
113
+ npx endorphin run test --tag authentication
114
+ npx endorphin run test --priority High
75
115
  ```
76
116
 
77
117
  #### ๐ŸŽฏ Run All Tests
78
118
  ```bash
79
- endorphin run test all
119
+ # Using npm scripts
120
+ npm test
121
+
122
+ # Using npx/global
123
+ npx endorphin run test all
80
124
  ```
81
125
 
82
126
  #### ๐ŸŽฌ Test Recorder Mode
83
127
  ```bash
84
- # Interactive test creation
85
- endorphin run test-recorder
128
+ # Using npm scripts
129
+ npm run test:record
130
+
131
+ # Using npx/global
132
+ npx endorphin run test-recorder
86
133
  ```
87
134
 
88
135
  ## ๐Ÿ—๏ธ Framework Architecture
89
136
 
90
- ### Modular Structure
91
- ```
92
- framework/
93
- โ”œโ”€โ”€ test-framework.js # Main entry point
94
- โ”œโ”€โ”€ index.js # Modular exports
95
- โ”œโ”€โ”€ config/ # Configuration files
96
- โ”‚ โ”œโ”€โ”€ agent-config.js # AI agent settings
97
- โ”‚ โ”œโ”€โ”€ browser-config.js # Browser configuration
98
- โ”‚ โ””โ”€โ”€ paths.js # Directory paths
99
- โ”œโ”€โ”€ core/ # Core components
100
- โ”‚ โ”œโ”€โ”€ browser-framework.js # Main framework class
101
- โ”‚ โ”œโ”€โ”€ config-loader.js # Configuration management
102
- โ”‚ โ”œโ”€โ”€ test-discovery.js # Test discovery & execution
103
- โ”‚ โ”œโ”€โ”€ test-manager.js # Test management
104
- โ”‚ โ”œโ”€โ”€ test-runner.js # Test execution
105
- โ”‚ โ””โ”€โ”€ test-session.js # Session tracking
106
- โ”œโ”€โ”€ tools/ # Browser automation tools
107
- โ”‚ โ”œโ”€โ”€ navigation.js # Page navigation
108
- โ”‚ โ”œโ”€โ”€ interaction.js # Clicks, form filling
109
- โ”‚ โ”œโ”€โ”€ verification.js # Element verification
110
- โ”‚ โ”œโ”€โ”€ content.js # Page content analysis
111
- โ”‚ โ””โ”€โ”€ utilities.js # Screenshots, waits
112
- โ”œโ”€โ”€ demos/ # Framework demonstrations
113
- โ”œโ”€โ”€ interactive/ # Interactive testing tools
114
- โ””โ”€โ”€ testing/ # Testing utilities
115
- ```
137
+ Endorphin AI is built with a modular, extensible architecture designed for reliability and maintainability.
138
+
139
+ ๐Ÿ“– **[View detailed Framework Architecture documentation](./doc/Framework-Architecture.md)**
140
+
141
+ ### Key Components
142
+ - **Core Framework**: Main test execution engine and session management
143
+ - **Browser Tools**: Intelligent automation tools powered by AI
144
+ - **Configuration System**: Flexible, hierarchical configuration management
145
+ - **Test Discovery**: Automatic test file detection and loading
146
+ - **Interactive Tools**: Real-time test creation and debugging
116
147
 
117
148
  ## โš™๏ธ Configuration
118
149
 
@@ -122,45 +153,20 @@ Endorphin AI works out of the box with sensible defaults, but you can customize
122
153
  ```javascript
123
154
  // endorphin.config.js
124
155
  export default {
125
- // Browser configuration
126
- browser: {
127
- type: 'chromium', // chromium, firefox, webkit
128
- headless: true, // Run browser in headless mode
129
- viewport: { // Browser viewport size
130
- width: 1280,
131
- height: 720
132
- },
133
- timeout: 30000 // Default timeout in milliseconds
134
- },
135
-
136
- // AI configuration
137
- ai: {
138
- model: 'gpt-4o-mini', // OpenAI model to use
139
- temperature: 0.1, // AI creativity (0-1)
140
- maxRetries: 3 // Max retries for AI calls
141
- },
142
-
143
- // Test execution configuration
144
- execution: {
145
- timeout: 60000, // Test timeout in milliseconds
146
- parallel: 1, // Number of parallel tests
147
- screenshots: true, // Take screenshots on failure
148
- testsDirectory: './tests', // Directory containing test files
149
- dataDirectory: './data' // Directory containing test data
156
+ // Global test settings
157
+ defaultTimeout: 30000,
158
+ headless: false,
159
+ viewport: { width: 1280, height: 720 },
160
+
161
+ // Default test data
162
+ testData: {
163
+ baseUrl: "https://staging.example.com",
164
+ adminEmail: "admin@example.com"
150
165
  },
151
-
152
- // Environment-specific settings
153
- environments: {
154
- development: {
155
- baseUrl: 'http://localhost:3000'
156
- },
157
- staging: {
158
- baseUrl: 'https://staging.example.com'
159
- },
160
- production: {
161
- baseUrl: 'https://example.com'
162
- }
163
- }
166
+
167
+ // Result settings
168
+ screenshots: true,
169
+ recordVideo: false
164
170
  };
165
171
  ```
166
172
 
@@ -168,23 +174,17 @@ export default {
168
174
  You can override configuration with CLI flags:
169
175
 
170
176
  ```bash
171
- # Run with different browser
172
- endorphin run test all --browser firefox
173
-
174
- # Run in non-headless mode
175
- endorphin run test QE-001 --no-headless
176
-
177
- # Set custom viewport
178
- endorphin run test all --viewport 1920x1080
179
-
180
- # Run tests in parallel
181
- endorphin run test all --parallel 3
182
-
183
- # Use different AI model
184
- endorphin run test all --model gpt-4
185
-
186
- # Set environment
187
- endorphin run test all --env staging
177
+ # Using npm scripts with -- to pass flags
178
+ npm test -- --browser firefox
179
+ npm run test:single QE-001 -- --no-headless
180
+
181
+ # Using npx/global
182
+ npx endorphin run test all --browser firefox
183
+ npx endorphin run test QE-001 --no-headless
184
+ npx endorphin run test all --viewport 1920x1080
185
+ npx endorphin run test all --parallel 3
186
+ npx endorphin run test all --model gpt-4
187
+ npx endorphin run test all --env staging
188
188
  ```
189
189
 
190
190
  ## ๐Ÿ“ Test Categories
@@ -265,48 +265,6 @@ export const QE002 = {
265
265
  };
266
266
  ```
267
267
 
268
- ## โš™๏ธ Configuration
269
-
270
- ### Optional: endorphin.config.js
271
- ```javascript
272
- export default {
273
- // Global test settings
274
- defaultTimeout: 30000,
275
- headless: false,
276
- viewport: { width: 1280, height: 720 },
277
-
278
- // Default test data
279
- testData: {
280
- baseUrl: "https://staging.example.com",
281
- adminEmail: "admin@example.com"
282
- },
283
-
284
- // Result settings
285
- screenshots: true,
286
- recordVideo: false
287
- };
288
- ```
289
-
290
- ## ๐Ÿ”ง Configuration
291
-
292
- ### Browser Configuration (`framework/config/browser-config.js`)
293
- - Browser launch options (headless mode, viewport size)
294
- - Timeouts and delays
295
- - Screenshot settings
296
- - Page loading options
297
-
298
- ### AI Agent Configuration (`framework/config/agent-config.js`)
299
- - OpenAI API settings
300
- - Model selection (GPT-4o)
301
- - Recursion limits and timeouts
302
- - Stop phrases for test completion
303
- - Execution timing settings
304
-
305
- ### Path Configuration (`framework/config/paths.js`)
306
- - Test result directories
307
- - Recording locations
308
- - Screenshot storage
309
-
310
268
  ## ๐Ÿ“Š Test Results
311
269
 
312
270
  Each test execution creates:
@@ -318,26 +276,21 @@ Each test execution creates:
318
276
 
319
277
  ### Example Test Output
320
278
  ```
321
- ๐ŸŽฏ Running Task: QE-001 - Basic Login Test
322
- ๐Ÿ“ Task: Test the login functionality with valid credentials
323
- โฐ Started at: 2025-06-19T05:36:37.705Z
324
-
325
- ๐Ÿ“ Created test session: qe-001_2025-06-19T05-36-37-706Z
326
- ๐ŸŒ Navigate to: https://qafromla.herokuapp.com
279
+ ๐ŸŽฏ Running: QE-001 - Basic Login Test
327
280
  ๐Ÿ“ธ Screenshot taken: step-1-navigation.png
328
- ๐Ÿ” Found login elements
329
- ๐Ÿ“ Filling login form...
330
281
  โœ… Login successful - test completed!
331
-
332
282
  ๐Ÿ“Š Result: PASSED
333
- ๐Ÿ“ Results: test-result/qe-001_2025-06-19T05-36-37-706Z
334
283
  ```
335
284
 
336
285
  ## ๐ŸŽฎ Interactive Features
337
286
 
338
287
  ### Custom Test Creation
339
288
  ```bash
340
- npm run interactive
289
+ # Using npm scripts
290
+ npm run test:record
291
+
292
+ # Using npx/global
293
+ npx endorphin run test-recorder
341
294
  ```
342
295
  Create tests on-the-fly with guided prompts:
343
296
  - Custom navigation tasks
@@ -345,114 +298,11 @@ Create tests on-the-fly with guided prompts:
345
298
  - Login test automation
346
299
  - Content verification
347
300
 
348
- ### Framework Demonstration
349
- ```bash
350
- npm run interactive-demo
351
- ```
352
- Runs pre-built demonstration tests showcasing:
353
- - Navigation capabilities
354
- - Form interaction
355
- - Content analysis
356
- - Result tracking
357
-
358
301
  ## ๐Ÿ” Browser Automation Tools
359
302
 
360
- The framework includes intelligent tools powered by AI:
361
-
362
- ### Navigation Tools
363
- - **navigate**: Smart URL navigation with wait conditions
364
- - **getPageContent**: Intelligent HTML analysis for element detection
365
-
366
- ### Interaction Tools
367
- - **click**: AI-powered element clicking with automatic waiting
368
- - **fill**: Smart form filling with focus management
369
- - **clearField**: Intelligent field clearing before input
370
-
371
- ### Verification Tools
372
- - **verifyElement**: Element visibility and interaction verification
373
- - **getElementInfo**: Detailed element analysis and properties
374
-
375
- ### Utility Tools
376
- - **wait**: Configurable delays and timing control
377
- - **screenshot**: High-quality visual documentation
378
-
379
- ## ๐ŸŽฎ Command Examples
380
-
381
- ### Basic Commands
382
- ```bash
383
- # Run specific test
384
- endorphin run test QE-001
385
-
386
- # Run all tests
387
- endorphin run test all
388
-
389
- # Run by priority
390
- endorphin run test --priority High
391
- endorphin run test --priority Medium
392
-
393
- # Run by tags
394
- endorphin run test --tag authentication
395
- endorphin run test --tag smoke
396
- endorphin run test --tag checkout
303
+ Intelligent AI-powered tools for navigation, interaction, verification, and utilities.
397
304
 
398
- # Interactive test creation
399
- endorphin run test-recorder
400
- ```
401
-
402
- ### Multiple Tag Support
403
- ```bash
404
- # Run tests matching any of these tags
405
- endorphin run test --tag "authentication,smoke"
406
-
407
- # Run high priority authentication tests
408
- endorphin run test --priority High --tag authentication
409
- ```
410
-
411
- ## ๐Ÿš€ Getting Started Examples
412
-
413
- ### Quick Smoke Test
414
- ```bash
415
- endorphin run test --tag smoke
416
- ```
417
-
418
- ### Authentication Testing
419
- ```bash
420
- endorphin run test --tag authentication
421
- ```
422
-
423
- ### Complete Test Suite
424
- ```bash
425
- endorphin run test all
426
- ```
427
-
428
- ### Create Custom Test
429
- ```bash
430
- endorphin run test-recorder
431
- # Follow prompts to create your own test
432
- ```
433
-
434
- ### Example Test File
435
- Create `tests/my-first-test.js`:
436
- ```javascript
437
- export const QE001 = {
438
- id: "QE-001",
439
- name: "Homepage Navigation Test",
440
- description: "Verify main navigation works correctly",
441
- priority: "High",
442
- tags: ["navigation", "smoke"],
443
- site: "https://example.com/",
444
- task: `Navigate to https://example.com/.
445
- Click on "About" link in navigation.
446
- Wait 2 seconds for page load.
447
- Verify page title contains "About".
448
- Take a screenshot.`
449
- };
450
- ```
451
-
452
- Then run it:
453
- ```bash
454
- endorphin run test QE-001
455
- ```
305
+ ๐Ÿ“– **[View detailed tool documentation](./doc/Framework-Architecture.md#browser-automation-tools)**
456
306
 
457
307
  ## ๐ŸŽ‰ Features
458
308
 
@@ -1,5 +1,5 @@
1
- // Endorphin e2e AI test framework>
2
- // Copyright (C) 2025 Redstudio Agency
1
+ // Endorphin e2e AI test framework
2
+ // Copyright (C) 2025 Redstudio Agency
3
3
 
4
4
  // This program is free software: you can redistribute it and/or modify
5
5
  // it under the terms of the GNU Affero General Public License as
@@ -34,31 +34,32 @@ export class TestRecorder {
34
34
  this.stepCounter = 0;
35
35
  this.recordingId = null;
36
36
  this.recordingPath = null;
37
- this.screenshotsPath = null;
37
+ this.stepsPath = null;
38
38
  this.isRecording = false;
39
+ this.startTime = null;
39
40
  }
40
41
 
41
42
  /**
42
43
  * Start recording session
43
44
  */
44
45
  async startRecording() {
45
- const timestamp = new Date().toISOString().replace(/[:.]/g, '-').slice(0, -5) + 'Z';
46
- this.recordingId = `${this.testData.id || 'INTERACTIVE-TEST'}_${timestamp}`;
46
+ this.startTime = new Date();
47
+ const timestamp = Date.now();
48
+ this.recordingId = `${this.testData.id || 'REC'}-${timestamp}`;
47
49
 
48
- // Create recording directories
49
- const rootPath = path.resolve(__dirname, '../../');
50
- this.recordingPath = path.join(rootPath, 'test-recorder', this.recordingId);
51
- this.screenshotsPath = path.join(this.recordingPath, 'screenshots');
50
+ // Create recording directories in USER project (not framework)
51
+ this.recordingPath = path.join(process.cwd(), 'test-recorder', this.recordingId);
52
+ this.stepsPath = path.join(this.recordingPath, 'steps');
52
53
 
53
54
  await fs.mkdir(this.recordingPath, { recursive: true });
54
- await fs.mkdir(this.screenshotsPath, { recursive: true });
55
+ await fs.mkdir(this.stepsPath, { recursive: true });
55
56
 
56
57
  this.isRecording = true;
57
58
  this.stepCounter = 0;
58
59
  this.steps = [];
59
60
 
60
- console.log(`๐ŸŽฌ Recording started: ${this.recordingId}`);
61
- console.log(`๐Ÿ“ Recording path: ${this.recordingPath}`);
61
+ console.log('Recording session:', this.recordingId);
62
+ console.log('Artifacts will be saved to:', this.recordingPath);
62
63
 
63
64
  return this.recordingId;
64
65
  }
@@ -66,69 +67,73 @@ export class TestRecorder {
66
67
  /**
67
68
  * Record a step with tool call and screenshot
68
69
  */
69
- async recordStep(prompt, toolName, toolParams, result) {
70
+ async recordStep(description, type, data, result) {
70
71
  if (!this.isRecording) return;
71
72
 
72
73
  this.stepCounter++;
73
- const stepId = `step-${this.stepCounter}`;
74
+ const stepId = String(this.stepCounter).padStart(3, '0');
75
+ const stepFolderName = `${stepId}-${this.sanitizeFileName(description)}`;
76
+ const stepPath = path.join(this.stepsPath, stepFolderName);
74
77
 
75
- // Take screenshot before and after action
76
- const screenshotBefore = await this.takeScreenshot(`${stepId}-before`);
78
+ // Create step folder
79
+ await fs.mkdir(stepPath, { recursive: true });
77
80
 
78
- const step = {
79
- id: stepId,
81
+ // Take BEFORE screenshot
82
+ const beforeScreenshot = path.join(stepPath, 'before.png');
83
+ await this.framework.page.screenshot({ path: beforeScreenshot, fullPage: true });
84
+
85
+ // Record step info
86
+ const stepInfo = {
80
87
  stepNumber: this.stepCounter,
88
+ description,
89
+ type,
81
90
  timestamp: new Date().toISOString(),
82
- prompt: prompt,
83
- tool: {
84
- name: toolName,
85
- params: toolParams
86
- },
87
- result: result,
88
- screenshots: {
89
- before: screenshotBefore
90
- }
91
+ data,
92
+ result,
93
+ beforeScreenshot: 'before.png',
94
+ afterScreenshot: 'after.png'
91
95
  };
92
96
 
93
- // Take screenshot after action (with small delay)
94
- await this.framework.page.waitForTimeout(1000);
95
- const screenshotAfter = await this.takeScreenshot(`${stepId}-after`);
96
- step.screenshots.after = screenshotAfter;
97
+ // Take AFTER screenshot (small delay to ensure DOM updates)
98
+ await new Promise(resolve => setTimeout(resolve, 500));
99
+ const afterScreenshot = path.join(stepPath, 'after.png');
100
+ await this.framework.page.screenshot({ path: afterScreenshot, fullPage: true });
101
+
102
+ // Save step info
103
+ await fs.writeFile(
104
+ path.join(stepPath, 'step-info.json'),
105
+ JSON.stringify(stepInfo, null, 2)
106
+ );
97
107
 
98
- this.steps.push(step);
108
+ // Add to steps array
109
+ this.steps.push({
110
+ ...stepInfo,
111
+ stepFolder: stepFolderName
112
+ });
99
113
 
100
- // Log to console
101
- console.log(`\n๐Ÿ“ Step ${this.stepCounter}: ${prompt}`);
102
- console.log(`๐Ÿ”ง Tool: ${toolName}`);
103
- console.log(`๐Ÿ“ธ Screenshots: ${screenshotBefore}, ${screenshotAfter}`);
114
+ console.log(`Step ${this.stepCounter} recorded: ${description}`);
104
115
 
105
- // Show visual feedback in browser
106
- await this.showBrowserFeedback(stepId, prompt, toolName);
116
+ // Show visual feedback in browser
117
+ await this.showBrowserFeedback(this.stepCounter, description, type);
107
118
 
108
- return step;
119
+ return stepInfo;
109
120
  }
110
121
 
111
122
  /**
112
- * Take screenshot and save to recording folder
123
+ * Sanitize filename for step folders
113
124
  */
114
- async takeScreenshot(filename) {
115
- try {
116
- const screenshotPath = path.join(this.screenshotsPath, `${filename}.png`);
117
- await this.framework.page.screenshot({
118
- path: screenshotPath,
119
- fullPage: true
120
- });
121
- return `${filename}.png`;
122
- } catch (error) {
123
- console.log(`โš ๏ธ Screenshot failed: ${error.message}`);
124
- return null;
125
- }
125
+ sanitizeFileName(description) {
126
+ return description
127
+ .toLowerCase()
128
+ .replace(/[^a-z0-9\s-]/g, '')
129
+ .replace(/\s+/g, '-')
130
+ .substring(0, 30);
126
131
  }
127
132
 
128
133
  /**
129
134
  * Show visual feedback in browser
130
135
  */
131
- async showBrowserFeedback(stepId, prompt, toolName) {
136
+ async showBrowserFeedback(stepId, description, type) {
132
137
  try {
133
138
  await this.framework.page.evaluate((data) => {
134
139
  // Remove previous feedback
@@ -155,9 +160,9 @@ export class TestRecorder {
155
160
  `;
156
161
 
157
162
  overlay.innerHTML = `
158
- <div style="font-weight: bold; margin-bottom: 8px;">๐ŸŽฌ Recording Step ${data.stepId}</div>
159
- <div style="margin-bottom: 5px;"><strong>Action:</strong> ${data.prompt}</div>
160
- <div><strong>Tool:</strong> ${data.toolName}</div>
163
+ <div style="font-weight: bold; margin-bottom: 8px;">Recording Step ${data.stepId}</div>
164
+ <div style="margin-bottom: 5px;"><strong>Action:</strong> ${data.description}</div>
165
+ <div><strong>Type:</strong> ${data.type}</div>
161
166
  `;
162
167
 
163
168
  // Add animation keyframes if not exists
@@ -183,7 +188,7 @@ export class TestRecorder {
183
188
  }
184
189
  }, 3000);
185
190
 
186
- }, { stepId, prompt, toolName });
191
+ }, { stepId, description, type });
187
192
  } catch (error) {
188
193
  // Browser feedback is optional, don't fail if it doesn't work
189
194
  }
@@ -231,9 +236,9 @@ export class TestRecorder {
231
236
  // Generate test file
232
237
  await this.generateTestFile();
233
238
 
234
- console.log(`\nโœ… Recording completed: ${this.recordingId}`);
235
- console.log(`๐Ÿ“ Artifacts saved to: ${this.recordingPath}`);
236
- console.log(`๐Ÿงช Test file generated in tests/ folder`);
239
+ console.log('Recording completed:', this.recordingId);
240
+ console.log('Artifacts saved to:', this.recordingPath);
241
+ console.log('Test file generated in tests/ folder');
237
242
 
238
243
  return {
239
244
  recordingId: this.recordingId,
@@ -249,43 +254,39 @@ export class TestRecorder {
249
254
  async generateTestFile() {
250
255
  const testId = this.testData.id || 'QE-NEW';
251
256
  const filename = `${testId.toLowerCase()}-recorded-test.js`;
252
- const testPath = path.resolve(__dirname, '../../tests', filename);
257
+
258
+ // Ensure tests directory exists
259
+ const testsDir = path.join(process.cwd(), 'tests');
260
+ await fs.mkdir(testsDir, { recursive: true });
261
+
262
+ const testPath = path.join(testsDir, filename);
253
263
 
254
264
  // Build task from recorded steps
255
265
  const taskSteps = this.steps.map(step => {
256
- const toolName = step.tool.name;
257
- const params = step.tool.params;
258
-
259
- switch (toolName) {
260
- case 'navigate':
261
- return `Navigate to ${params.url}.`;
262
- case 'click':
263
- return `Click on "${params.selector || 'element'}".`;
264
- case 'fill':
265
- return `Fill "${params.selector || 'field'}" with "${params.value}".`;
266
- case 'clearField':
267
- return `Clear field "${params.selector}".`;
268
- case 'wait':
269
- return `Wait ${params.time || 1000}ms.`;
270
- case 'screenshot':
271
- return `Take screenshot.`;
272
- default:
273
- return step.prompt;
274
- }
266
+ // For now, use generic descriptions until we implement proper task building
267
+ return step.description;
275
268
  }).join(' ');
276
269
 
270
+ // Add "recorded" tag if not already present
271
+ const tags = this.testData.tags || [];
272
+ if (!tags.includes('recorded')) {
273
+ tags.push('recorded');
274
+ }
275
+
276
+ const exportName = testId.replace(/-/g, '_');
277
+
277
278
  const testContent = `// ${testId}: ${this.testData.name}
278
279
  // Description: ${this.testData.description}
279
280
  // Priority: ${this.testData.priority || 'Medium'}
280
- // Tags: ${(this.testData.tags || []).join(', ')}
281
+ // Tags: ${tags.join(', ')}
281
282
  // Generated by Test Recorder: ${this.recordingId}
282
283
 
283
- export const ${testId.replace(/-/g, '')} = {
284
+ export const ${exportName} = {
284
285
  "id": "${testId}",
285
286
  "name": "${this.testData.name}",
286
287
  "description": "${this.testData.description}",
287
288
  "priority": "${this.testData.priority || 'Medium'}",
288
- "tags": ${JSON.stringify(this.testData.tags || [], null, 4)},
289
+ "tags": ${JSON.stringify(tags, null, 4)},
289
290
  "site": "${this.testData.site}",
290
291
  "testData": ${JSON.stringify(this.testData.testData || {}, null, 4)},
291
292
  "task": "${taskSteps} STOP - test completed.",
@@ -295,7 +296,7 @@ export const ${testId.replace(/-/g, '')} = {
295
296
  `;
296
297
 
297
298
  await fs.writeFile(testPath, testContent);
298
- console.log(`๐Ÿ“ Test file created: ${filename}`);
299
+ console.log('Test file created:', filename);
299
300
 
300
301
  return testPath;
301
302
  }
@@ -1,5 +1,5 @@
1
- // Endorphin e2e AI test framework>
2
- // Copyright (C) 2025 Redstudio Agency
1
+ // Endorphin e2e AI test framework
2
+ // Copyright (C) 2025 Redstudio Agency
3
3
 
4
4
  // This program is free software: you can redistribute it and/or modify
5
5
  // it under the terms of the GNU Affero General Public License as
@@ -28,7 +28,6 @@ export { AGENT_CONFIG } from './config/agent-config.js';
28
28
  export { PATHS } from './config/paths.js';
29
29
 
30
30
  // Module exports for organized components
31
- export * as Demos from './demos/index.js';
32
31
  export * as Interactive from './interactive/index.js';
33
32
  export * as Testing from './testing/index.js';
34
33
 
@@ -108,7 +108,7 @@ async function collectTestData() {
108
108
  return testData;
109
109
  }
110
110
 
111
- async function runInteractiveRecorder() {
111
+ async function runInteractiveRecorder(config = {}) {
112
112
  console.log('\n๐ŸŽฌ Interactive Test Recorder');
113
113
  console.log('โ•'.repeat(50));
114
114
  console.log('Record browser interactions step by step!');
@@ -126,7 +126,8 @@ async function runInteractiveRecorder() {
126
126
  return;
127
127
  }
128
128
 
129
- const framework = new EnhancedBrowserTestFramework();
129
+ // Create framework with the config from CLI
130
+ const framework = new EnhancedBrowserTestFramework(config);
130
131
  const recorder = new TestRecorder(framework, testData);
131
132
 
132
133
  try {
@@ -211,7 +212,6 @@ async function runInteractiveRecorder() {
211
212
  } finally {
212
213
  await framework.cleanup();
213
214
  rl.close();
214
- rl.close();
215
215
  }
216
216
  }
217
217
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "endorphin-ai",
3
- "version": "0.1.0",
3
+ "version": "0.2.1",
4
4
  "description": "E2E Testing Reinvented with AI - A powerful browser automation framework using AI-powered testing with LangChain, OpenAI GPT-4o, and Playwright",
5
5
  "main": "framework/index.js",
6
6
  "bin": {
@@ -13,20 +13,15 @@
13
13
  "test:watch": "vitest --watch",
14
14
  "test:ui": "vitest --ui",
15
15
  "test:coverage": "vitest run --coverage",
16
+ "test:recorder": "vitest run dev-tests/test-recorder*.test.js",
16
17
  "framework:test": "node framework/test-framework.js --test",
17
18
  "framework:demo": "node framework/test-framework.js",
18
19
  "framework:all": "node framework/test-framework.js --all",
19
20
  "framework:list": "node framework/test-framework.js --list",
20
- "framework:comprehensive": "node framework/test-framework.js --comprehensive",
21
- "framework:QE-001": "node framework/test-framework.js --test QE-001",
22
- "framework:QE-002": "node framework/test-framework.js --test QE-002",
23
21
  "framework:auth": "node framework/test-framework.js --tag authentication",
24
22
  "framework:smoke": "node framework/test-framework.js --tag smoke",
25
23
  "framework:high": "node framework/test-framework.js --priority High",
26
- "verify-format": "node framework/testing/verify-test-format.js",
27
- "test-recorder": "node framework/interactive/enhanced-interactive-recorder.js",
28
- "test-recorder-demo": "node framework/demos/interactive-demo.js",
29
- "test-framework": "node framework/testing/test-modular-framework.js"
24
+ "test-recorder": "node framework/interactive/enhanced-interactive-recorder.js"
30
25
  },
31
26
  "keywords": [
32
27
  "ai",
@@ -81,4 +76,4 @@
81
76
  "vitest": "^2.1.8",
82
77
  "@vitest/ui": "^2.1.8"
83
78
  }
84
- }
79
+ }