testdriverai 7.1.4 → 7.2.2

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 (72) hide show
  1. package/.github/workflows/acceptance.yaml +81 -0
  2. package/.github/workflows/publish.yaml +44 -0
  3. package/agent/index.js +18 -19
  4. package/agent/interface.js +4 -0
  5. package/agent/lib/commands.js +321 -121
  6. package/agent/lib/redraw.js +99 -39
  7. package/agent/lib/sandbox.js +98 -6
  8. package/agent/lib/sdk.js +25 -0
  9. package/agent/lib/system.js +2 -1
  10. package/agent/lib/validation.js +6 -6
  11. package/docs/docs.json +211 -101
  12. package/docs/snippets/tests/type-repeated-replay.mdx +1 -1
  13. package/docs/v7/_drafts/caching-selectors.mdx +24 -0
  14. package/docs/v7/api/act.mdx +1 -1
  15. package/docs/v7/api/assert.mdx +1 -1
  16. package/docs/v7/api/assertions.mdx +7 -7
  17. package/docs/v7/api/elements.mdx +78 -0
  18. package/docs/v7/api/find.mdx +38 -0
  19. package/docs/v7/api/focusApplication.mdx +2 -2
  20. package/docs/v7/api/hover.mdx +2 -2
  21. package/docs/v7/features/ai-native.mdx +57 -71
  22. package/docs/v7/features/application-logs.mdx +353 -0
  23. package/docs/v7/features/browser-logs.mdx +414 -0
  24. package/docs/v7/features/cache-management.mdx +402 -0
  25. package/docs/v7/features/continuous-testing.mdx +346 -0
  26. package/docs/v7/features/coverage.mdx +508 -0
  27. package/docs/v7/features/data-driven-testing.mdx +441 -0
  28. package/docs/v7/features/easy-to-write.mdx +2 -73
  29. package/docs/v7/features/enterprise.mdx +155 -39
  30. package/docs/v7/features/fast.mdx +63 -81
  31. package/docs/v7/features/managed-sandboxes.mdx +384 -0
  32. package/docs/v7/features/network-monitoring.mdx +568 -0
  33. package/docs/v7/features/observable.mdx +3 -22
  34. package/docs/v7/features/parallel-execution.mdx +381 -0
  35. package/docs/v7/features/powerful.mdx +1 -1
  36. package/docs/v7/features/reports.mdx +414 -0
  37. package/docs/v7/features/sandbox-customization.mdx +229 -0
  38. package/docs/v7/features/scalable.mdx +217 -2
  39. package/docs/v7/features/stable.mdx +106 -147
  40. package/docs/v7/features/system-performance.mdx +616 -0
  41. package/docs/v7/features/test-analytics.mdx +373 -0
  42. package/docs/v7/features/test-cases.mdx +393 -0
  43. package/docs/v7/features/test-replays.mdx +408 -0
  44. package/docs/v7/features/test-reports.mdx +308 -0
  45. package/docs/v7/getting-started/{running-and-debugging.mdx → debugging-tests.mdx} +12 -142
  46. package/docs/v7/getting-started/quickstart.mdx +22 -305
  47. package/docs/v7/getting-started/running-tests.mdx +173 -0
  48. package/docs/v7/overview/what-is-testdriver.mdx +2 -14
  49. package/docs/v7/presets/chrome-extension.mdx +147 -122
  50. package/interfaces/cli/commands/init.js +3 -3
  51. package/interfaces/cli/lib/base.js +3 -2
  52. package/interfaces/logger.js +0 -2
  53. package/interfaces/shared-test-state.mjs +0 -5
  54. package/interfaces/vitest-plugin.mjs +70 -50
  55. package/lib/core/Dashcam.js +60 -85
  56. package/lib/vitest/hooks.mjs +42 -50
  57. package/package.json +1 -1
  58. package/sdk-log-formatter.js +350 -175
  59. package/sdk.d.ts +36 -3
  60. package/sdk.js +431 -116
  61. package/setup/aws/cloudformation.yaml +2 -2
  62. package/setup/aws/self-hosted.yml +1 -1
  63. package/test/testdriver/chrome-extension.test.mjs +55 -72
  64. package/test/testdriver/element-not-found.test.mjs +2 -1
  65. package/test/testdriver/hover-image.test.mjs +1 -1
  66. package/test/testdriver/scroll-until-text.test.mjs +10 -6
  67. package/test/testdriver/setup/lifecycleHelpers.mjs +19 -24
  68. package/test/testdriver/setup/testHelpers.mjs +18 -23
  69. package/vitest.config.mjs +3 -3
  70. package/.github/workflows/linux-tests.yml +0 -28
  71. package/docs/v7/getting-started/generating-tests.mdx +0 -525
  72. package/test/testdriver/auto-cache-key-demo.test.mjs +0 -56
@@ -168,14 +168,14 @@ Resources:
168
168
  IpProtocol: tcp,
169
169
  FromPort: 8765,
170
170
  ToPort: 8765,
171
- CidrIp: 35.171.123.200/32,
171
+ CidrIp: 74.220.58.0/24,
172
172
  Description: "pyautogui-cli WebSockets - Static IP 1",
173
173
  }
174
174
  - {
175
175
  IpProtocol: tcp,
176
176
  FromPort: 8765,
177
177
  ToPort: 8765,
178
- CidrIp: 52.201.199.222/32,
178
+ CidrIp: 74.220.50.0/24,
179
179
  Description: "pyautogui-cli WebSockets - Static IP 2",
180
180
  }
181
181
  - {
@@ -78,7 +78,7 @@ jobs:
78
78
  AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
79
79
  AWS_REGION: us-east-2
80
80
  AWS_LAUNCH_TEMPLATE_ID: lt-00d02f31cfc602f27
81
- AMI_ID: ami-086b5b4b86d78987c
81
+ AMI_ID: ami-0c2858680200ac890
82
82
  RESOLUTION: 1920x1080
83
83
  - name: Run TestDriver
84
84
  run: node bin/testdriverai.js run testdriver/acceptance/${{ matrix.test }} --ip="${{ steps.aws-setup.outputs.public-ip }}" --junit=out.xml
@@ -1,89 +1,72 @@
1
1
  /**
2
- * Chrome Extension Loading Demo
3
- * Demonstrates how to load Chrome extensions using Chrome for Testing
2
+ * TestDriver SDK - Chrome Extension Test (Vitest)
3
+ * Tests loading a Chrome extension using provision.chromeExtension()
4
4
  *
5
- * This test shows how to launch Chrome with a specific extension loaded
6
- * by using its Chrome Web Store extension ID.
5
+ * This test suite covers:
6
+ * 1. Loading extension from local path (extensionPath)
7
+ * 2. Loading extension from Chrome Web Store (extensionId)
7
8
  */
8
9
 
9
- import { afterAll, beforeAll, describe, expect, it } from "vitest";
10
- import TestDriver from "../../sdk.js";
11
- import {
12
- runPostrun,
13
- runPrerunChromeExtension
14
- } from "./setup/lifecycleHelpers.mjs";
10
+ import { describe, expect, it } from "vitest";
11
+ import { TestDriver } from "../../lib/vitest/hooks.mjs";
15
12
 
16
- describe("Chrome Extension Loading", () => {
17
- let client;
18
- let dashcamUrl;
13
+ describe("Chrome Extension Test", () => {
14
+ it("should load hello-world Chrome extension from local path", async (context) => {
15
+ const testdriver = TestDriver(context, { headless: false, newSandbox: true });
16
+
17
+ // Wait for connection to be ready before running exec
18
+ await testdriver.ready();
19
+
20
+ // Clone the Chrome extensions samples repo
21
+ await testdriver.exec(
22
+ 'sh',
23
+ 'git clone --depth 1 https://github.com/GoogleChrome/chrome-extensions-samples.git /tmp/chrome-extensions-samples',
24
+ 60000,
25
+ true
26
+ );
19
27
 
20
- beforeAll(async () => {
21
- // Initialize TestDriver client
22
- client = await TestDriver.create({
23
- apiKey: process.env.TD_API_KEY,
24
- apiRoot: process.env.TD_API_ROOT,
25
- os: "linux",
26
- verbosity: 1,
28
+ // Launch Chrome with the hello-world extension loaded
29
+ await testdriver.provision.chromeExtension({
30
+ extensionPath: '/tmp/chrome-extensions-samples/functional-samples/tutorial.hello-world',
31
+ url: 'https://testdriver.ai'
27
32
  });
28
33
 
29
- // Run prerun with uBlock Origin extension loaded
30
- // Extension ID: cjpalhdlnbpafiamejdnhcphjbkeiagm
31
- await runPrerunChromeExtension(client, "cjpalhdlnbpafiamejdnhcphjbkeiagm");
32
- });
33
-
34
- afterAll(async () => {
35
- if (client) {
36
- dashcamUrl = await runPostrun(client);
37
- await client.cleanup();
38
- }
39
- });
40
-
41
- it("should load Chrome with extension and verify functionality", async () => {
42
- // Focus Chrome browser
43
- await client.focusApplication("Google Chrome");
44
-
45
- // Verify the page loaded
46
- const pageElement = await client.find("TestDriver.ai Sandbox");
47
- expect(pageElement.found()).toBe(true);
34
+ // The hello-world extension adds a puzzle piece icon to the toolbar
35
+ // When clicked, it shows a popup with "Hello Extensions"
36
+
37
+ // First, let's verify Chrome loaded and we can see the page
38
+ const pageResult = await testdriver.assert("the testdriver.ai website is visible");
39
+ expect(pageResult).toBeTruthy();
48
40
 
49
- // Test basic interaction to ensure Chrome is working with the extension
50
- const signInButton = await client.find(
51
- "Sign In, black button below the password field",
52
- );
53
- await signInButton.click();
41
+ // Click on the extensions button (puzzle piece icon) in Chrome toolbar
42
+ const extensionsButton = await testdriver.find("The puzzle-shaped icon in the Chrome toolbar.");
43
+ await extensionsButton.click();
54
44
 
55
- // Verify error message appears
56
- const result = await client.assert(
57
- "an error shows that fields are required",
58
- );
59
- expect(result).toBeTruthy();
45
+ // Look for the hello world extension in the extensions menu
46
+ const helloExtension = await testdriver.find("Hello Extensions extension in the extensions dropdown");
47
+ await helloExtension.click();
60
48
 
61
- console.log("✅ Chrome extension loaded successfully!");
62
- if (dashcamUrl) {
63
- console.log("🎥 Dashcam URL:", dashcamUrl);
64
- }
49
+ // Verify the extension popup shows "Hello Extensions" text
50
+ const popupResult = await testdriver.assert("a popup shows with the text 'Hello Extensions'");
51
+ expect(popupResult).toBeTruthy();
65
52
  });
66
53
 
67
- it("should demonstrate extension interaction", async () => {
68
- // You can add specific tests here to interact with the extension
69
- // For example, if testing uBlock Origin, you might:
70
- // 1. Navigate to a page with ads
71
- // 2. Verify ads are blocked
72
- // 3. Access the extension's popup or settings
73
-
74
- await client.focusApplication("Google Chrome");
75
-
76
- // Example: Navigate to extension management page to verify it's loaded
77
- await client.exec(
78
- "sh",
79
- `xdotool key --clearmodifiers ctrl+shift+e`,
80
- 5000,
81
- true
82
- );
54
+ it("should load Loom from Chrome Web Store by extensionId", async (context) => {
55
+ const testdriver = TestDriver(context, { headless: false, newSandbox: true});
56
+
57
+ // Launch Chrome with Loom loaded by its Chrome Web Store ID
58
+ // Loom ID: liecbddmkiiihnedobmlmillhodjkdmb
59
+ await testdriver.provision.chromeExtension({
60
+ extensionId: 'liecbddmkiiihnedobmlmillhodjkdmb',
61
+ url: 'https://testdriver.ai'
62
+ });
83
63
 
84
- // Wait a moment for the extensions page to potentially load
85
- await new Promise((resolve) => setTimeout(resolve, 2000));
64
+ // Click on the extensions button (puzzle piece icon) in Chrome toolbar
65
+ const extensionsButton = await testdriver.find("The puzzle-shaped icon in the Chrome toolbar.");
66
+ await extensionsButton.click();
86
67
 
87
- console.log("✅ Extension interaction test completed");
68
+ // Look for Loom in the extensions menu
69
+ const loomExtension = await testdriver.find("Loom extension in the extensions dropdown");
70
+ expect(loomExtension.found()).toBeTruthy();
88
71
  });
89
72
  });
@@ -21,5 +21,6 @@ describe("Element Not Found Test", () => {
21
21
  // Should return an element that is not found
22
22
  expect(element.found()).toBe(false);
23
23
  expect(element.coordinates).toBeNull();
24
- }, 90000); // 90 second timeout for the test (should complete much faster)
24
+ }); // 90 second timeout for the test (should complete much faster)
25
25
  });
26
+
@@ -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: false });
12
+ const testdriver = TestDriver(context, { headless: true });
13
13
 
14
14
  // provision.chrome() automatically calls ready() and starts dashcam
15
15
  await testdriver.provision.chrome({
@@ -9,7 +9,7 @@ import { performLogin } from "./setup/testHelpers.mjs";
9
9
 
10
10
  describe("Scroll Until Text Test", () => {
11
11
  it('should scroll until "testdriver socks" appears', async (context) => {
12
- const testdriver = TestDriver(context, { headless: true });
12
+ const testdriver = TestDriver(context, { headless: true, reconnect: false });
13
13
  await testdriver.provision.chrome({ url: 'http://testdriver-sandbox.vercel.app/login' });
14
14
 
15
15
  //
@@ -18,18 +18,22 @@ describe("Scroll Until Text Test", () => {
18
18
 
19
19
  // Scroll until text appears
20
20
  await testdriver.focusApplication("Google Chrome");
21
+
22
+ await testdriver.find('TestDriver.ai Sandbox heading').click();
23
+
21
24
  // Scroll until text appears
22
25
  let found = false;
23
26
  let scrollCount = 0;
24
27
  const maxScrolls = 10;
25
28
 
26
29
  while (!found && scrollCount < maxScrolls) {
27
- const findResult = await testdriver.find("testdriver socks");
28
- if (findResult) {
29
- found = true;
30
+ const findResult = await testdriver.find("testdriver socks product text is fully visible");
31
+
32
+ if (findResult.found()) {
33
+ found = true;
30
34
  } else {
31
- await testdriver.scroll({ direction: "down" });
32
- scrollCount++;
35
+ await testdriver.scroll();
36
+ scrollCount++;
33
37
  }
34
38
  }
35
39
 
@@ -86,13 +86,6 @@ export async function stopDashcam(client) {
86
86
  const dashcam = getDashcam(client);
87
87
  const url = await dashcam.stop();
88
88
 
89
- if (url) {
90
- console.log("✅ Found dashcam URL:", url);
91
- console.log("🎥 Dashcam URL:", url);
92
- } else {
93
- console.warn("⚠️ No replay URL found in dashcam output");
94
- }
95
-
96
89
  return url;
97
90
  }
98
91
 
@@ -116,7 +109,7 @@ export async function launchChrome(
116
109
  } else {
117
110
  await client.exec(
118
111
  shell,
119
- `google-chrome --start-maximized --disable-fre --no-default-browser-check --no-first-run --guest "${url}" >/dev/null 2>&1 &`,
112
+ `google-chrome --start-maximized --disable-fre --no-default-browser-check --no-first-run --no-experiments --guest "${url}" >/dev/null 2>&1 &`,
120
113
  30000,
121
114
  );
122
115
  }
@@ -188,13 +181,13 @@ export async function launchChromeForTesting(
188
181
  // For now, fallback to regular Chrome on Windows
189
182
  await client.exec(
190
183
  "pwsh",
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}"`,
184
+ `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", "--no-experiments", "${url}"`,
192
185
  30000,
193
186
  );
194
187
  } else {
195
188
  await client.exec(
196
189
  shell,
197
- `chrome-for-testing --start-maximized --disable-fre --no-default-browser-check --no-first-run --user-data-dir=${userDataDir} "${url}" >/dev/null 2>&1 &`,
190
+ `chrome-for-testing --start-maximized --disable-fre --no-default-browser-check --no-first-run --no-experiments --user-data-dir=${userDataDir} "${url}" >/dev/null 2>&1 &`,
198
191
  30000,
199
192
  );
200
193
  }
@@ -202,19 +195,18 @@ export async function launchChromeForTesting(
202
195
 
203
196
  /**
204
197
  * Launch Chrome for Testing with a Chrome extension loaded
198
+ * Also loads dashcam-chrome extension for web log capture on Linux
205
199
  * @param {TestDriver} client - TestDriver client
206
- * @param {string} extensionId - Chrome Web Store extension ID (e.g., "cjpalhdlnbpafiamejdnhcphjbkeiagm" for uBlock Origin)
200
+ * @param {string} extensionPath - Local filesystem path to the unpacked extension directory
207
201
  * @param {string} url - URL to open (default: https://testdriver-sandbox.vercel.app/)
208
202
  * @example
209
- * // Launch with uBlock Origin extension
210
- * await launchChromeExtension(client, "cjpalhdlnbpafiamejdnhcphjbkeiagm");
211
- *
212
- * // Launch with multiple extensions (comma-separated)
213
- * await launchChromeExtension(client, "cjpalhdlnbpafiamejdnhcphjbkeiagm,nngceckbapebfimnlniiiahkandclblb");
203
+ * // Clone an extension and launch Chrome with it
204
+ * await client.exec('sh', 'git clone https://github.com/user/extension.git /tmp/extension');
205
+ * await launchChromeExtension(client, '/tmp/extension');
214
206
  */
215
207
  export async function launchChromeExtension(
216
208
  client,
217
- extensionId,
209
+ extensionPath,
218
210
  url = "http://testdriver-sandbox.vercel.app/",
219
211
  ) {
220
212
  const shell = client.os === "windows" ? "pwsh" : "sh";
@@ -274,13 +266,15 @@ export async function launchChromeExtension(
274
266
  // For now, fallback to regular Chrome on Windows
275
267
  await client.exec(
276
268
  "pwsh",
277
- `Start-Process "C:/Program Files/Google/Chrome/Application/chrome.exe" -ArgumentList "--start-maximized", "--user-data-dir=${userDataDir}", "--load-extension=${extensionId}", "${url}"`,
269
+ `Start-Process "C:/Program Files/Google/Chrome/Application/chrome.exe" -ArgumentList "--start-maximized", "--user-data-dir=${userDataDir}", "--load-extension=${extensionPath}", "${url}"`,
278
270
  30000,
279
271
  );
280
272
  } else {
273
+ // Load both user extension and dashcam-chrome for web log capture
274
+ const extensionsToLoad = `${extensionPath},/usr/lib/node_modules/dashcam-chrome/build`;
281
275
  await client.exec(
282
276
  shell,
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 &`,
277
+ `chrome-for-testing --start-maximized --disable-fre --no-default-browser-check --no-first-run --no-experiments --user-data-dir=${userDataDir} --load-extension=${extensionsToLoad} "${url}" >/dev/null 2>&1 &`,
284
278
  30000,
285
279
  );
286
280
  }
@@ -338,16 +332,17 @@ export async function runPrerunChromeForTesting(client) {
338
332
  * Run prerun lifecycle hooks with Chrome extension loaded
339
333
  * Implements lifecycle/prerun.yaml functionality with a Chrome extension
340
334
  * @param {TestDriver} client - TestDriver client
341
- * @param {string} extensionId - Chrome Web Store extension ID to load
335
+ * @param {string} extensionPath - Local filesystem path to the unpacked extension directory
342
336
  * @example
343
- * // Launch with uBlock Origin extension
344
- * await runPrerunChromeExtension(client, "cjpalhdlnbpafiamejdnhcphjbkeiagm");
337
+ * // Clone an extension and run prerun with it
338
+ * await client.exec('sh', 'git clone https://github.com/user/extension.git /tmp/extension');
339
+ * await runPrerunChromeExtension(client, '/tmp/extension');
345
340
  */
346
- export async function runPrerunChromeExtension(client, extensionId) {
341
+ export async function runPrerunChromeExtension(client, extensionPath) {
347
342
  await authDashcam(client);
348
343
  await addDashcamLog(client);
349
344
  await startDashcam(client);
350
- await launchChromeExtension(client, extensionId);
345
+ await launchChromeExtension(client, extensionPath);
351
346
  await waitForPage(client, "TestDriver.ai Sandbox");
352
347
  }
353
348
 
@@ -11,26 +11,26 @@ import path, { dirname } from "path";
11
11
  import { fileURLToPath } from "url";
12
12
  import TestDriver from "../../../sdk.js";
13
13
  import {
14
- addDashcamLog,
15
- authDashcam,
16
- launchChrome,
17
- runPostrun,
18
- runPrerun,
19
- startDashcam,
20
- stopDashcam,
21
- waitForPage,
14
+ addDashcamLog,
15
+ authDashcam,
16
+ launchChrome,
17
+ runPostrun,
18
+ runPrerun,
19
+ startDashcam,
20
+ stopDashcam,
21
+ waitForPage,
22
22
  } from "./lifecycleHelpers.mjs";
23
23
 
24
24
  // Re-export lifecycle helpers for backward compatibility
25
25
  export {
26
- addDashcamLog,
27
- authDashcam,
28
- launchChrome,
29
- runPostrun,
30
- runPrerun,
31
- startDashcam,
32
- stopDashcam,
33
- waitForPage
26
+ addDashcamLog,
27
+ authDashcam,
28
+ launchChrome,
29
+ runPostrun,
30
+ runPrerun,
31
+ startDashcam,
32
+ stopDashcam,
33
+ waitForPage
34
34
  };
35
35
 
36
36
  // Get the directory of the current module
@@ -70,8 +70,6 @@ export function storeTestResult(
70
70
  dashcamUrl,
71
71
  sessionInfo = {},
72
72
  ) {
73
- console.log(`📝 Storing test result: ${testName}`);
74
- console.log(` Dashcam URL: ${dashcamUrl || "none"}`);
75
73
 
76
74
  // Extract replay object ID from dashcam URL
77
75
  let replayObjectId = null;
@@ -548,9 +546,7 @@ export async function teardownTest(client, options = {}) {
548
546
  };
549
547
 
550
548
  fs.writeFileSync(testResultFile, JSON.stringify(testResult, null, 2));
551
- console.log(
552
- `[TestHelpers] ✅ Wrote test result to file: ${testResultFile} (testFile: ${testFile}, testOrder: ${testOrder})`,
553
- );
549
+
554
550
  } catch (error) {
555
551
  console.error(
556
552
  `[TestHelpers] ❌ Failed to write test result file:`,
@@ -570,7 +566,6 @@ export async function teardownTest(client, options = {}) {
570
566
  console.log("🔌 Disconnecting client...");
571
567
  try {
572
568
  await client.disconnect();
573
- console.log("✅ Client disconnected");
574
569
  } catch (disconnectError) {
575
570
  console.error("❌ Error disconnecting:", disconnectError.message);
576
571
  // Don't throw - we're already in cleanup
@@ -614,7 +609,7 @@ export async function performLogin(
614
609
 
615
610
  // Get password from screen if not provided
616
611
  if (!password) {
617
- password = await client.remember("the password");
612
+ password = await client.extract("the password");
618
613
  }
619
614
 
620
615
  const usernameField = await client.find(
package/vitest.config.mjs CHANGED
@@ -8,12 +8,12 @@ config();
8
8
 
9
9
  export default defineConfig({
10
10
  test: {
11
- testTimeout: 300000,
12
- hookTimeout: 300000,
11
+ testTimeout: 900000,
12
+ hookTimeout: 900000,
13
13
  reporters: [
14
14
  'default',
15
- // Don't pass apiKey/apiRoot here - they'll be read from env at runtime
16
15
  TestDriver(),
16
+ ['junit', { outputFile: 'test-report.junit.xml' }]
17
17
  ],
18
18
  setupFiles: ['testdriverai/vitest/setup'],
19
19
  },
@@ -1,28 +0,0 @@
1
- name: Linux Tests
2
-
3
- on:
4
- push:
5
- branches: [ main, develop ]
6
- pull_request:
7
- branches: [ main, develop ]
8
-
9
- jobs:
10
- test:
11
- runs-on: ubuntu-latest
12
-
13
- steps:
14
- - uses: actions/checkout@v4
15
-
16
- - name: Setup Node.js
17
- uses: actions/setup-node@v4
18
- with:
19
- node-version: '20'
20
- cache: 'npm'
21
-
22
- - name: Install dependencies
23
- run: npm ci
24
-
25
- - name: Run Linux tests
26
- run: npx vitest run test/testdriver/assert.test.mjs
27
- env:
28
- TD_API_KEY: ${{ secrets.TD_API_KEY }}