endorphin-ai 0.1.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.
Files changed (35) hide show
  1. package/LICENSE.md +209 -0
  2. package/README.md +474 -0
  3. package/bin/endorphin.js +256 -0
  4. package/examples/endorphin.config.js +22 -0
  5. package/examples/tests/QE-001-basic-login-test.js +18 -0
  6. package/examples/tests/sample-test.js +9 -0
  7. package/examples/tools/.gitkeep +0 -0
  8. package/framework/config/agent-config.js +53 -0
  9. package/framework/config/browser-config.js +53 -0
  10. package/framework/config/paths.js +40 -0
  11. package/framework/core/agent-setup.js +75 -0
  12. package/framework/core/browser-framework.js +766 -0
  13. package/framework/core/config-loader.js +309 -0
  14. package/framework/core/test-discovery.js +402 -0
  15. package/framework/core/test-manager.js +343 -0
  16. package/framework/core/test-recorder.js +302 -0
  17. package/framework/core/test-runner.js +133 -0
  18. package/framework/core/test-session.js +98 -0
  19. package/framework/index.js +44 -0
  20. package/framework/interactive/enhanced-interactive-recorder.js +223 -0
  21. package/framework/interactive/index.js +18 -0
  22. package/framework/interactive/interactive-test-clean.js +33 -0
  23. package/framework/interactive/interactive-test.js +33 -0
  24. package/framework/test-framework.js +29 -0
  25. package/framework/testing/index.js +15 -0
  26. package/framework/testing/test-interactive-recorder.js +83 -0
  27. package/framework/testing/test-modular-framework.js +47 -0
  28. package/framework/testing/verify-test-format.js +58 -0
  29. package/framework/tools/content.js +67 -0
  30. package/framework/tools/index.js +52 -0
  31. package/framework/tools/interaction.js +180 -0
  32. package/framework/tools/navigation.js +43 -0
  33. package/framework/tools/utilities.js +99 -0
  34. package/framework/tools/verification.js +84 -0
  35. package/package.json +84 -0
@@ -0,0 +1,133 @@
1
+ // Endorphin e2e AI test framework>
2
+ // Copyright (C) 2025 Redstudio Agency
3
+
4
+ // This program is free software: you can redistribute it and/or modify
5
+ // it under the terms of the GNU Affero General Public License as
6
+ // published by the Free Software Foundation, either version 3 of the
7
+ // License, or (at your option) any later version.
8
+
9
+ // This program is distributed in the hope that it will be useful,
10
+ // but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ // GNU Affero General Public License for more details.
13
+
14
+ // You should have received a copy of the GNU Affero General Public License
15
+ // along with this program. If not, see <http://www.gnu.org/licenses/>.
16
+
17
+
18
+
19
+ import { HumanMessage } from "@langchain/core/messages";
20
+ import { AGENT_CONFIG } from '../config/agent-config.js';
21
+
22
+ /**
23
+ * Run a test task using the AI agent
24
+ * @param {Object} framework - Framework instance
25
+ * @param {string} taskDescription - Description of the task to perform
26
+ * @param {string} testName - Optional test name
27
+ * @returns {Object} Test result
28
+ */
29
+ export async function runTask(framework, taskDescription, testName = null) {
30
+ const timestamp = new Date().toISOString();
31
+ const name = testName || `Test-${Date.now()}`;
32
+
33
+ console.log(`\nšŸŽÆ Running Task: ${name}`);
34
+ console.log(`šŸ“ Task: ${taskDescription}`);
35
+ console.log(`ā° Started at: ${timestamp}\n`);
36
+
37
+ // Create test session
38
+ const session = framework.createTestSession(name, name.replace(/\s+/g, '-').toLowerCase());
39
+ framework.currentTestSession = session;
40
+
41
+ try {
42
+ // Log initial step
43
+ framework.logTestStep("Test started", null, null, `Starting task: ${taskDescription}`, true);
44
+ await framework.takeStepScreenshot("Initial page state");
45
+
46
+ const finalState = await framework.agent.invoke({
47
+ messages: [new HumanMessage(taskDescription)],
48
+ }, {
49
+ recursionLimit: AGENT_CONFIG.agent.recursionLimit,
50
+ configurable: { thread_id: `session-${framework.currentTestSession.sessionId}` }
51
+ });
52
+
53
+ const result = finalState.messages[finalState.messages.length - 1].content;
54
+
55
+ // Log final step
56
+ framework.logTestStep("Test completed", null, null, result, true);
57
+ await framework.takeStepScreenshot("Final page state");
58
+
59
+ // Finish session
60
+ await framework.finishTestSession('SUCCESS', result);
61
+
62
+ console.log(`\nāœ… Task "${name}" completed successfully!`);
63
+ console.log(`šŸ“Š Result: ${result}\n`);
64
+
65
+ return {
66
+ testName: name,
67
+ task: taskDescription,
68
+ timestamp,
69
+ status: 'SUCCESS',
70
+ result: result,
71
+ duration: Date.now() - new Date(timestamp).getTime(),
72
+ sessionDir: session.sessionDir
73
+ };
74
+
75
+ } catch (error) {
76
+ console.error(`\nāŒ Task "${name}" failed:`);
77
+ console.error(`šŸ’„ Error: ${error.message}\n`);
78
+
79
+ // Log error step
80
+ framework.logTestStep("Test failed", null, null, error.message, false);
81
+ await framework.takeStepScreenshot("Error state");
82
+
83
+ // Finish session with failure
84
+ await framework.finishTestSession('FAILED', error.message);
85
+
86
+ return {
87
+ testName: name,
88
+ task: taskDescription,
89
+ timestamp,
90
+ status: 'FAILED',
91
+ error: error.message,
92
+ duration: Date.now() - new Date(timestamp).getTime(),
93
+ sessionDir: session.sessionDir
94
+ };
95
+ }
96
+ }
97
+
98
+ /**
99
+ * Run multiple test tasks in sequence
100
+ * @param {Object} framework - Framework instance
101
+ * @param {Array} tasks - Array of task objects {name, description}
102
+ * @returns {Array} Array of test results
103
+ */
104
+ export async function runTaskSequence(framework, tasks) {
105
+ const results = [];
106
+
107
+ console.log(`\nšŸŽÆ Running ${tasks.length} tasks in sequence...\n`);
108
+
109
+ for (let i = 0; i < tasks.length; i++) {
110
+ const task = tasks[i];
111
+ console.log(`\nšŸ“‹ Task ${i + 1}/${tasks.length}: ${task.name}`);
112
+
113
+ const result = await runTask(framework, task.description, task.name);
114
+ results.push(result);
115
+
116
+ // Add delay between tasks if configured
117
+ if (AGENT_CONFIG.execution.stepDelay && i < tasks.length - 1) {
118
+ console.log(`ā±ļø Waiting ${AGENT_CONFIG.execution.stepDelay}ms before next task...`);
119
+ await new Promise(resolve => setTimeout(resolve, AGENT_CONFIG.execution.stepDelay));
120
+ }
121
+ }
122
+
123
+ // Print summary
124
+ const successful = results.filter(r => r.status === 'SUCCESS').length;
125
+ const failed = results.filter(r => r.status === 'FAILED').length;
126
+
127
+ console.log(`\nšŸ“Š Task Sequence Summary:`);
128
+ console.log(` āœ… Successful: ${successful}`);
129
+ console.log(` āŒ Failed: ${failed}`);
130
+ console.log(` šŸ“ˆ Success Rate: ${(successful / results.length * 100).toFixed(1)}%\n`);
131
+
132
+ return results;
133
+ }
@@ -0,0 +1,98 @@
1
+ // Endorphin e2e AI test framework>
2
+ // Copyright (C) 2025 Redstudio Agency
3
+
4
+ // This program is free software: you can redistribute it and/or modify
5
+ // it under the terms of the GNU Affero General Public License as
6
+ // published by the Free Software Foundation, either version 3 of the
7
+ // License, or (at your option) any later version.
8
+
9
+ // This program is distributed in the hope that it will be useful,
10
+ // but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ // GNU Affero General Public License for more details.
13
+
14
+ // You should have received a copy of the GNU Affero General Public License
15
+ // along with this program. If not, see <http://www.gnu.org/licenses/>.
16
+
17
+
18
+ import fs from 'fs';
19
+ import path from 'path';
20
+
21
+ /**
22
+ * Create a new test session with directory structure and metadata
23
+ * @param {string} testName - Name of the test
24
+ * @param {string} testId - Optional test ID
25
+ * @param {string} resultBaseDir - Base directory for test results
26
+ * @returns {Object} Test session object
27
+ */
28
+ export function createTestSession(testName, testId = null, resultBaseDir) {
29
+ const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
30
+ const sessionId = testId || `test-${Date.now()}`;
31
+ const sessionName = `${sessionId}_${timestamp}`;
32
+ const sessionDir = path.join(resultBaseDir, sessionName);
33
+ const screenshotsDir = path.join(sessionDir, 'screenshots');
34
+
35
+ // Create directories
36
+ fs.mkdirSync(sessionDir, { recursive: true });
37
+ fs.mkdirSync(screenshotsDir, { recursive: true });
38
+
39
+ const session = {
40
+ sessionId,
41
+ sessionName,
42
+ testName,
43
+ testId,
44
+ startTime: new Date().toISOString(),
45
+ endTime: null,
46
+ sessionDir,
47
+ screenshotsDir,
48
+ steps: [],
49
+ toolCalls: [],
50
+ stepCounter: 0,
51
+ screenshotCounter: 0,
52
+ status: 'RUNNING',
53
+ finalResult: null,
54
+ duration: null
55
+ };
56
+
57
+ console.log(`šŸ“ Created test session: ${sessionName}`);
58
+ return session;
59
+ }
60
+
61
+ /**
62
+ * Generate test session summary
63
+ * @param {Object} session - Test session object
64
+ * @returns {Object} Session summary
65
+ */
66
+ export function generateSessionSummary(session) {
67
+ return {
68
+ testName: session.testName,
69
+ sessionId: session.sessionId,
70
+ status: session.status,
71
+ startTime: session.startTime,
72
+ endTime: session.endTime,
73
+ duration: session.duration,
74
+ totalSteps: session.steps.length,
75
+ successfulSteps: session.steps.filter(s => s.status === 'SUCCESS').length,
76
+ failedSteps: session.steps.filter(s => s.status === 'FAILED').length,
77
+ totalScreenshots: session.screenshotCounter,
78
+ finalResult: session.finalResult
79
+ };
80
+ }
81
+
82
+ /**
83
+ * Save test session data to files
84
+ * @param {Object} session - Test session object
85
+ */
86
+ export function saveTestSession(session) {
87
+ // Save complete session data
88
+ const sessionFile = path.join(session.sessionDir, 'test-session.json');
89
+ fs.writeFileSync(sessionFile, JSON.stringify(session, null, 2));
90
+
91
+ // Save summary
92
+ const summary = generateSessionSummary(session);
93
+ const summaryFile = path.join(session.sessionDir, 'summary.json');
94
+ fs.writeFileSync(summaryFile, JSON.stringify(summary, null, 2));
95
+
96
+ console.log(`šŸ’¾ Session data saved to: ${session.sessionDir}`);
97
+ return summary;
98
+ }
@@ -0,0 +1,44 @@
1
+ // Endorphin e2e AI test framework>
2
+ // Copyright (C) 2025 Redstudio Agency
3
+
4
+ // This program is free software: you can redistribute it and/or modify
5
+ // it under the terms of the GNU Affero General Public License as
6
+ // published by the Free Software Foundation, either version 3 of the
7
+ // License, or (at your option) any later version.
8
+
9
+ // This program is distributed in the hope that it will be useful,
10
+ // but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ // GNU Affero General Public License for more details.
13
+
14
+ // You should have received a copy of the GNU Affero General Public License
15
+ // along with this program. If not, see <http://www.gnu.org/licenses/>.
16
+
17
+ export { EnhancedBrowserTestFramework } from './core/browser-framework.js';
18
+ export { TestRecorder } from './core/test-recorder.js';
19
+ export { runTask, runTaskSequence } from './core/test-runner.js';
20
+ export { createTestSession, generateSessionSummary, saveTestSession } from './core/test-session.js';
21
+ export { setupAgent } from './core/agent-setup.js';
22
+ export { createAllTools } from './tools/index.js';
23
+ export { TestManager } from './core/test-manager.js';
24
+
25
+ // Configuration exports
26
+ export { BROWSER_CONFIG } from './config/browser-config.js';
27
+ export { AGENT_CONFIG } from './config/agent-config.js';
28
+ export { PATHS } from './config/paths.js';
29
+
30
+ // Module exports for organized components
31
+ export * as Demos from './demos/index.js';
32
+ export * as Interactive from './interactive/index.js';
33
+ export * as Testing from './testing/index.js';
34
+
35
+ // Individual tool creators for custom setups
36
+ export { createNavigationTool } from './tools/navigation.js';
37
+ export { createGetPageContentTool, createGetSimplePageContentTool } from './tools/content.js';
38
+ export { createClickTool, createFillTool, createClearFieldTool } from './tools/interaction.js';
39
+ export { createVerifyElementTool, createGetElementInfoTool } from './tools/verification.js';
40
+ export { createWaitTool, createScreenshotTool } from './tools/utilities.js';
41
+
42
+ // Default export for simple usage: import EndorphinAI from 'endorphin-ai'
43
+ import { EnhancedBrowserTestFramework } from './core/browser-framework.js';
44
+ export default EnhancedBrowserTestFramework;
@@ -0,0 +1,223 @@
1
+ // Endorphin e2e AI test framework>
2
+ // Copyright (C) 2025 Redstudio Agency
3
+
4
+ // This program is free software: you can redistribute it and/or modify
5
+ // it under the terms of the GNU Affero General Public License as
6
+ // published by the Free Software Foundation, either version 3 of the
7
+ // License, or (at your option) any later version.
8
+
9
+ // This program is distributed in the hope that it will be useful,
10
+ // but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ // GNU Affero General Public License for more details.
13
+
14
+ // You should have received a copy of the GNU Affero General Public License
15
+ // along with this program. If not, see <http://www.gnu.org/licenses/>.
16
+
17
+ import { EnhancedBrowserTestFramework } from '../index.js';
18
+ import { TestRecorder } from '../core/test-recorder.js';
19
+ import readline from 'readline';
20
+ import dotenv from 'dotenv';
21
+
22
+ // Load environment variables
23
+ dotenv.config();
24
+
25
+ const rl = readline.createInterface({
26
+ input: process.stdin,
27
+ output: process.stdout
28
+ });
29
+
30
+ function askQuestion(question) {
31
+ return new Promise((resolve) => {
32
+ rl.question(question, (answer) => {
33
+ resolve(answer);
34
+ });
35
+ });
36
+ }
37
+
38
+ async function collectTestData() {
39
+ console.log('\nšŸ“‹ Test Data Collection');
40
+ console.log('═'.repeat(40));
41
+
42
+ const testData = {};
43
+
44
+ // Required fields
45
+ testData.id = await askQuestion('Test ID (e.g., QE-012): ');
46
+ testData.name = await askQuestion('Test Name: ');
47
+ testData.description = await askQuestion('Test Description: ');
48
+
49
+ // Optional fields
50
+ const priority = await askQuestion('Priority (High/Medium/Low) [Medium]: ');
51
+ testData.priority = priority || 'Medium';
52
+
53
+ const tags = await askQuestion('Tags (comma-separated): ');
54
+ testData.tags = tags ? tags.split(',').map(tag => tag.trim()) : [];
55
+
56
+ // Site URL (use env variable as default)
57
+ const defaultSite = process.env.BASE_URL || 'https://qafromla.herokuapp.com/';
58
+ const site = await askQuestion(`Site URL [${defaultSite}]: `);
59
+ testData.site = site || defaultSite;
60
+
61
+ // Collect test data object
62
+ console.log('\nšŸ”§ Test Data (for form filling, login, etc.)');
63
+ console.log('Press Enter to skip any field');
64
+
65
+ const testDataObj = {};
66
+
67
+ const uid = await askQuestion('User ID: ');
68
+ if (uid) testDataObj.uid = uid;
69
+
70
+ const email = await askQuestion('Email: ');
71
+ if (email) testDataObj.email = email;
72
+
73
+ const password = await askQuestion('Password: ');
74
+ if (password) testDataObj.password = password;
75
+
76
+ const firstName = await askQuestion('First Name: ');
77
+ if (firstName) testDataObj.firstName = firstName;
78
+
79
+ const lastName = await askQuestion('Last Name: ');
80
+ if (lastName) testDataObj.lastName = lastName;
81
+
82
+ // Add any additional custom fields
83
+ console.log('\nAdd custom fields (key=value format, or press Enter to finish):');
84
+ while (true) {
85
+ const customField = await askQuestion('Custom field (key=value): ');
86
+ if (!customField) break;
87
+
88
+ const [key, ...valueParts] = customField.split('=');
89
+ const value = valueParts.join('=');
90
+ if (key && value) {
91
+ testDataObj[key.trim()] = value.trim();
92
+ }
93
+ }
94
+
95
+ testData.testData = testDataObj;
96
+
97
+ // Display collected data
98
+ console.log('\nšŸ“Š Collected Test Data:');
99
+ console.log('═'.repeat(40));
100
+ console.log(JSON.stringify(testData, null, 2));
101
+
102
+ const confirm = await askQuestion('\nConfirm test data? (y/n): ');
103
+ if (confirm.toLowerCase() !== 'y') {
104
+ console.log('āŒ Test data collection cancelled');
105
+ return null;
106
+ }
107
+
108
+ return testData;
109
+ }
110
+
111
+ async function runInteractiveRecorder() {
112
+ console.log('\nšŸŽ¬ Interactive Test Recorder');
113
+ console.log('═'.repeat(50));
114
+ console.log('Record browser interactions step by step!');
115
+ console.log('Commands:');
116
+ console.log('• Type natural language commands (e.g., "click login button")');
117
+ console.log('• Type "done" to stop recording and generate test');
118
+ console.log('• Each step will be recorded with screenshots');
119
+ console.log('═'.repeat(50));
120
+
121
+ // Collect test data first
122
+ const testData = await collectTestData();
123
+ if (!testData) {
124
+ console.log('šŸ‘‹ Exiting...');
125
+ rl.close();
126
+ return;
127
+ }
128
+
129
+ const framework = new EnhancedBrowserTestFramework();
130
+ const recorder = new TestRecorder(framework, testData);
131
+
132
+ try {
133
+ // Initialize framework
134
+ console.log('\nšŸš€ Initializing browser...');
135
+ await framework.initialize();
136
+
137
+ // Start recording
138
+ const recordingId = await recorder.startRecording();
139
+
140
+ // Navigate to the site
141
+ console.log(`\n🌐 Navigating to: ${testData.site}`);
142
+ await framework.tools.navigate({ url: testData.site });
143
+
144
+ // Record the navigation step
145
+ await recorder.recordStep(
146
+ `Navigate to ${testData.site}`,
147
+ 'navigate',
148
+ { url: testData.site },
149
+ 'Navigation completed'
150
+ );
151
+
152
+ console.log('\nšŸ’¬ Ready for interactive commands!');
153
+ console.log('Type your commands or "done" to finish recording.\n');
154
+
155
+ // Interactive command loop
156
+ while (true) {
157
+ const prompt = await askQuestion('šŸŽ¬ Next step: ');
158
+
159
+ if (prompt.toLowerCase() === 'done') {
160
+ console.log('\nšŸ›‘ Stopping recording...');
161
+ break;
162
+ }
163
+
164
+ if (!prompt.trim()) {
165
+ console.log('āš ļø Please enter a command or "done" to finish.');
166
+ continue;
167
+ }
168
+
169
+ try {
170
+ // Execute the command using the framework's AI agent
171
+ console.log(`\nšŸ¤– Processing: "${prompt}"`);
172
+
173
+ // Use the AI agent to interpret and execute the command
174
+ const result = await framework.runTask(prompt, `Interactive-Step-${Date.now()}`);
175
+
176
+ // Record this step
177
+ await recorder.recordStep(
178
+ prompt,
179
+ 'ai-agent',
180
+ { command: prompt },
181
+ result.result || 'Command executed by AI agent'
182
+ );
183
+
184
+ console.log(`āœ… Step completed: ${result.result || 'Success'}`);
185
+
186
+ } catch (error) {
187
+ console.log(`āŒ Error executing command: ${error.message}`);
188
+
189
+ // Still record the failed attempt
190
+ await recorder.recordStep(
191
+ prompt,
192
+ 'error',
193
+ { error: error.message },
194
+ `Error: ${error.message}`
195
+ );
196
+ }
197
+ }
198
+
199
+ // Stop recording and generate files
200
+ const recordingResult = await recorder.stopRecording();
201
+
202
+ console.log('\nšŸŽ‰ Recording Complete!');
203
+ console.log('═'.repeat(40));
204
+ console.log(`šŸ“ Recording ID: ${recordingResult.recordingId}`);
205
+ console.log(`šŸ“‚ Artifacts: ${recordingResult.recordingPath}`);
206
+ console.log(`🧪 Steps recorded: ${recordingResult.steps}`);
207
+ console.log(`šŸ“ Test file generated in tests/ folder`);
208
+
209
+ } catch (error) {
210
+ console.error(`šŸ’„ Error in interactive recorder: ${error.message}`);
211
+ } finally {
212
+ await framework.cleanup();
213
+ rl.close();
214
+ rl.close();
215
+ }
216
+ }
217
+
218
+ // Run the interactive recorder
219
+ if (import.meta.url === `file://${process.argv[1]}`) {
220
+ runInteractiveRecorder().catch(console.error);
221
+ }
222
+
223
+ export { runInteractiveRecorder, collectTestData };
@@ -0,0 +1,18 @@
1
+ // Endorphin e2e AI test framework>
2
+ // Copyright (C) 2025 Redstudio Agency
3
+
4
+ // This program is free software: you can redistribute it and/or modify
5
+ // it under the terms of the GNU Affero General Public License as
6
+ // published by the Free Software Foundation, either version 3 of the
7
+ // License, or (at your option) any later version.
8
+
9
+ // This program is distributed in the hope that it will be useful,
10
+ // but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ // GNU Affero General Public License for more details.
13
+
14
+ // You should have received a copy of the GNU Affero General Public License
15
+ // along with this program. If not, see <http://www.gnu.org/licenses/>.
16
+
17
+ export { runInteractiveRecorder as EnhancedInteractiveRecorder } from './enhanced-interactive-recorder.js';
18
+ // Note: interactive-test.js is deprecated and shows upgrade notice only
@@ -0,0 +1,33 @@
1
+ // Endorphin e2e AI test framework>
2
+ // Copyright (C) 2025 Redstudio Agency
3
+
4
+ // This program is free software: you can redistribute it and/or modify
5
+ // it under the terms of the GNU Affero General Public License as
6
+ // published by the Free Software Foundation, either version 3 of the
7
+ // License, or (at your option) any later version.
8
+
9
+ // This program is distributed in the hope that it will be useful,
10
+ // but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ // GNU Affero General Public License for more details.
13
+
14
+ // You should have received a copy of the GNU Affero General Public License
15
+ // along with this program. If not, see <http://www.gnu.org/licenses/>.
16
+
17
+ // DEPRECATED: This file has been replaced by enhanced-interactive-recorder.js
18
+ // This file is kept for backward compatibility
19
+
20
+ console.log('\nāš ļø NOTICE: This interactive mode has been upgraded!');
21
+ console.log('═'.repeat(60));
22
+ console.log('šŸŽ¬ Enhanced Interactive Test Recorder is now available');
23
+ console.log('šŸ“ Features: Step-by-step recording, test data collection, and more');
24
+ console.log('');
25
+ console.log('Please use:');
26
+ console.log(' npm run interactive');
27
+ console.log('');
28
+ console.log('Or run directly:');
29
+ console.log(' node framework/interactive/enhanced-interactive-recorder.js');
30
+ console.log('═'.repeat(60));
31
+ console.log('');
32
+
33
+ process.exit(0);
@@ -0,0 +1,33 @@
1
+ // Endorphin e2e AI test framework>
2
+ // Copyright (C) 2025 Redstudio Agency
3
+
4
+ // This program is free software: you can redistribute it and/or modify
5
+ // it under the terms of the GNU Affero General Public License as
6
+ // published by the Free Software Foundation, either version 3 of the
7
+ // License, or (at your option) any later version.
8
+
9
+ // This program is distributed in the hope that it will be useful,
10
+ // but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ // GNU Affero General Public License for more details.
13
+
14
+ // You should have received a copy of the GNU Affero General Public License
15
+ // along with this program. If not, see <http://www.gnu.org/licenses/>.
16
+
17
+ // DEPRECATED: This file has been replaced by enhanced-interactive-recorder.js
18
+ // This file is kept for backward compatibility
19
+
20
+ console.log('\nāš ļø NOTICE: This interactive mode has been upgraded!');
21
+ console.log('═'.repeat(60));
22
+ console.log('šŸŽ¬ Enhanced Interactive Test Recorder is now available');
23
+ console.log('šŸ“ Features: Step-by-step recording, test data collection, and more');
24
+ console.log('');
25
+ console.log('Please use:');
26
+ console.log(' npm run interactive');
27
+ console.log('');
28
+ console.log('Or run directly:');
29
+ console.log(' node framework/interactive/enhanced-interactive-recorder.js');
30
+ console.log('═'.repeat(60));
31
+ console.log('');
32
+
33
+ process.exit(0);
@@ -0,0 +1,29 @@
1
+ // Endorphin e2e AI test framework
2
+ // Copyright (C) 2025 Redstudio Agency
3
+
4
+ // This program is free software: you can redistribute it and/or modify
5
+ // it under the terms of the GNU Affero General Public License as
6
+ // published by the Free Software Foundation, either version 3 of the
7
+ // License, or (at your option) any later version.
8
+
9
+ // This program is distributed in the hope that it will be useful,
10
+ // but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ // GNU Affero General Public License for more details.
13
+
14
+ // You should have received a copy of the GNU Affero General Public License
15
+ // along with this program. If not, see <http://www.gnu.org/licenses/>.
16
+
17
+ import { EnhancedBrowserTestFramework } from './index.js';
18
+
19
+ // Re-export the framework for compatibility
20
+ export { EnhancedBrowserTestFramework };
21
+
22
+ // Export test discovery functions for CLI
23
+ export {
24
+ runSingleTestById,
25
+ runTestsByTag,
26
+ runTestsByPriority,
27
+ runAllTests,
28
+ listAllTests
29
+ } from './core/test-discovery.js';
@@ -0,0 +1,15 @@
1
+ // Endorphin e2e AI test framework>
2
+ // Copyright (C) 2025 Redstudio Agency
3
+
4
+ // This program is free software: you can redistribute it and/or modify
5
+ // it under the terms of the GNU Affero General Public License as
6
+ // published by the Free Software Foundation, either version 3 of the
7
+ // License, or (at your option) any later version.
8
+
9
+ // This program is distributed in the hope that it will be useful,
10
+ // but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ // GNU Affero General Public License for more details.
13
+
14
+ // You should have received a copy of the GNU Affero General Public License
15
+ // along with this program. If not, see <http://www.gnu.org/licenses/>.