testdriverai 7.2.46 → 7.2.48

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 (60) hide show
  1. package/.github/workflows/acceptance-linux-scheduled.yaml +1 -1
  2. package/.github/workflows/acceptance.yaml +2 -2
  3. package/.github/workflows/windows-self-hosted.yaml +1 -1
  4. package/README.md +2 -2
  5. package/agent/lib/sdk.js +177 -22
  6. package/docs/TEST-GITHUB-COMMENTS.md +2 -2
  7. package/docs/v7/_drafts/plugin-migration.mdx +1 -1
  8. package/docs/v7/aws-setup.mdx +1 -1
  9. package/docs/v7/examples.mdx +1 -1
  10. package/docs/v7/find.mdx +35 -0
  11. package/{test/testdriver → examples}/chrome-extension.test.mjs +3 -3
  12. package/interfaces/vitest-plugin.mjs +77 -12
  13. package/package.json +1 -1
  14. package/sdk.js +20 -4
  15. package/test/manual/reconnect-provision.test.mjs +2 -2
  16. package/testdriver-plugin/skills/actions/SKILL.md +93 -0
  17. package/testdriver-plugin/skills/assertions/SKILL.md +77 -0
  18. package/testdriver-plugin/skills/caching/SKILL.md +66 -0
  19. package/testdriver-plugin/skills/creating-tests/SKILL.md +104 -0
  20. package/testdriver-plugin/skills/finding-elements/SKILL.md +77 -0
  21. package/testdriver-plugin/skills/github-actions/SKILL.md +100 -0
  22. package/testdriver-plugin/skills/running-tests/SKILL.md +77 -0
  23. package/testdriver-plugin/skills/secrets/SKILL.md +87 -0
  24. package/testdriver-plugin/skills/self-hosting/SKILL.md +89 -0
  25. package/testdriver-plugin/skills/setup/SKILL.md +76 -0
  26. package/testdriver-plugin/skills/variables/SKILL.md +88 -0
  27. package/testdriver-plugin/skills/waiting/SKILL.md +72 -0
  28. package/debug/01-table-initial.png +0 -0
  29. package/debug/02-after-ai-explore.png +0 -0
  30. package/debug/02-after-scroll.png +0 -0
  31. package/examples/github-actions.yml +0 -68
  32. package/examples/run-tests-with-recording.sh +0 -70
  33. package/examples/screenshot-example.js +0 -63
  34. package/examples/sdk-awesome-logs-demo.js +0 -177
  35. package/examples/sdk-cache-thresholds.js +0 -96
  36. package/examples/sdk-element-properties.js +0 -155
  37. package/examples/sdk-simple-example.js +0 -65
  38. package/examples/test-recording-example.test.js +0 -166
  39. /package/{test/testdriver → examples}/ai.test.mjs +0 -0
  40. /package/{test/testdriver → examples}/assert.test.mjs +0 -0
  41. /package/{test/testdriver → examples}/drag-and-drop.test.mjs +0 -0
  42. /package/{test/testdriver → examples}/element-not-found.test.mjs +0 -0
  43. /package/{test/testdriver → examples}/exec-output.test.mjs +0 -0
  44. /package/{test/testdriver → examples}/exec-pwsh.test.mjs +0 -0
  45. /package/{test/testdriver → examples}/focus-window.test.mjs +0 -0
  46. /package/{test/testdriver → examples}/formatted-logging.test.mjs +0 -0
  47. /package/{test/testdriver → examples}/hover-image.test.mjs +0 -0
  48. /package/{test/testdriver → examples}/hover-text-with-description.test.mjs +0 -0
  49. /package/{test/testdriver → examples}/hover-text.test.mjs +0 -0
  50. /package/{test/testdriver → examples}/installer.test.mjs +0 -0
  51. /package/{test/testdriver → examples}/launch-vscode-linux.test.mjs +0 -0
  52. /package/{test/testdriver → examples}/match-image.test.mjs +0 -0
  53. /package/{test/testdriver → examples}/press-keys.test.mjs +0 -0
  54. /package/{test/testdriver → examples}/prompt.test.mjs +0 -0
  55. /package/{test/testdriver → examples}/scroll-keyboard.test.mjs +0 -0
  56. /package/{test/testdriver → examples}/scroll-until-image.test.mjs +0 -0
  57. /package/{test/testdriver → examples}/scroll-until-text.test.mjs +0 -0
  58. /package/{test/testdriver → examples}/scroll.test.mjs +0 -0
  59. /package/{test/testdriver → examples}/type.test.mjs +0 -0
  60. /package/{test/testdriver → examples}/windows-installer.test.mjs +0 -0
@@ -0,0 +1,89 @@
1
+ ---
2
+ name: self-hosting
3
+ description: Self-host TestDriver sandboxes. Use when running Windows tests on AWS, configuring custom AMIs, or setting up your own infrastructure.
4
+ ---
5
+
6
+ # Self-Hosting
7
+
8
+ Read: `node_modules/testdriverai/docs/v7/self-hosted.mdx`
9
+ Read: `node_modules/testdriverai/docs/v7/aws-setup.mdx`
10
+
11
+ ## When to Self-Host
12
+
13
+ - **Windows testing** - Required for Windows sandboxes
14
+ - **Custom environments** - Special software or configurations
15
+ - **Data compliance** - Keep tests in your own infrastructure
16
+ - **Performance** - Reduce latency with regional instances
17
+
18
+ ## AWS Setup for Windows
19
+
20
+ ### Prerequisites
21
+ 1. AWS account with EC2 access
22
+ 2. TestDriver Windows AMI (contact support)
23
+ 3. VPC with public subnet
24
+
25
+ ### Required Environment Variables
26
+
27
+ ```bash
28
+ TD_API_KEY=your_api_key
29
+ TD_OS=windows
30
+ AWS_REGION=us-east-2
31
+ AWS_ACCESS_KEY_ID=AKIA...
32
+ AWS_SECRET_ACCESS_KEY=...
33
+ AMI_ID=ami-0dd5fa241273a7d50
34
+ AWS_LAUNCH_TEMPLATE_ID=lt-0ef9bf26a945fb442
35
+ ```
36
+
37
+ ### Launch Template Configuration
38
+
39
+ Create an EC2 launch template with:
40
+ - Instance type: `c5.xlarge` or larger
41
+ - AMI: TestDriver Windows AMI
42
+ - Security group: Allow RDP (3389) and TestDriver ports
43
+ - IAM role: EC2 permissions for your use case
44
+
45
+ ### Running Windows Tests
46
+
47
+ ```bash
48
+ TD_OS=windows npx vitest run tests/windows-app.test.mjs
49
+ ```
50
+
51
+ ## Test Configuration
52
+
53
+ ```javascript
54
+ const testdriver = TestDriver(context, {
55
+ os: 'windows', // Use Windows sandbox
56
+ });
57
+
58
+ await testdriver.provision.chrome({ url: 'https://example.com' });
59
+ // or
60
+ await testdriver.provision.installer({
61
+ url: 'https://example.com/app.msi',
62
+ launch: true,
63
+ });
64
+ ```
65
+
66
+ ## Windows-Specific Examples
67
+
68
+ - `node_modules/testdriverai/examples/windows-installer.test.mjs`
69
+ - `node_modules/testdriverai/examples/exec-pwsh.test.mjs`
70
+
71
+ ## PowerShell Execution
72
+
73
+ ```javascript
74
+ // Run PowerShell commands on Windows
75
+ const result = await testdriver.exec("pwsh", "Get-Date", 5000);
76
+ const files = await testdriver.exec("pwsh", "Get-ChildItem C:\\", 5000);
77
+ ```
78
+
79
+ ## Troubleshooting
80
+
81
+ **Instance not starting?**
82
+ - Check AWS credentials and permissions
83
+ - Verify launch template exists
84
+ - Check AMI is available in your region
85
+
86
+ **Connection timeout?**
87
+ - Security group must allow inbound traffic
88
+ - Instance needs public IP or NAT gateway
89
+ - Check TestDriver agent is running on AMI
@@ -0,0 +1,76 @@
1
+ ---
2
+ name: setup
3
+ description: Set up TestDriver in a project. Use when installing testdriverai, configuring vitest, setting up TD_API_KEY, or initializing a new test project.
4
+ ---
5
+
6
+ # Setting Up TestDriver
7
+
8
+ Read the quickstart guide: `node_modules/testdriverai/docs/v7/quickstart.mdx`
9
+
10
+ ## Requirements
11
+
12
+ 1. **API Key** from [console.testdriver.ai/team](https://console.testdriver.ai/team)
13
+ 2. **Node.js** and **Vitest**
14
+
15
+ ## Setup Steps
16
+
17
+ ### 1. Install TestDriver
18
+
19
+ ```bash
20
+ npm install testdriverai vitest dotenv --save-dev
21
+ ```
22
+
23
+ ### 2. Create `.env` file
24
+
25
+ ```bash
26
+ TD_API_KEY=your_api_key_here
27
+ ```
28
+
29
+ ### 3. Create `vitest.config.mjs`
30
+
31
+ ```javascript
32
+ import { config } from 'dotenv';
33
+ import TestDriver from 'testdriverai/vitest';
34
+ import { defineConfig } from 'vitest/config';
35
+
36
+ config();
37
+
38
+ const setupFiles = ['testdriverai/vitest/setup', 'testdriverai/vitest/setup-aws'];
39
+
40
+ export default defineConfig({
41
+ test: {
42
+ testTimeout: 900000,
43
+ hookTimeout: 900000,
44
+ disableConsoleIntercept: true,
45
+ maxConcurrency: 3,
46
+ reporters: ['default', TestDriver(), ['junit', { outputFile: 'test-report.junit.xml' }]],
47
+ setupFiles,
48
+ },
49
+ });
50
+ ```
51
+
52
+ ### 4. Add to `.gitignore`
53
+
54
+ ```
55
+ .env
56
+ ```
57
+
58
+ ## Verify Setup
59
+
60
+ Create a test file `tests/example.test.mjs`:
61
+
62
+ ```javascript
63
+ import { describe, expect, it } from "vitest";
64
+ import { TestDriver } from "testdriverai/lib/vitest/hooks.mjs";
65
+
66
+ describe("Setup Test", () => {
67
+ it("should load a page", async (context) => {
68
+ const testdriver = TestDriver(context);
69
+ await testdriver.provision.chrome({ url: 'https://example.com' });
70
+ const result = await testdriver.assert("Example Domain heading is visible");
71
+ expect(result).toBeTruthy();
72
+ });
73
+ });
74
+ ```
75
+
76
+ Run: `npx vitest run tests/example.test.mjs`
@@ -0,0 +1,88 @@
1
+ ---
2
+ name: variables
3
+ description: Use variables in TestDriver tests. Use when parameterizing tests, using environment variables, or passing data between test steps.
4
+ ---
5
+
6
+ # Using Variables
7
+
8
+ Read: `node_modules/testdriverai/docs/v7/variables.mdx`
9
+
10
+ ## Environment Variables
11
+
12
+ Access via `process.env`:
13
+
14
+ ```javascript
15
+ const username = process.env.TEST_USERNAME;
16
+ const password = process.env.TEST_PASSWORD;
17
+
18
+ await testdriver.find("Username input").click();
19
+ await testdriver.type(username);
20
+ ```
21
+
22
+ ## .env File
23
+
24
+ Create `.env` in project root:
25
+
26
+ ```bash
27
+ TD_API_KEY=your_api_key
28
+ TEST_USERNAME=testuser@example.com
29
+ TEST_PASSWORD=testpass123
30
+ BASE_URL=https://staging.example.com
31
+ ```
32
+
33
+ Load with dotenv (already configured in vitest.config.mjs):
34
+
35
+ ```javascript
36
+ import { config } from 'dotenv';
37
+ config();
38
+ ```
39
+
40
+ ## Parameterized Tests
41
+
42
+ ```javascript
43
+ const testCases = [
44
+ { email: 'user1@test.com', expected: 'Welcome User 1' },
45
+ { email: 'user2@test.com', expected: 'Welcome User 2' },
46
+ ];
47
+
48
+ describe("Login Tests", () => {
49
+ testCases.forEach(({ email, expected }) => {
50
+ it(`should login ${email}`, async (context) => {
51
+ const testdriver = TestDriver(context);
52
+ await testdriver.provision.chrome({ url: process.env.BASE_URL });
53
+
54
+ await testdriver.find("Email input").click();
55
+ await testdriver.type(email);
56
+
57
+ const result = await testdriver.assert(`page shows '${expected}'`);
58
+ expect(result).toBeTruthy();
59
+ });
60
+ });
61
+ });
62
+ ```
63
+
64
+ ## Sharing Data Between Steps
65
+
66
+ ```javascript
67
+ it("should complete flow", async (context) => {
68
+ const testdriver = TestDriver(context);
69
+ await testdriver.provision.chrome({ url: 'https://example.com' });
70
+
71
+ // Get data from page
72
+ const orderId = await testdriver.exec("js",
73
+ "return document.querySelector('.order-id').textContent",
74
+ 5000
75
+ );
76
+
77
+ // Use in later assertions
78
+ const result = await testdriver.assert(`Order ${orderId} is confirmed`);
79
+ expect(result).toBeTruthy();
80
+ });
81
+ ```
82
+
83
+ ## Dynamic URLs
84
+
85
+ ```javascript
86
+ const baseUrl = process.env.BASE_URL || 'https://localhost:3000';
87
+ await testdriver.provision.chrome({ url: `${baseUrl}/login` });
88
+ ```
@@ -0,0 +1,72 @@
1
+ ---
2
+ name: waiting
3
+ description: Wait for elements in TestDriver tests. Use when polling for elements, waiting for page loads, handling loading states, or setting timeouts.
4
+ ---
5
+
6
+ # Waiting for Elements
7
+
8
+ Read: `node_modules/testdriverai/docs/v7/waiting-for-elements.mdx`
9
+
10
+ ## Polling with Timeout
11
+
12
+ Use the `timeout` option to poll until an element is found:
13
+
14
+ ```javascript
15
+ // Retries every 5 seconds until found or timeout
16
+ const element = await testdriver.find("Success message", { timeout: 30000 });
17
+ ```
18
+
19
+ ## Wait for Page Load
20
+
21
+ ```javascript
22
+ // Assert something visible after load
23
+ await testdriver.assert("Page has finished loading");
24
+
25
+ // Or check for specific content
26
+ await testdriver.assert("Welcome message is visible");
27
+ ```
28
+
29
+ ## Wait via Assertion
30
+
31
+ ```javascript
32
+ // This will wait and retry until true or timeout
33
+ const loaded = await testdriver.assert("The dashboard has fully loaded");
34
+ expect(loaded).toBeTruthy();
35
+ ```
36
+
37
+ ## Wait via exec (JavaScript)
38
+
39
+ ```javascript
40
+ await testdriver.exec("js", `
41
+ await new Promise(resolve => {
42
+ const check = () => {
43
+ if (document.querySelector('.loaded')) resolve();
44
+ else setTimeout(check, 100);
45
+ };
46
+ check();
47
+ });
48
+ `, 10000);
49
+ ```
50
+
51
+ ## Common Patterns
52
+
53
+ ### Wait for element to disappear
54
+ ```javascript
55
+ // Keep checking until loading spinner is gone
56
+ let spinner = await testdriver.find("Loading spinner");
57
+ while (spinner.found()) {
58
+ await new Promise(r => setTimeout(r, 1000));
59
+ spinner = await testdriver.find("Loading spinner");
60
+ }
61
+ ```
62
+
63
+ ### Wait between actions
64
+ ```javascript
65
+ await button.click();
66
+ await new Promise(r => setTimeout(r, 2000)); // Wait 2 seconds
67
+ await testdriver.assert("Result is visible");
68
+ ```
69
+
70
+ ## Examples
71
+
72
+ See `node_modules/testdriverai/docs/guide/best-practices-polling.mdx`
Binary file
Binary file
Binary file
@@ -1,68 +0,0 @@
1
- name: TestDriver Tests with GitHub Comments
2
-
3
- on:
4
- pull_request:
5
- types: [opened, synchronize, reopened]
6
- push:
7
- branches: [main, develop]
8
-
9
- jobs:
10
- test:
11
- runs-on: ubuntu-latest
12
-
13
- permissions:
14
- # Required for posting comments on PRs
15
- pull-requests: write
16
- # Required for posting comments on commits
17
- contents: write
18
-
19
- steps:
20
- - name: Checkout code
21
- uses: actions/checkout@v4
22
-
23
- - name: Setup Node.js
24
- uses: actions/setup-node@v4
25
- with:
26
- node-version: '20'
27
- cache: 'npm'
28
-
29
- - name: Install dependencies
30
- run: npm ci
31
-
32
- - name: Run TestDriver tests
33
- env:
34
- # TestDriver API key (add this to your repository secrets)
35
- TD_API_KEY: ${{ secrets.TD_API_KEY }}
36
-
37
- # GitHub token for posting comments (automatically provided)
38
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
39
-
40
- # PR number for PR comments
41
- GITHUB_PR_NUMBER: ${{ github.event.pull_request.number }}
42
-
43
- # Git information (automatically available)
44
- # GITHUB_SHA, GITHUB_REF_NAME, GITHUB_REPOSITORY, GITHUB_ACTOR
45
-
46
- run: npm run test:sdk
47
-
48
- - name: Upload test results
49
- if: always()
50
- uses: actions/upload-artifact@v4
51
- with:
52
- name: test-results
53
- path: |
54
- test-report.junit.xml
55
- test-results/
56
- retention-days: 30
57
-
58
- - name: Comment PR on failure
59
- if: failure() && github.event_name == 'pull_request'
60
- uses: actions/github-script@v7
61
- with:
62
- script: |
63
- github.rest.issues.createComment({
64
- issue_number: context.issue.number,
65
- owner: context.repo.owner,
66
- repo: context.repo.repo,
67
- body: '❌ TestDriver tests failed. Check the workflow logs for details.'
68
- })
@@ -1,70 +0,0 @@
1
- #!/bin/bash
2
-
3
- # Example script showing how to run tests with TestDriver + Dashcam integration
4
- # This script demonstrates the complete flow:
5
- # 1. Start dashcam
6
- # 2. Run tests with Vitest reporter
7
- # 3. Stop and publish dashcam recording
8
- # 4. View results in TestDriver dashboard
9
-
10
- set -e
11
-
12
- echo "======================================"
13
- echo "TestDriver + Dashcam Test Recording"
14
- echo "======================================"
15
- echo ""
16
-
17
- # Check for required environment variables
18
- if [ -z "$TD_API_KEY" ]; then
19
- echo "Error: TD_API_KEY environment variable is required"
20
- echo "Get your API key from: https://console.testdriver.ai/settings/api-keys"
21
- exit 1
22
- fi
23
-
24
- if [ -z "$DASHCAM_PROJECT_ID" ]; then
25
- echo "Warning: DASHCAM_PROJECT_ID not set, replays won't be published"
26
- fi
27
-
28
- # Start Dashcam recording
29
- echo "📹 Starting Dashcam..."
30
- dashcam start
31
-
32
- # Track test logs
33
- echo "📝 Tracking test output..."
34
- dashcam track --name="TestDriver Tests" --type=application --pattern="*.log"
35
-
36
- echo ""
37
-
38
- # Run tests with Vitest and TestDriver reporter
39
- echo "🧪 Running tests..."
40
- npx vitest run --config vitest.config.example.js
41
-
42
- # Capture exit code
43
- TEST_EXIT_CODE=$?
44
-
45
- # Stop dashcam
46
- echo ""
47
- echo "🛑 Stopping Dashcam..."
48
- dashcam stop
49
-
50
- # Publish to dashcam project if configured
51
- if [ -n "$DASHCAM_PROJECT_ID" ]; then
52
- echo "📤 Publishing replay to project: $DASHCAM_PROJECT_ID"
53
- REPLAY_URL=$(dashcam publish -p "$DASHCAM_PROJECT_ID" --json | jq -r '.replayUrl')
54
- echo "✅ Replay URL: $REPLAY_URL"
55
- echo ""
56
- echo "View your test recording at:"
57
- echo "$REPLAY_URL"
58
- else
59
- echo "⚠️ Skipping publish (DASHCAM_PROJECT_ID not set)"
60
- fi
61
-
62
- echo ""
63
- echo "======================================"
64
- echo "📊 View Results"
65
- echo "======================================"
66
- echo "Dashboard: https://console.testdriver.ai/dashboard/test-runs"
67
- echo ""
68
-
69
- # Exit with the same code as tests
70
- exit $TEST_EXIT_CODE
@@ -1,63 +0,0 @@
1
- /**
2
- * TestDriver SDK - Screenshot Example
3
- *
4
- * This example demonstrates how to use the screenshot() method
5
- * to capture screenshots of the sandbox environment.
6
- */
7
-
8
- const TestDriver = require("../sdk.js");
9
- const fs = require("fs");
10
- const path = require("path");
11
-
12
- async function main() {
13
- // Initialize TestDriver SDK
14
- const client = new TestDriver(process.env.TD_API_KEY);
15
-
16
- try {
17
- // Connect to sandbox
18
- console.log("Connecting to sandbox...");
19
- await client.connect();
20
-
21
- // Navigate to a website
22
- console.log("Opening Chrome and navigating to example.com...");
23
- await client.focusApplication("Google Chrome");
24
- const urlBar = await client.find("URL bar in Chrome");
25
- await urlBar.click();
26
- await client.type("https://example.com");
27
- await client.pressKeys(["enter"]);
28
-
29
- // Wait a moment for page to load
30
- await client.wait(2000);
31
-
32
- // Capture a screenshot
33
- console.log("Capturing screenshot...");
34
- const screenshot = await client.screenshot();
35
-
36
- // Save screenshot to file
37
- const outputPath = path.join(__dirname, "example-screenshot.png");
38
- fs.writeFileSync(outputPath, Buffer.from(screenshot, "base64"));
39
- console.log(`Screenshot saved to: ${outputPath}`);
40
-
41
- // You can also capture with the mouse cursor visible
42
- console.log("Capturing screenshot with mouse cursor...");
43
- await client.hover(400, 300);
44
- const screenshotWithMouse = await client.screenshot(1, false, true);
45
-
46
- const outputPathWithMouse = path.join(
47
- __dirname,
48
- "example-screenshot-with-mouse.png",
49
- );
50
- fs.writeFileSync(
51
- outputPathWithMouse,
52
- Buffer.from(screenshotWithMouse, "base64"),
53
- );
54
- console.log(`Screenshot with mouse saved to: ${outputPathWithMouse}`);
55
- } catch (error) {
56
- console.error("Error:", error);
57
- } finally {
58
- // Clean up
59
- await client.disconnect();
60
- }
61
- }
62
-
63
- main();