testdriverai 7.1.3 โ†’ 7.2.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 (78) hide show
  1. package/.github/workflows/acceptance.yaml +81 -0
  2. package/.github/workflows/publish.yaml +44 -0
  3. package/.github/workflows/test-init.yml +145 -0
  4. package/agent/index.js +18 -19
  5. package/agent/lib/commander.js +2 -2
  6. package/agent/lib/commands.js +324 -124
  7. package/agent/lib/redraw.js +99 -39
  8. package/agent/lib/sandbox.js +98 -6
  9. package/agent/lib/sdk.js +25 -0
  10. package/agent/lib/system.js +2 -1
  11. package/agent/lib/validation.js +6 -6
  12. package/docs/docs.json +211 -101
  13. package/docs/snippets/tests/type-repeated-replay.mdx +1 -1
  14. package/docs/v7/_drafts/caching-selectors.mdx +24 -0
  15. package/docs/v7/_drafts/migration.mdx +3 -3
  16. package/docs/v7/api/act.mdx +2 -2
  17. package/docs/v7/api/assert.mdx +2 -2
  18. package/docs/v7/api/assertions.mdx +21 -21
  19. package/docs/v7/api/elements.mdx +78 -0
  20. package/docs/v7/api/find.mdx +38 -0
  21. package/docs/v7/api/focusApplication.mdx +2 -2
  22. package/docs/v7/api/hover.mdx +2 -2
  23. package/docs/v7/features/ai-native.mdx +57 -71
  24. package/docs/v7/features/application-logs.mdx +353 -0
  25. package/docs/v7/features/browser-logs.mdx +414 -0
  26. package/docs/v7/features/cache-management.mdx +402 -0
  27. package/docs/v7/features/continuous-testing.mdx +346 -0
  28. package/docs/v7/features/coverage.mdx +508 -0
  29. package/docs/v7/features/data-driven-testing.mdx +441 -0
  30. package/docs/v7/features/easy-to-write.mdx +2 -73
  31. package/docs/v7/features/enterprise.mdx +155 -39
  32. package/docs/v7/features/fast.mdx +63 -81
  33. package/docs/v7/features/managed-sandboxes.mdx +384 -0
  34. package/docs/v7/features/network-monitoring.mdx +568 -0
  35. package/docs/v7/features/observable.mdx +3 -22
  36. package/docs/v7/features/parallel-execution.mdx +381 -0
  37. package/docs/v7/features/powerful.mdx +1 -1
  38. package/docs/v7/features/reports.mdx +414 -0
  39. package/docs/v7/features/sandbox-customization.mdx +229 -0
  40. package/docs/v7/features/scalable.mdx +217 -2
  41. package/docs/v7/features/stable.mdx +106 -147
  42. package/docs/v7/features/system-performance.mdx +616 -0
  43. package/docs/v7/features/test-analytics.mdx +373 -0
  44. package/docs/v7/features/test-cases.mdx +393 -0
  45. package/docs/v7/features/test-replays.mdx +408 -0
  46. package/docs/v7/features/test-reports.mdx +308 -0
  47. package/docs/v7/getting-started/{running-and-debugging.mdx โ†’ debugging-tests.mdx} +12 -142
  48. package/docs/v7/getting-started/quickstart.mdx +22 -305
  49. package/docs/v7/getting-started/running-tests.mdx +173 -0
  50. package/docs/v7/overview/readme.mdx +1 -1
  51. package/docs/v7/overview/what-is-testdriver.mdx +2 -14
  52. package/docs/v7/presets/chrome-extension.mdx +147 -122
  53. package/interfaces/cli/commands/init.js +78 -20
  54. package/interfaces/cli/lib/base.js +3 -2
  55. package/interfaces/logger.js +0 -2
  56. package/interfaces/shared-test-state.mjs +0 -5
  57. package/interfaces/vitest-plugin.mjs +69 -42
  58. package/lib/core/Dashcam.js +65 -66
  59. package/lib/vitest/hooks.mjs +42 -50
  60. package/manual/test-init-command.js +223 -0
  61. package/package.json +2 -2
  62. package/schema.json +5 -5
  63. package/sdk-log-formatter.js +351 -176
  64. package/sdk.d.ts +8 -8
  65. package/sdk.js +436 -121
  66. package/setup/aws/cloudformation.yaml +2 -2
  67. package/setup/aws/self-hosted.yml +1 -1
  68. package/test/testdriver/chrome-extension.test.mjs +55 -72
  69. package/test/testdriver/element-not-found.test.mjs +2 -1
  70. package/test/testdriver/hover-image.test.mjs +1 -1
  71. package/test/testdriver/hover-text-with-description.test.mjs +0 -3
  72. package/test/testdriver/scroll-until-text.test.mjs +10 -6
  73. package/test/testdriver/setup/lifecycleHelpers.mjs +19 -24
  74. package/test/testdriver/setup/testHelpers.mjs +18 -23
  75. package/vitest.config.mjs +3 -3
  76. package/.github/workflows/linux-tests.yml +0 -28
  77. package/docs/v7/getting-started/generating-tests.mdx +0 -525
  78. package/test/testdriver/auto-cache-key-demo.test.mjs +0 -56
@@ -0,0 +1,223 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Test Init Command
5
+ *
6
+ * This script tests the `testdriverai init` command by:
7
+ * 1. Creating a temporary test project
8
+ * 2. Running the init command
9
+ * 3. Verifying all files were created correctly
10
+ * 4. Running the generated test
11
+ * 5. Cleaning up
12
+ *
13
+ * Usage:
14
+ * node manual/test-init-command.js
15
+ *
16
+ * Requirements:
17
+ * - TD_API_KEY environment variable must be set
18
+ */
19
+
20
+ const fs = require('fs');
21
+ const path = require('path');
22
+ const { execSync } = require('child_process');
23
+ const os = require('os');
24
+
25
+ // Colors for terminal output
26
+ const colors = {
27
+ reset: '\x1b[0m',
28
+ green: '\x1b[32m',
29
+ red: '\x1b[31m',
30
+ cyan: '\x1b[36m',
31
+ yellow: '\x1b[33m',
32
+ gray: '\x1b[90m',
33
+ };
34
+
35
+ function log(message, color = 'reset') {
36
+ console.log(`${colors[color]}${message}${colors.reset}`);
37
+ }
38
+
39
+ function success(message) {
40
+ log(`โœ“ ${message}`, 'green');
41
+ }
42
+
43
+ function error(message) {
44
+ log(`โœ— ${message}`, 'red');
45
+ }
46
+
47
+ function info(message) {
48
+ log(message, 'cyan');
49
+ }
50
+
51
+ function step(message) {
52
+ log(`\n${message}`, 'cyan');
53
+ }
54
+
55
+ // Main test function
56
+ async function testInitCommand() {
57
+ // Check for API key
58
+ if (!process.env.TD_API_KEY) {
59
+ error('TD_API_KEY environment variable is required');
60
+ process.exit(1);
61
+ }
62
+
63
+ const testDir = path.join(os.tmpdir(), `test-init-${Date.now()}`);
64
+ const cliPath = path.join(__dirname, '..');
65
+
66
+ try {
67
+ step('๐Ÿ“ฆ Creating test directory...');
68
+ fs.mkdirSync(testDir, { recursive: true });
69
+ success(`Created: ${testDir}`);
70
+
71
+ step('๐Ÿ”ง Setting up .env file...');
72
+ const envContent = `TD_API_KEY=${process.env.TD_API_KEY}\n`;
73
+ fs.writeFileSync(path.join(testDir, '.env'), envContent);
74
+ success('Created .env with API key');
75
+
76
+ step('๐Ÿš€ Running init command...');
77
+ try {
78
+ execSync(`node ${path.join(cliPath, 'bin/testdriverai.js')} init`, {
79
+ cwd: testDir,
80
+ stdio: 'inherit',
81
+ env: { ...process.env, TD_API_KEY: process.env.TD_API_KEY }
82
+ });
83
+ success('Init command completed');
84
+ } catch (err) {
85
+ error('Init command failed');
86
+ throw err;
87
+ }
88
+
89
+ step('๐Ÿ” Verifying project structure...');
90
+
91
+ const expectedFiles = [
92
+ 'package.json',
93
+ 'vitest.config.js',
94
+ 'tests/example.test.js',
95
+ 'tests/login.js',
96
+ '.env',
97
+ '.gitignore',
98
+ '.github/workflows/testdriver.yml'
99
+ ];
100
+
101
+ for (const file of expectedFiles) {
102
+ const filePath = path.join(testDir, file);
103
+ if (!fs.existsSync(filePath)) {
104
+ error(`Missing file: ${file}`);
105
+ throw new Error(`Expected file not found: ${file}`);
106
+ }
107
+ success(`Found: ${file}`);
108
+ }
109
+
110
+ step('๐Ÿ“ Verifying vitest.config.js contents...');
111
+ const vitestConfig = fs.readFileSync(path.join(testDir, 'vitest.config.js'), 'utf8');
112
+
113
+ if (!vitestConfig.includes('TestDriver()')) {
114
+ error('TestDriver reporter not found in vitest.config.js');
115
+ console.log(vitestConfig);
116
+ throw new Error('TestDriver reporter not configured');
117
+ }
118
+ success('TestDriver reporter is configured');
119
+
120
+ if (!vitestConfig.includes('setupFiles') || !vitestConfig.includes('testdriverai/vitest/setup')) {
121
+ error('setupFiles not configured correctly');
122
+ console.log(vitestConfig);
123
+ throw new Error('setupFiles not configured');
124
+ }
125
+ success('setupFiles is configured correctly');
126
+
127
+ if (!vitestConfig.includes('reporters')) {
128
+ error('reporters array not found');
129
+ console.log(vitestConfig);
130
+ throw new Error('reporters not configured');
131
+ }
132
+ success('reporters array includes TestDriver');
133
+
134
+ step('๐Ÿ“ Verifying example test contents...');
135
+ const testFile = fs.readFileSync(path.join(testDir, 'tests/example.test.js'), 'utf8');
136
+
137
+ if (!testFile.includes('.provision.chrome')) {
138
+ error('Test does not use .provision.chrome');
139
+ console.log(testFile);
140
+ throw new Error('Test does not use .provision pattern');
141
+ }
142
+ success('Test uses .provision.chrome');
143
+
144
+ if (!testFile.includes("from 'testdriverai/vitest/hooks'")) {
145
+ error('Test does not import from testdriverai/vitest/hooks');
146
+ console.log(testFile);
147
+ throw new Error('Test does not import TestDriver from vitest/hooks');
148
+ }
149
+ success('Test imports TestDriver from vitest/hooks');
150
+
151
+ if (!testFile.includes("from './login.js'")) {
152
+ error('Test does not import login from ./login.js');
153
+ console.log(testFile);
154
+ throw new Error('Test does not import login snippet');
155
+ }
156
+ success('Test imports login snippet');
157
+
158
+ step('๐Ÿ“ Verifying login snippet contents...');
159
+ const loginFile = fs.readFileSync(path.join(testDir, 'tests/login.js'), 'utf8');
160
+
161
+ if (!loginFile.includes('.extract(')) {
162
+ error('Login snippet does not use .extract()');
163
+ console.log(loginFile);
164
+ throw new Error('Login snippet does not demonstrate .extract()');
165
+ }
166
+ success('Login snippet demonstrates .extract()');
167
+
168
+ if (!loginFile.includes('secret: true')) {
169
+ error('Login snippet does not use secret option');
170
+ console.log(loginFile);
171
+ throw new Error('Login snippet does not demonstrate secret typing');
172
+ }
173
+ success('Login snippet demonstrates secret typing');
174
+
175
+ step('๐Ÿงช Running generated test...');
176
+ try {
177
+ execSync('npm test', {
178
+ cwd: testDir,
179
+ stdio: 'inherit',
180
+ env: { ...process.env, TD_API_KEY: process.env.TD_API_KEY }
181
+ });
182
+ success('Test execution completed successfully');
183
+ } catch (err) {
184
+ error('Test execution failed');
185
+ throw err;
186
+ }
187
+
188
+ step('โœ… All checks passed!');
189
+ log('\nTest summary:', 'green');
190
+ log(' โ€ข Init command executed successfully', 'green');
191
+ log(' โ€ข All expected files created', 'green');
192
+ log(' โ€ข Configuration files are correct', 'green');
193
+ log(' โ€ข Example test has proper patterns', 'green');
194
+ log(' โ€ข Generated test runs successfully', 'green');
195
+
196
+ } catch (err) {
197
+ step('โŒ Test failed!');
198
+ error(err.message);
199
+ if (err.stack) {
200
+ log(err.stack, 'gray');
201
+ }
202
+ process.exit(1);
203
+ } finally {
204
+ // Optional: Clean up test directory
205
+ // Commented out so you can inspect the generated files
206
+ // step('๐Ÿงน Cleaning up...');
207
+ // if (fs.existsSync(testDir)) {
208
+ // fs.rmSync(testDir, { recursive: true, force: true });
209
+ // success('Cleaned up test directory');
210
+ // }
211
+
212
+ info(`\nTest project preserved at: ${testDir}`);
213
+ info('To clean up manually, run:');
214
+ log(` rm -rf ${testDir}`, 'gray');
215
+ }
216
+ }
217
+
218
+ // Run the test
219
+ testInitCommand().catch(err => {
220
+ error('Unexpected error:');
221
+ console.error(err);
222
+ process.exit(1);
223
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "testdriverai",
3
- "version": "7.1.3",
3
+ "version": "7.2.0",
4
4
  "description": "Next generation autonomous AI agent for end-to-end testing of web & desktop",
5
5
  "main": "sdk.js",
6
6
  "exports": {
@@ -85,7 +85,7 @@
85
85
  },
86
86
  "devDependencies": {
87
87
  "@eslint/js": "^9.10.0",
88
- "@vitest/ui": "^4.0.8",
88
+ "@vitest/ui": "^4.0.15",
89
89
  "chai": "^5.1.2",
90
90
  "esbuild": "0.20.2",
91
91
  "esbuild-plugin-fileloc": "^0.0.6",
package/schema.json CHANGED
@@ -618,7 +618,7 @@
618
618
  }
619
619
  }
620
620
  },
621
- "remember": {
621
+ "extract": {
622
622
  "type": "object",
623
623
  "required": [
624
624
  "description",
@@ -628,7 +628,7 @@
628
628
  "properties": {
629
629
  "command": {
630
630
  "type": "string",
631
- "const": "remember"
631
+ "const": "extract"
632
632
  },
633
633
  "description": {
634
634
  "type": "string"
@@ -783,7 +783,7 @@
783
783
  "scroll-until-text",
784
784
  "scroll-until-image",
785
785
  "focus-application",
786
- "remember",
786
+ "extract",
787
787
  "assert",
788
788
  "exec",
789
789
  "if",
@@ -971,12 +971,12 @@
971
971
  "if": {
972
972
  "properties": {
973
973
  "command": {
974
- "const": "remember"
974
+ "const": "extract"
975
975
  }
976
976
  }
977
977
  },
978
978
  "then": {
979
- "$ref": "#/$defs/commandsAvailable/remember"
979
+ "$ref": "#/$defs/commandsAvailable/extract"
980
980
  }
981
981
  },
982
982
  {