testdriverai 7.1.1 → 7.1.3

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.
@@ -423,7 +423,7 @@ export default function testDriverPlugin(options = {}) {
423
423
  options.apiRoot || process.env.TD_API_ROOT || "https://testdriver-api.onrender.com";
424
424
  pluginState.ciProvider = detectCI();
425
425
  pluginState.gitInfo = getGitInfo();
426
-
426
+
427
427
  // Store TestDriver-specific options (excluding plugin-specific ones)
428
428
  const { apiKey, apiRoot, ...testDriverOptions } = options;
429
429
  pluginState.testDriverOptions = testDriverOptions;
@@ -441,7 +441,13 @@ export default function testDriverPlugin(options = {}) {
441
441
  logger.debug("Global TestDriver options:", testDriverOptions);
442
442
  }
443
443
 
444
- return new TestDriverReporter(options);
444
+ // Create reporter instance
445
+ const reporter = new TestDriverReporter(options);
446
+
447
+ // Add name property for Vitest
448
+ reporter.name = 'testdriver';
449
+
450
+ return reporter;
445
451
  }
446
452
 
447
453
  /**
@@ -458,6 +464,10 @@ class TestDriverReporter {
458
464
  this.ctx = ctx;
459
465
  logger.debug("onInit called - UPDATED VERSION");
460
466
 
467
+ // Store project root for making file paths relative
468
+ pluginState.projectRoot = ctx.config.root || process.cwd();
469
+ logger.debug("Project root:", pluginState.projectRoot);
470
+
461
471
  // NOW read the API key and API root (after setupFiles have run, including dotenv/config)
462
472
  pluginState.apiKey = this.options.apiKey || process.env.TD_API_KEY;
463
473
  pluginState.apiRoot = this.options.apiRoot || process.env.TD_API_ROOT || "https://testdriver-api.onrender.com";
@@ -668,11 +678,15 @@ class TestDriverReporter {
668
678
  dashcamUrl = testResult.dashcamUrl || null;
669
679
  const platform = testResult.platform || null;
670
680
  sessionId = testResult.sessionId || null;
671
- testFile =
681
+ const absolutePath =
672
682
  testResult.testFile ||
673
683
  test.file?.filepath ||
674
684
  test.file?.name ||
675
685
  "unknown";
686
+ // Make path relative to project root
687
+ testFile = pluginState.projectRoot && absolutePath !== "unknown"
688
+ ? path.relative(pluginState.projectRoot, absolutePath)
689
+ : absolutePath;
676
690
  testOrder =
677
691
  testResult.testOrder !== undefined ? testResult.testOrder : 0;
678
692
  // Don't override duration from file - use Vitest's result.duration
@@ -696,7 +710,7 @@ class TestDriverReporter {
696
710
  logger.debug(`No result file found for test: ${test.id}`);
697
711
  // Fallback to test object properties - try multiple sources
698
712
  // In Vitest, the file path is on test.module.task.filepath
699
- testFile =
713
+ const absolutePath =
700
714
  test.module?.task?.filepath ||
701
715
  test.module?.file?.filepath ||
702
716
  test.module?.file?.name ||
@@ -706,13 +720,17 @@ class TestDriverReporter {
706
720
  test.suite?.file?.name ||
707
721
  test.location?.file ||
708
722
  "unknown";
723
+ // Make path relative to project root
724
+ testFile = pluginState.projectRoot && absolutePath !== "unknown"
725
+ ? path.relative(pluginState.projectRoot, absolutePath)
726
+ : absolutePath;
709
727
  logger.debug(`Resolved testFile: ${testFile}`);
710
728
  }
711
729
  } catch (error) {
712
730
  logger.error("Failed to read test result file:", error.message);
713
731
  // Fallback to test object properties - try multiple sources
714
732
  // In Vitest, the file path is on test.module.task.filepath
715
- testFile =
733
+ const absolutePath =
716
734
  test.module?.task?.filepath ||
717
735
  test.module?.file?.filepath ||
718
736
  test.module?.file?.name ||
@@ -722,6 +740,10 @@ class TestDriverReporter {
722
740
  test.suite?.file?.name ||
723
741
  test.location?.file ||
724
742
  "unknown";
743
+ // Make path relative to project root
744
+ testFile = pluginState.projectRoot && absolutePath !== "unknown"
745
+ ? path.relative(pluginState.projectRoot, absolutePath)
746
+ : absolutePath;
725
747
  logger.debug(`Resolved testFile from fallback: ${testFile}`);
726
748
  }
727
749
 
@@ -901,8 +923,9 @@ function getGitInfo() {
901
923
  encoding: "utf8",
902
924
  stdio: ["pipe", "pipe", "ignore"]
903
925
  }).trim();
926
+ logger.debug("Git commit from local:", info.commit);
904
927
  } catch (e) {
905
- // Git command failed, ignore
928
+ logger.debug("Failed to get git commit:", e.message);
906
929
  }
907
930
  }
908
931
 
@@ -912,8 +935,9 @@ function getGitInfo() {
912
935
  encoding: "utf8",
913
936
  stdio: ["pipe", "pipe", "ignore"]
914
937
  }).trim();
938
+ logger.debug("Git branch from local:", info.branch);
915
939
  } catch (e) {
916
- // Git command failed, ignore
940
+ logger.debug("Failed to get git branch:", e.message);
917
941
  }
918
942
  }
919
943
 
@@ -923,8 +947,9 @@ function getGitInfo() {
923
947
  encoding: "utf8",
924
948
  stdio: ["pipe", "pipe", "ignore"]
925
949
  }).trim();
950
+ logger.debug("Git author from local:", info.author);
926
951
  } catch (e) {
927
- // Git command failed, ignore
952
+ logger.debug("Failed to get git author:", e.message);
928
953
  }
929
954
  }
930
955
 
@@ -941,12 +966,14 @@ function getGitInfo() {
941
966
  const match = remoteUrl.match(/[:/]([^/:]+\/[^/:]+?)(\.git)?$/);
942
967
  if (match) {
943
968
  info.repo = match[1];
969
+ logger.debug("Git repo from local:", info.repo);
944
970
  }
945
971
  } catch (e) {
946
- // Git command failed, ignore
972
+ logger.debug("Failed to get git repo:", e.message);
947
973
  }
948
974
  }
949
975
 
976
+ logger.info("Collected git info:", info);
950
977
  return info;
951
978
  }
952
979
 
@@ -246,7 +246,11 @@ export function TestDriver(context, options = {}) {
246
246
  if (dashcamUrl) {
247
247
  const testId = context.task.id;
248
248
  const platform = testdriver.os || 'linux';
249
- const testFile = context.task.file?.filepath || context.task.file?.name || 'unknown';
249
+ const absolutePath = context.task.file?.filepath || context.task.file?.name || 'unknown';
250
+ const projectRoot = process.cwd();
251
+ const testFile = absolutePath !== 'unknown'
252
+ ? path.relative(projectRoot, absolutePath)
253
+ : absolutePath;
250
254
 
251
255
  // Create results directory if it doesn't exist
252
256
  const resultsDir = path.join(os.tmpdir(), 'testdriver-results');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "testdriverai",
3
- "version": "7.1.1",
3
+ "version": "7.1.3",
4
4
  "description": "Next generation autonomous AI agent for end-to-end testing of web & desktop",
5
5
  "main": "sdk.js",
6
6
  "exports": {
package/sdk.js CHANGED
@@ -339,12 +339,12 @@ class Element {
339
339
  }
340
340
 
341
341
  // Determine threshold:
342
- // - If cacheKey is provided, enable cache (threshold = 0.05 or custom)
342
+ // - If cacheKey is provided, enable cache (threshold = 0.01 or custom)
343
343
  // - If no cacheKey, disable cache (threshold = -1) unless explicitly overridden
344
344
  let threshold;
345
345
  if (cacheKey) {
346
346
  // cacheKey provided - enable cache with threshold
347
- threshold = cacheThreshold ?? 0.05;
347
+ threshold = cacheThreshold ?? 0.01;
348
348
  } else if (cacheThreshold !== null) {
349
349
  // Explicit threshold provided without cacheKey
350
350
  threshold = cacheThreshold;
@@ -1255,11 +1255,65 @@ class TestDriverSDK {
1255
1255
  console.log('[provision.chrome] ✅ Dashcam started');
1256
1256
  }
1257
1257
 
1258
+ // Set up Chrome profile with preferences
1259
+ const shell = this.os === 'windows' ? 'pwsh' : 'sh';
1260
+ const userDataDir = this.os === 'windows'
1261
+ ? 'C:\\Users\\testdriver\\AppData\\Local\\TestDriver\\Chrome'
1262
+ : '/tmp/testdriver-chrome-profile';
1263
+
1264
+ // Create user data directory and Default profile directory
1265
+ const defaultProfileDir = this.os === 'windows'
1266
+ ? `${userDataDir}\\Default`
1267
+ : `${userDataDir}/Default`;
1268
+
1269
+ const createDirCmd = this.os === 'windows'
1270
+ ? `New-Item -ItemType Directory -Path "${defaultProfileDir}" -Force | Out-Null`
1271
+ : `mkdir -p "${defaultProfileDir}"`;
1272
+
1273
+ await this.exec(shell, createDirCmd, 10000, true);
1274
+
1275
+ // Write Chrome preferences
1276
+ const chromePrefs = {
1277
+ credentials_enable_service: false,
1278
+ profile: {
1279
+ password_manager_enabled: false,
1280
+ default_content_setting_values: {}
1281
+ },
1282
+ signin: {
1283
+ allowed: false
1284
+ },
1285
+ sync: {
1286
+ requested: false,
1287
+ first_setup_complete: true,
1288
+ sync_all_os_types: false
1289
+ },
1290
+ autofill: {
1291
+ enabled: false
1292
+ },
1293
+ local_state: {
1294
+ browser: {
1295
+ has_seen_welcome_page: true
1296
+ }
1297
+ }
1298
+ };
1299
+
1300
+ const prefsPath = this.os === 'windows'
1301
+ ? `${defaultProfileDir}\\Preferences`
1302
+ : `${defaultProfileDir}/Preferences`;
1303
+
1304
+ const prefsJson = JSON.stringify(chromePrefs, null, 2);
1305
+ const writePrefCmd = this.os === 'windows'
1306
+ ? `Set-Content -Path "${prefsPath}" -Value '${prefsJson.replace(/'/g, "''")}'`
1307
+ : `cat > "${prefsPath}" << 'EOF'\n${prefsJson}\nEOF`;
1308
+
1309
+ await this.exec(shell, writePrefCmd, 10000, true);
1310
+ console.log('[provision.chrome] ✅ Chrome preferences configured');
1311
+
1258
1312
  // Build Chrome launch command
1259
1313
  const chromeArgs = [];
1260
1314
  if (maximized) chromeArgs.push('--start-maximized');
1261
1315
  if (guest) chromeArgs.push('--guest');
1262
- chromeArgs.push('--disable-fre', '--no-default-browser-check', '--no-first-run');
1316
+ chromeArgs.push('--disable-fre', '--no-default-browser-check', '--no-first-run', '--disable-infobars', `--user-data-dir=${userDataDir}`);
1263
1317
 
1264
1318
  // Add dashcam-chrome extension on Linux
1265
1319
  if (this.os === 'linux') {
@@ -1267,7 +1321,6 @@ class TestDriverSDK {
1267
1321
  }
1268
1322
 
1269
1323
  // Launch Chrome
1270
- const shell = this.os === 'windows' ? 'pwsh' : 'sh';
1271
1324
 
1272
1325
  if (this.os === 'windows') {
1273
1326
  const argsString = chromeArgs.map(arg => `"${arg}"`).join(', ');
@@ -1665,12 +1718,12 @@ class TestDriverSDK {
1665
1718
  }
1666
1719
 
1667
1720
  // Determine threshold:
1668
- // - If cacheKey is provided, enable cache (threshold = 0.05 or custom)
1721
+ // - If cacheKey is provided, enable cache (threshold = 0.01 or custom)
1669
1722
  // - If no cacheKey, disable cache (threshold = -1) unless explicitly overridden
1670
1723
  let threshold;
1671
1724
  if (cacheKey) {
1672
1725
  // cacheKey provided - enable cache with threshold
1673
- threshold = cacheThreshold ?? 0.05;
1726
+ threshold = cacheThreshold ?? 0.01;
1674
1727
  } else if (cacheThreshold !== null) {
1675
1728
  // Explicit threshold provided without cacheKey
1676
1729
  threshold = cacheThreshold;
@@ -6,7 +6,7 @@
6
6
  import { describe, expect, it } from "vitest";
7
7
  import { TestDriver } from "../../lib/vitest/hooks.mjs";
8
8
 
9
- describe.skipIf(process.env.TD_OS === "linux")("Exec Output Test", () => {
9
+ describe.skip("Exec Output Test", () => {
10
10
  it(
11
11
  "should set date using PowerShell and navigate to calendar",
12
12
  async (context) => {
@@ -6,7 +6,7 @@
6
6
  import { describe, expect, it } from "vitest";
7
7
  import { TestDriver } from "../../lib/vitest/hooks.mjs";
8
8
 
9
- describe.skipIf(process.env.TD_OS === "linux")("Exec PowerShell Test", () => {
9
+ describe.skip("Exec PowerShell Test", () => {
10
10
  it(
11
11
  "should generate random email using PowerShell and enter it",
12
12
  async (context) => {
@@ -7,7 +7,7 @@ import { describe, expect, it } from "vitest";
7
7
  import { TestDriver } from "../../lib/vitest/hooks.mjs";
8
8
 
9
9
  describe("Focus Window Test", () => {
10
- it.skipIf(process.env.TD_OS === "linux")(
10
+ it.skip(
11
11
  "should click Microsoft Edge icon and focus Google Chrome",
12
12
  async (context) => {
13
13
  const testdriver = TestDriver(context, { headless: true });
@@ -9,7 +9,7 @@ import { performLogin } from "./setup/testHelpers.mjs";
9
9
 
10
10
  describe("Hover Image Test", () => {
11
11
  it("should click on shopping cart icon and verify empty cart", async (context) => {
12
- const testdriver = TestDriver(context, { headless: true });
12
+ const testdriver = TestDriver(context, { headless: false });
13
13
 
14
14
  // provision.chrome() automatically calls ready() and starts dashcam
15
15
  await testdriver.provision.chrome({
@@ -14,7 +14,7 @@ const __filename = fileURLToPath(import.meta.url);
14
14
  const __dirname = dirname(__filename);
15
15
 
16
16
  describe("Match Image Test", () => {
17
- it("should match shopping cart image and verify empty cart", async (context) => {
17
+ it.skip("should match shopping cart image and verify empty cart", async (context) => {
18
18
  const testdriver = TestDriver(context, { headless: true });
19
19
  await testdriver.provision.chrome({ url: 'http://testdriver-sandbox.vercel.app/login' });
20
20
 
@@ -27,7 +27,7 @@ describe("Scroll Keyboard Test", () => {
27
27
  "The Hamster Dance, large heading at top of page",
28
28
  );
29
29
  await heading.click();
30
- await testdriver.scroll("down", 1000);
30
+ await testdriver.scroll("down", { amount: 1000 });
31
31
 
32
32
  // Assert the page is scrolled down
33
33
  const result = await testdriver.assert(
@@ -7,7 +7,7 @@ import { describe, expect, it } from "vitest";
7
7
  import { TestDriver } from "../../lib/vitest/hooks.mjs";
8
8
 
9
9
  describe("Scroll Until Image Test", () => {
10
- it("should scroll until brown colored house image appears", async (context) => {
10
+ it.skip("should scroll until brown colored house image appears", async (context) => {
11
11
  const testdriver = TestDriver(context, { headless: true });
12
12
  await testdriver.provision.chrome({ url: 'http://testdriver-sandbox.vercel.app/login' });
13
13
 
@@ -18,7 +18,24 @@ describe("Scroll Until Text Test", () => {
18
18
 
19
19
  // Scroll until text appears
20
20
  await testdriver.focusApplication("Google Chrome");
21
- await testdriver.scrollUntilText({ text: "testdriver socks", direction: "down" });
21
+ // Scroll until text appears
22
+ let found = false;
23
+ let scrollCount = 0;
24
+ const maxScrolls = 10;
25
+
26
+ while (!found && scrollCount < maxScrolls) {
27
+ const findResult = await testdriver.find("testdriver socks");
28
+ if (findResult) {
29
+ found = true;
30
+ } else {
31
+ await testdriver.scroll({ direction: "down" });
32
+ scrollCount++;
33
+ }
34
+ }
35
+
36
+ if (!found) {
37
+ throw new Error(`Failed to find "testdriver socks" after ${maxScrolls} scrolls`);
38
+ }
22
39
 
23
40
  // Assert testdriver socks appears on screen
24
41
  await testdriver.focusApplication("Google Chrome");
@@ -32,7 +32,7 @@ describe("Scroll Test", () => {
32
32
  await heading.click();
33
33
 
34
34
  // Scroll down
35
- await testdriver.scroll("down", 1000);
35
+ await testdriver.scroll("down", { amount: 1000 });
36
36
 
37
37
  // Assert page is scrolled
38
38
  const result = await testdriver.assert("the page is scrolled down, the hamster dance heading is not visible on the page");
@@ -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
@@ -8,8 +8,8 @@ config();
8
8
 
9
9
  export default defineConfig({
10
10
  test: {
11
- testTimeout: 120000,
12
- hookTimeout: 120000,
11
+ testTimeout: 300000,
12
+ hookTimeout: 300000,
13
13
  reporters: [
14
14
  'default',
15
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
- });