testdriverai 7.1.2 → 7.1.4

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 (38) hide show
  1. package/.github/workflows/test-init.yml +145 -0
  2. package/agent/lib/commander.js +2 -2
  3. package/agent/lib/commands.js +10 -5
  4. package/docs/docs.json +29 -84
  5. package/docs/v7/_drafts/migration.mdx +3 -3
  6. package/docs/v7/api/act.mdx +1 -1
  7. package/docs/v7/api/assert.mdx +1 -1
  8. package/docs/v7/api/assertions.mdx +14 -14
  9. package/docs/v7/getting-started/quickstart.mdx +11 -9
  10. package/docs/v7/getting-started/running-and-debugging.mdx +3 -2
  11. package/docs/v7/getting-started/writing-tests.mdx +4 -5
  12. package/docs/v7/overview/readme.mdx +1 -1
  13. package/docs/v7/presets/chrome.mdx +38 -41
  14. package/docs/v7/presets/electron.mdx +107 -100
  15. package/docs/v7/presets/webapp.mdx +40 -43
  16. package/interfaces/cli/commands/init.js +79 -21
  17. package/interfaces/vitest-plugin.mjs +36 -9
  18. package/lib/vitest/hooks.mjs +5 -1
  19. package/manual/test-init-command.js +223 -0
  20. package/package.json +2 -2
  21. package/schema.json +5 -5
  22. package/sdk-log-formatter.js +1 -1
  23. package/sdk.d.ts +8 -8
  24. package/sdk.js +64 -14
  25. package/test/testdriver/exec-output.test.mjs +1 -1
  26. package/test/testdriver/exec-pwsh.test.mjs +1 -1
  27. package/test/testdriver/focus-window.test.mjs +1 -1
  28. package/test/testdriver/hover-image.test.mjs +1 -1
  29. package/test/testdriver/hover-text-with-description.test.mjs +0 -3
  30. package/test/testdriver/match-image.test.mjs +1 -1
  31. package/test/testdriver/scroll-keyboard.test.mjs +1 -1
  32. package/test/testdriver/scroll-until-image.test.mjs +1 -1
  33. package/test/testdriver/scroll-until-text.test.mjs +18 -1
  34. package/test/testdriver/scroll.test.mjs +1 -1
  35. package/test/testdriver/setup/lifecycleHelpers.mjs +105 -5
  36. package/test/testdriver/setup/testHelpers.mjs +6 -2
  37. package/vitest.config.mjs +7 -2
  38. package/test/testdriver/exec-js.test.mjs +0 -43
@@ -123,7 +123,7 @@ export async function launchChrome(
123
123
  }
124
124
 
125
125
  /**
126
- * Launch Chrome for Testing browser with guest mode
126
+ * Launch Chrome for Testing browser with custom profile
127
127
  * @param {TestDriver} client - TestDriver client
128
128
  * @param {string} url - URL to open (default: https://testdriver-sandbox.vercel.app/)
129
129
  */
@@ -132,19 +132,69 @@ export async function launchChromeForTesting(
132
132
  url = "http://testdriver-sandbox.vercel.app/",
133
133
  ) {
134
134
  const shell = client.os === "windows" ? "pwsh" : "sh";
135
+ const userDataDir = client.os === "windows"
136
+ ? "C:\\Users\\testdriver\\AppData\\Local\\TestDriver\\Chrome"
137
+ : "/tmp/testdriver-chrome-profile";
138
+
139
+ // Create user data directory and Default profile directory
140
+ const defaultProfileDir = client.os === "windows"
141
+ ? `${userDataDir}\\Default`
142
+ : `${userDataDir}/Default`;
143
+
144
+ const createDirCmd = client.os === "windows"
145
+ ? `New-Item -ItemType Directory -Path "${defaultProfileDir}" -Force | Out-Null`
146
+ : `mkdir -p "${defaultProfileDir}"`;
147
+
148
+ await client.exec(shell, createDirCmd, 10000, true);
149
+
150
+ // Write Chrome preferences
151
+ const chromePrefs = {
152
+ credentials_enable_service: false,
153
+ profile: {
154
+ password_manager_enabled: false,
155
+ default_content_setting_values: {}
156
+ },
157
+ signin: {
158
+ allowed: false
159
+ },
160
+ sync: {
161
+ requested: false,
162
+ first_setup_complete: true,
163
+ sync_all_os_types: false
164
+ },
165
+ autofill: {
166
+ enabled: false
167
+ },
168
+ local_state: {
169
+ browser: {
170
+ has_seen_welcome_page: true
171
+ }
172
+ }
173
+ };
174
+
175
+ const prefsPath = client.os === "windows"
176
+ ? `${defaultProfileDir}\\Preferences`
177
+ : `${defaultProfileDir}/Preferences`;
178
+
179
+ const prefsJson = JSON.stringify(chromePrefs, null, 2);
180
+ const writePrefCmd = client.os === "windows"
181
+ ? `Set-Content -Path "${prefsPath}" -Value '${prefsJson.replace(/'/g, "''")}'`
182
+ : `cat > "${prefsPath}" << 'EOF'\n${prefsJson}\nEOF`;
183
+
184
+ await client.exec(shell, writePrefCmd, 10000, true);
135
185
 
136
186
  if (client.os === "windows") {
137
187
  // Windows Chrome for Testing path would need to be determined
138
188
  // For now, fallback to regular Chrome on Windows
139
189
  await client.exec(
140
190
  "pwsh",
141
- `Start-Process "C:/Program Files/Google/Chrome/Application/chrome.exe" -ArgumentList "--start-maximized", "--guest", "${url}"`,
191
+ `Start-Process "C:/Program Files/Google/Chrome/Application/chrome.exe" -ArgumentList "--start-maximized", "--user-data-dir=${userDataDir}", "--disable-fre", "--no-default-browser-check", "--no-first-run", "${url}"`,
142
192
  30000,
143
193
  );
144
194
  } else {
145
195
  await client.exec(
146
196
  shell,
147
- `chrome-for-testing --start-maximized --disable-fre --no-default-browser-check --no-first-run --guest "${url}" >/dev/null 2>&1 &`,
197
+ `chrome-for-testing --start-maximized --disable-fre --no-default-browser-check --no-first-run --user-data-dir=${userDataDir} "${url}" >/dev/null 2>&1 &`,
148
198
  30000,
149
199
  );
150
200
  }
@@ -168,19 +218,69 @@ export async function launchChromeExtension(
168
218
  url = "http://testdriver-sandbox.vercel.app/",
169
219
  ) {
170
220
  const shell = client.os === "windows" ? "pwsh" : "sh";
221
+ const userDataDir = client.os === "windows"
222
+ ? "C:\\Users\\testdriver\\AppData\\Local\\TestDriver\\Chrome"
223
+ : "/tmp/testdriver-chrome-profile";
224
+
225
+ // Create user data directory and Default profile directory
226
+ const defaultProfileDir = client.os === "windows"
227
+ ? `${userDataDir}\\Default`
228
+ : `${userDataDir}/Default`;
229
+
230
+ const createDirCmd = client.os === "windows"
231
+ ? `New-Item -ItemType Directory -Path "${defaultProfileDir}" -Force | Out-Null`
232
+ : `mkdir -p "${defaultProfileDir}"`;
233
+
234
+ await client.exec(shell, createDirCmd, 10000, true);
235
+
236
+ // Write Chrome preferences
237
+ const chromePrefs = {
238
+ credentials_enable_service: false,
239
+ profile: {
240
+ password_manager_enabled: false,
241
+ default_content_setting_values: {}
242
+ },
243
+ signin: {
244
+ allowed: false
245
+ },
246
+ sync: {
247
+ requested: false,
248
+ first_setup_complete: true,
249
+ sync_all_os_types: false
250
+ },
251
+ autofill: {
252
+ enabled: false
253
+ },
254
+ local_state: {
255
+ browser: {
256
+ has_seen_welcome_page: true
257
+ }
258
+ }
259
+ };
260
+
261
+ const prefsPath = client.os === "windows"
262
+ ? `${defaultProfileDir}\\Preferences`
263
+ : `${defaultProfileDir}/Preferences`;
264
+
265
+ const prefsJson = JSON.stringify(chromePrefs, null, 2);
266
+ const writePrefCmd = client.os === "windows"
267
+ ? `Set-Content -Path "${prefsPath}" -Value '${prefsJson.replace(/'/g, "''")}'`
268
+ : `cat > "${prefsPath}" << 'EOF'\n${prefsJson}\nEOF`;
269
+
270
+ await client.exec(shell, writePrefCmd, 10000, true);
171
271
 
172
272
  if (client.os === "windows") {
173
273
  // Windows Chrome for Testing path would need to be determined
174
274
  // For now, fallback to regular Chrome on Windows
175
275
  await client.exec(
176
276
  "pwsh",
177
- `Start-Process "C:/Program Files/Google/Chrome/Application/chrome.exe" -ArgumentList "--start-maximized", "--load-extension=${extensionId}", "${url}"`,
277
+ `Start-Process "C:/Program Files/Google/Chrome/Application/chrome.exe" -ArgumentList "--start-maximized", "--user-data-dir=${userDataDir}", "--load-extension=${extensionId}", "${url}"`,
178
278
  30000,
179
279
  );
180
280
  } else {
181
281
  await client.exec(
182
282
  shell,
183
- `chrome-for-testing --start-maximized --disable-fre --no-default-browser-check --no-first-run --load-extension=${extensionId} "${url}" >/dev/null 2>&1 &`,
283
+ `chrome-for-testing --start-maximized --disable-fre --no-default-browser-check --no-first-run --user-data-dir=${userDataDir} --load-extension=${extensionId} "${url}" >/dev/null 2>&1 &`,
184
284
  30000,
185
285
  );
186
286
  }
@@ -511,9 +511,13 @@ export async function teardownTest(client, options = {}) {
511
511
  fs.mkdirSync(dir, { recursive: true });
512
512
  }
513
513
 
514
- // Get test file path
515
- const testFile =
514
+ // Get test file path - make it relative to project root
515
+ const absolutePath =
516
516
  options.task.file?.filepath || options.task.file?.name || "unknown";
517
+ const projectRoot = process.cwd();
518
+ const testFile = absolutePath !== "unknown"
519
+ ? path.relative(projectRoot, absolutePath)
520
+ : absolutePath;
517
521
 
518
522
  // Calculate test order (index within parent suite)
519
523
  let testOrder = 0;
package/vitest.config.mjs CHANGED
@@ -1,10 +1,15 @@
1
+ import { config } from 'dotenv';
1
2
  import TestDriver from 'testdriverai/vitest';
2
3
  import { defineConfig } from 'vitest/config';
3
4
 
5
+ // Load .env file early so it's available to the reporter (runs in main process)
6
+ // and to worker processes
7
+ config();
8
+
4
9
  export default defineConfig({
5
10
  test: {
6
- testTimeout: 120000,
7
- hookTimeout: 120000,
11
+ testTimeout: 300000,
12
+ hookTimeout: 300000,
8
13
  reporters: [
9
14
  'default',
10
15
  // Don't pass apiKey/apiRoot here - they'll be read from env at runtime
@@ -1,43 +0,0 @@
1
- /**
2
- * TestDriver SDK - Exec JS Test (Vitest)
3
- * Converted from: testdriver/acceptance/exec-js.yaml
4
- */
5
-
6
- import { describe, expect, it } from "vitest";
7
- import { TestDriver } from "../../lib/vitest/hooks.mjs";
8
-
9
- describe("Exec JavaScript Test", () => {
10
- it("should fetch user data from API and enter email", async (context) => {
11
- const testdriver = TestDriver(context, { headless: true });
12
- await testdriver.provision.chrome({ url: 'http://testdriver-sandbox.vercel.app/login' });
13
-
14
- //
15
- // Execute JavaScript to fetch user data
16
- const userEmail = await testdriver.exec(
17
- "js",
18
- `
19
- const response = await fetch('https://jsonplaceholder.typicode.com/users');
20
- const user = await response.json();
21
- console.log('user', user[0]);
22
- result = user[0].email;
23
- `,
24
- 10000,
25
- );
26
-
27
- expect(userEmail).toBeTruthy();
28
- expect(userEmail).toContain("@");
29
-
30
- // Enter email in username field
31
- const usernameField = await testdriver.find(
32
- "Username, input field for username",
33
- );
34
- await usernameField.click();
35
- await testdriver.type(userEmail);
36
-
37
- // Assert email is in the field
38
- const result = await testdriver.assert(
39
- 'the username field contains "Sincere@april.biz" which is a valid email address',
40
- );
41
- expect(result).toBeTruthy();
42
- });
43
- });