testdriverai 7.0.0 → 7.1.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 (112) hide show
  1. package/AGENTS.md +550 -0
  2. package/CODEOWNERS +0 -1
  3. package/README.md +126 -0
  4. package/agent/index.js +43 -18
  5. package/agent/lib/commands.js +794 -135
  6. package/agent/lib/redraw.js +124 -39
  7. package/agent/lib/sandbox.js +10 -1
  8. package/agent/lib/sdk.js +21 -0
  9. package/docs/MIGRATION.md +425 -0
  10. package/docs/PRESETS.md +210 -0
  11. package/docs/docs.json +91 -37
  12. package/docs/guide/best-practices-polling.mdx +154 -0
  13. package/docs/v7/api/dashcam.mdx +497 -0
  14. package/docs/v7/api/doubleClick.mdx +102 -0
  15. package/docs/v7/api/mouseDown.mdx +161 -0
  16. package/docs/v7/api/mouseUp.mdx +164 -0
  17. package/docs/v7/api/rightClick.mdx +123 -0
  18. package/docs/v7/getting-started/configuration.mdx +380 -0
  19. package/docs/v7/getting-started/quickstart.mdx +273 -140
  20. package/docs/v7/guides/best-practices.mdx +486 -0
  21. package/docs/v7/guides/caching-ai.mdx +215 -0
  22. package/docs/v7/guides/caching-selectors.mdx +292 -0
  23. package/docs/v7/guides/caching.mdx +366 -0
  24. package/docs/v7/guides/ci-cd/azure.mdx +587 -0
  25. package/docs/v7/guides/ci-cd/circleci.mdx +523 -0
  26. package/docs/v7/guides/ci-cd/github-actions.mdx +457 -0
  27. package/docs/v7/guides/ci-cd/gitlab.mdx +498 -0
  28. package/docs/v7/guides/ci-cd/jenkins.mdx +664 -0
  29. package/docs/v7/guides/ci-cd/travis.mdx +438 -0
  30. package/docs/v7/guides/debugging.mdx +349 -0
  31. package/docs/v7/guides/faq.mdx +393 -0
  32. package/docs/v7/guides/performance.mdx +517 -0
  33. package/docs/v7/guides/troubleshooting.mdx +526 -0
  34. package/docs/v7/guides/vitest-plugin.mdx +477 -0
  35. package/docs/v7/guides/vitest.mdx +535 -0
  36. package/docs/v7/platforms/linux.mdx +308 -0
  37. package/docs/v7/platforms/macos.mdx +433 -0
  38. package/docs/v7/platforms/windows.mdx +430 -0
  39. package/docs/v7/presets/chrome-extension.mdx +223 -0
  40. package/docs/v7/presets/chrome.mdx +287 -0
  41. package/docs/v7/presets/electron.mdx +435 -0
  42. package/docs/v7/presets/vscode.mdx +398 -0
  43. package/docs/v7/presets/webapp.mdx +396 -0
  44. package/docs/v7/progressive-apis/CORE.md +459 -0
  45. package/docs/v7/progressive-apis/HOOKS.md +360 -0
  46. package/docs/v7/progressive-apis/PROGRESSIVE_DISCLOSURE.md +230 -0
  47. package/docs/v7/progressive-apis/PROVISION.md +266 -0
  48. package/interfaces/vitest-plugin.mjs +186 -100
  49. package/package.json +12 -1
  50. package/sdk.d.ts +335 -42
  51. package/sdk.js +756 -95
  52. package/src/core/Dashcam.js +469 -0
  53. package/src/core/index.d.ts +150 -0
  54. package/src/core/index.js +12 -0
  55. package/src/presets/index.mjs +331 -0
  56. package/src/vitest/extended.mjs +108 -0
  57. package/src/vitest/hooks.d.ts +119 -0
  58. package/src/vitest/hooks.mjs +298 -0
  59. package/src/vitest/index.mjs +64 -0
  60. package/src/vitest/lifecycle.mjs +277 -0
  61. package/src/vitest/utils.mjs +150 -0
  62. package/test/dashcam.test.js +137 -0
  63. package/testdriver/acceptance-sdk/assert.test.mjs +13 -31
  64. package/testdriver/acceptance-sdk/auto-cache-key-demo.test.mjs +56 -0
  65. package/testdriver/acceptance-sdk/chrome-extension.test.mjs +89 -0
  66. package/testdriver/acceptance-sdk/drag-and-drop.test.mjs +7 -19
  67. package/testdriver/acceptance-sdk/element-not-found.test.mjs +6 -19
  68. package/testdriver/acceptance-sdk/exec-js.test.mjs +6 -18
  69. package/testdriver/acceptance-sdk/exec-output.test.mjs +8 -20
  70. package/testdriver/acceptance-sdk/exec-pwsh.test.mjs +13 -25
  71. package/testdriver/acceptance-sdk/focus-window.test.mjs +8 -20
  72. package/testdriver/acceptance-sdk/formatted-logging.test.mjs +5 -20
  73. package/testdriver/acceptance-sdk/hooks-example.test.mjs +38 -0
  74. package/testdriver/acceptance-sdk/hover-image.test.mjs +10 -19
  75. package/testdriver/acceptance-sdk/hover-text-with-description.test.mjs +7 -19
  76. package/testdriver/acceptance-sdk/hover-text.test.mjs +5 -19
  77. package/testdriver/acceptance-sdk/match-image.test.mjs +7 -19
  78. package/testdriver/acceptance-sdk/presets-example.test.mjs +87 -0
  79. package/testdriver/acceptance-sdk/press-keys.test.mjs +5 -19
  80. package/testdriver/acceptance-sdk/prompt.test.mjs +6 -18
  81. package/testdriver/acceptance-sdk/scroll-keyboard.test.mjs +6 -20
  82. package/testdriver/acceptance-sdk/scroll-until-image.test.mjs +6 -18
  83. package/testdriver/acceptance-sdk/scroll-until-text.test.mjs +9 -23
  84. package/testdriver/acceptance-sdk/scroll.test.mjs +12 -21
  85. package/testdriver/acceptance-sdk/setup/testHelpers.mjs +124 -352
  86. package/testdriver/acceptance-sdk/sully-ai.test.mjs +234 -0
  87. package/testdriver/acceptance-sdk/test-console-logs.test.mjs +42 -0
  88. package/testdriver/acceptance-sdk/type.test.mjs +19 -58
  89. package/vitest.config.mjs +1 -0
  90. package/.vscode/mcp.json +0 -9
  91. package/MIGRATION.md +0 -389
  92. package/PLUGIN_MIGRATION.md +0 -222
  93. package/PROMPT_CACHE.md +0 -200
  94. package/SDK_LOGGING.md +0 -222
  95. package/SDK_MIGRATION.md +0 -474
  96. package/SDK_README.md +0 -1122
  97. package/debug-screenshot-1763401388589.png +0 -0
  98. package/examples/run-tests-with-recording.sh +0 -70
  99. package/examples/screenshot-example.js +0 -63
  100. package/examples/sdk-awesome-logs-demo.js +0 -177
  101. package/examples/sdk-cache-thresholds.js +0 -96
  102. package/examples/sdk-element-properties.js +0 -155
  103. package/examples/sdk-simple-example.js +0 -65
  104. package/examples/test-recording-example.test.js +0 -166
  105. package/mcp-server/AI_GUIDELINES.md +0 -57
  106. package/test-find-api.js +0 -73
  107. package/test-prompt-cache.js +0 -96
  108. package/test-sandbox-render.js +0 -28
  109. package/test-sdk-methods.js +0 -15
  110. package/test-sdk-refactor.js +0 -53
  111. package/test-stack-trace.mjs +0 -57
  112. package/testdriver/acceptance-sdk/setup/lifecycleHelpers.mjs +0 -239
Binary file
@@ -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://app.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://app.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();
@@ -1,177 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- /**
4
- * TestDriver SDK - AWESOME Logs Demo 🎨
5
- *
6
- * This example showcases the beautiful, emoji-rich logging with great DX
7
- * that makes your test output a joy to read!
8
- *
9
- * Run: TD_API_KEY=your_key node examples/sdk-awesome-logs-demo.js
10
- */
11
-
12
- const TestDriver = require("../sdk.js");
13
- const { formatter } = require("../sdk-log-formatter.js");
14
-
15
- (async () => {
16
- try {
17
- console.log(
18
- formatter.formatHeader("TestDriver SDK - AWESOME Logs Demo", "🚀"),
19
- );
20
-
21
- // Create client with logging enabled
22
- const client = new TestDriver(process.env.TD_API_KEY, {
23
- os: "windows",
24
- logging: true,
25
- });
26
-
27
- // Demo 1: Connection
28
- console.log(
29
- formatter.formatConnection("connect", {
30
- sandboxId: "demo-sandbox-123",
31
- os: "Windows",
32
- }),
33
- );
34
-
35
- await client.connect({ headless: true });
36
-
37
- // Demo 2: Navigation
38
- console.log(
39
- "\n" + formatter.formatAction("navigate", "https://example.com"),
40
- );
41
- await client.focusApplication("Google Chrome");
42
- await client.type("https://example.com");
43
- await client.pressKeys(["enter"]);
44
-
45
- // Demo 3: Wait with loading indicator
46
- console.log("\n" + formatter.formatWaiting("for page to load", 2000));
47
- await new Promise((resolve) => setTimeout(resolve, 2000));
48
-
49
- // Demo 4: Finding elements (this will use the real formatElementFound from sdk.js)
50
- console.log("\n" + formatter.formatHeader("Finding Elements", "🔍"));
51
-
52
- const heading = await client.find("heading that says Example Domain");
53
- // The actual find() call will emit the formatted log automatically
54
-
55
- if (heading.found()) {
56
- await heading.click();
57
- // The click will also emit a formatted log automatically
58
- }
59
-
60
- // Demo 5: Multiple actions
61
- console.log("\n" + formatter.formatHeader("User Actions", "👆"));
62
-
63
- const link = await client.find("More information link");
64
- if (link.found()) {
65
- await link.hover();
66
- await link.click();
67
- }
68
-
69
- // Demo 6: Typing
70
- console.log(
71
- "\n" +
72
- formatter.formatAction("type", "search query", {
73
- text: "TestDriver AI",
74
- }),
75
- );
76
-
77
- // Demo 7: Scroll
78
- console.log("\n" + formatter.formatAction("scroll", "down the page"));
79
- await client.scroll("down", 300);
80
-
81
- // Demo 8: Assertions
82
- console.log("\n" + formatter.formatHeader("Assertions", "✅"));
83
- console.log(
84
- formatter.formatAssertion("Page title is correct", true, {
85
- duration: "45ms",
86
- }),
87
- );
88
- console.log(
89
- formatter.formatAssertion("Footer is visible", true, {
90
- duration: "23ms",
91
- }),
92
- );
93
- console.log(
94
- formatter.formatAssertion("Login button exists", false, {
95
- duration: "1234ms",
96
- }),
97
- );
98
-
99
- // Demo 9: Cache status
100
- console.log("\n" + formatter.formatHeader("Cache Performance", "⚡"));
101
- console.log(
102
- formatter.formatCacheStatus(true, {
103
- similarity: 0.98,
104
- strategy: "image",
105
- }),
106
- );
107
- console.log(
108
- formatter.formatCacheStatus(false, {
109
- strategy: "text",
110
- }),
111
- );
112
-
113
- // Demo 10: Screenshot
114
- console.log(
115
- "\n" +
116
- formatter.formatScreenshot({
117
- path: "/tmp/testdriver-debug/screenshot-123.png",
118
- size: "245 KB",
119
- }),
120
- );
121
-
122
- // Demo 11: Progress
123
- console.log("\n" + formatter.formatHeader("Multi-step Process", "📈"));
124
- for (let i = 1; i <= 5; i++) {
125
- console.log(formatter.formatProgress(i, 5, `Processing step ${i}`));
126
- await new Promise((resolve) => setTimeout(resolve, 300));
127
- }
128
-
129
- // Demo 12: Divider
130
- console.log("\n" + formatter.formatDivider());
131
-
132
- // Demo 13: Test summary
133
- console.log(
134
- formatter.formatSummary({
135
- passed: 12,
136
- failed: 2,
137
- skipped: 1,
138
- total: 15,
139
- duration: "45.23s",
140
- }),
141
- );
142
-
143
- // Demo 14: Error handling
144
- console.log(formatter.formatHeader("Error Examples", "🚨"));
145
- console.log(
146
- formatter.formatError(
147
- "Element not found",
148
- new Error("Timeout after 5000ms"),
149
- ),
150
- );
151
- console.log(
152
- formatter.formatError(
153
- "Connection failed",
154
- new Error("Network unreachable"),
155
- ),
156
- );
157
-
158
- // Demo 15: Test lifecycle
159
- console.log(formatter.formatTestStart("Login Flow Test"));
160
- await new Promise((resolve) => setTimeout(resolve, 1000));
161
- console.log(formatter.formatTestEnd("Login Flow Test", true, 2345));
162
-
163
- console.log(formatter.formatTestStart("Checkout Process"));
164
- await new Promise((resolve) => setTimeout(resolve, 800));
165
- console.log(formatter.formatTestEnd("Checkout Process", false, 5678));
166
-
167
- // Final summary
168
- console.log("\n" + formatter.formatHeader("Demo Complete!", "🎉"));
169
- console.log("\n✨ Your test logs now look AWESOME! ✨\n");
170
-
171
- await client.disconnect();
172
- console.log("\n" + formatter.formatConnection("disconnect"));
173
- } catch (error) {
174
- console.error(formatter.formatError("Demo failed", error));
175
- process.exit(1);
176
- }
177
- })();
@@ -1,96 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- /**
4
- * TestDriver SDK - Cache Thresholds Example
5
- *
6
- * This example demonstrates how to configure cache thresholds for different
7
- * operations and view cache debugging information.
8
- *
9
- * Run with VERBOSE=true to see cache hit/miss information:
10
- * TD_API_KEY=your_key VERBOSE=true node examples/sdk-cache-thresholds.js
11
- */
12
-
13
- const TestDriver = require("../sdk.js");
14
-
15
- (async () => {
16
- try {
17
- // Create client with custom cache thresholds
18
- const client = new TestDriver(process.env.TD_API_KEY, {
19
- os: "windows",
20
- logging: true,
21
- cacheThreshold: {
22
- find: 0.03, // 3% difference = 97% similarity required for cache hit
23
- findAll: 0.05, // 5% difference = 95% similarity required for cache hit
24
- },
25
- });
26
-
27
- console.log("\n=== TestDriver SDK - Cache Thresholds Demo ===\n");
28
- console.log("Cache thresholds configured:");
29
- console.log(" - find: 0.03 (97% similarity required)");
30
- console.log(" - findAll: 0.05 (95% similarity required)\n");
31
- console.log("You can also override thresholds per-command:");
32
- console.log(' await client.find("element", 0.01) // 99% similarity\n');
33
-
34
- // Connect to sandbox
35
- console.log("Connecting to sandbox...");
36
- await client.connect({ headless: true });
37
-
38
- // Open a test page
39
- console.log("Opening test page...");
40
- await client.focusApplication("Google Chrome");
41
- await client.type("https://example.com");
42
- await client.pressKeys(["enter"]);
43
-
44
- // Wait for page load
45
- await new Promise((resolve) => setTimeout(resolve, 3000));
46
-
47
- // Example 1: First find - should be a cache MISS
48
- console.log("\n--- First find (cache MISS expected) ---");
49
- const heading1 = await client.find("heading that says Example Domain");
50
-
51
- if (heading1.found()) {
52
- console.log(`✓ Element found at (${heading1.x}, ${heading1.y})`);
53
- }
54
-
55
- // Example 2: Second find - should be a cache HIT (same element, same screen)
56
- console.log("\n--- Second find (cache HIT expected) ---");
57
- // eslint-disable-next-line no-unused-vars
58
- const _heading2 = await client.find("heading that says Example Domain");
59
-
60
- // Example 3: Find with custom threshold override
61
- console.log("\n--- Find with strict threshold (0.01 = 99% similarity) ---");
62
- // eslint-disable-next-line no-unused-vars
63
- const _heading3 = await client.find(
64
- "heading that says Example Domain",
65
- 0.01,
66
- );
67
-
68
- // Example 4: Find a different element - cache MISS
69
- console.log("\n--- Finding different element (cache MISS expected) ---");
70
- // eslint-disable-next-line no-unused-vars
71
- const _paragraph = await client.find(
72
- "paragraph with text about illustrative examples",
73
- );
74
-
75
- // Example 5: Find the same paragraph again - cache HIT
76
- console.log("\n--- Finding same paragraph again (cache HIT expected) ---");
77
- // eslint-disable-next-line no-unused-vars
78
- const _paragraph2 = await client.find(
79
- "paragraph with text about illustrative examples",
80
- );
81
-
82
- console.log("\n=== Demo Complete ===");
83
- console.log(
84
- "\nNote: Run with VERBOSE=true to see detailed cache information:",
85
- );
86
- console.log(" - Cache hit/miss status");
87
- console.log(" - Cache strategy (image/text)");
88
- console.log(" - Similarity scores");
89
- console.log(" - Response times\n");
90
-
91
- await client.disconnect();
92
- } catch (error) {
93
- console.error("Test failed:", error);
94
- process.exit(1);
95
- }
96
- })();
@@ -1,155 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- /**
4
- * TestDriver SDK - Element Properties Example
5
- *
6
- * This example demonstrates accessing all available properties from located elements,
7
- * including coordinates, dimensions, confidence scores, screenshots, and more.
8
- */
9
-
10
- const TestDriverSDK = require("../sdk");
11
-
12
- (async () => {
13
- const client = new TestDriverSDK(process.env.TD_API_KEY);
14
-
15
- try {
16
- await client.connect();
17
-
18
- // Example 1: Basic coordinate properties
19
- console.log("=== Example 1: Basic Coordinates ===");
20
- const button = await client.find("the login button");
21
-
22
- if (button.found()) {
23
- console.log("Button found!");
24
- console.log(" X (top-left):", button.x);
25
- console.log(" Y (top-left):", button.y);
26
- console.log(" Center X:", button.centerX);
27
- console.log(" Center Y:", button.centerY);
28
- console.log(" Coordinates object:", button.getCoordinates());
29
- }
30
-
31
- // Example 2: Element dimensions
32
- console.log("\n=== Example 2: Element Dimensions ===");
33
- const input = await client.find("username input field");
34
-
35
- if (input.found()) {
36
- console.log("Input field found!");
37
- console.log(" Width:", input.width);
38
- console.log(" Height:", input.height);
39
-
40
- if (input.boundingBox) {
41
- console.log(" Bounding box:", input.boundingBox);
42
- }
43
- }
44
-
45
- // Example 3: Confidence and text data
46
- console.log("\n=== Example 3: Match Quality & Text ===");
47
- const link = await client.find("sign up link");
48
-
49
- if (link.found()) {
50
- console.log("Link found!");
51
- console.log(" Confidence score:", link.confidence);
52
- console.log(" Text content:", link.text);
53
- console.log(" Label:", link.label);
54
- }
55
-
56
- // Example 4: Screenshot data
57
- console.log("\n=== Example 4: Element Screenshot ===");
58
- const icon = await client.find("settings icon");
59
-
60
- if (icon.found() && icon.screenshot) {
61
- console.log("Icon found with screenshot!");
62
- console.log(" Screenshot (base64) length:", icon.screenshot.length);
63
-
64
- // You could save this to a file:
65
- // const fs = require('fs');
66
- // fs.writeFileSync('element.png', Buffer.from(icon.screenshot, 'base64'));
67
- }
68
-
69
- // Example 5: Full API response
70
- console.log("\n=== Example 5: Full API Response ===");
71
- const widget = await client.find("main content area");
72
-
73
- if (widget.found()) {
74
- const fullResponse = widget.getResponse();
75
- console.log("Full API response:", JSON.stringify(fullResponse, null, 2));
76
-
77
- // Log all available properties
78
- if (fullResponse) {
79
- console.log("\nAll available properties:");
80
- Object.keys(fullResponse).forEach((key) => {
81
- const value = fullResponse[key];
82
- const preview =
83
- typeof value === "string" && value.length > 50
84
- ? value.substring(0, 50) + "..."
85
- : value;
86
- console.log(` ${key}:`, preview);
87
- });
88
- }
89
- }
90
-
91
- // Example 6: Property-based validation
92
- console.log("\n=== Example 6: Property-based Validation ===");
93
- const message = await client.find("error message");
94
-
95
- if (message.found()) {
96
- // Check position
97
- if (message.centerY < 200) {
98
- console.log("✓ Error message is at top of screen");
99
- }
100
-
101
- // Check confidence
102
- if (message.confidence && message.confidence > 0.9) {
103
- console.log("✓ High confidence match (", message.confidence, ")");
104
- }
105
-
106
- // Check text content
107
- if (message.text) {
108
- console.log("✓ Message text:", message.text);
109
- }
110
- }
111
-
112
- // Example 7: Position-based logic
113
- console.log("\n=== Example 7: Position-based Logic ===");
114
- const menu = await client.find("dropdown menu");
115
-
116
- if (menu.found()) {
117
- // Calculate positions
118
- const offsetX = menu.x + 10;
119
- const offsetY = menu.y + 20;
120
- console.log("Menu position:", { x: menu.x, y: menu.y });
121
- console.log("Offset position:", { x: offsetX, y: offsetY });
122
-
123
- // Check if element is in viewport
124
- const viewportHeight = 768;
125
- if (menu.y > 0 && menu.y < viewportHeight) {
126
- console.log("✓ Element is visible in viewport");
127
- }
128
- }
129
-
130
- // Example 8: Conditional actions based on properties
131
- console.log("\n=== Example 8: Conditional Actions ===");
132
- const notification = await client.find("notification popup");
133
-
134
- if (notification.found()) {
135
- // Only interact if confidence is high
136
- if (notification.confidence && notification.confidence > 0.8) {
137
- console.log("High confidence, clicking notification");
138
- await notification.click();
139
- } else {
140
- console.log("Low confidence, skipping interaction");
141
- console.log("Debug info:", {
142
- coordinates: notification.getCoordinates(),
143
- confidence: notification.confidence,
144
- text: notification.text,
145
- });
146
- }
147
- }
148
-
149
- await client.disconnect();
150
- } catch (error) {
151
- console.error("Test failed:", error);
152
- await client.disconnect();
153
- process.exit(1);
154
- }
155
- })();
@@ -1,65 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- /**
4
- * TestDriver SDK - Simple Example with AWESOME Logs 🎨
5
- *
6
- * A straightforward example showing the beautiful logging in action.
7
- *
8
- * Run: TD_API_KEY=your_key node examples/sdk-simple-example.js
9
- */
10
-
11
- const TestDriver = require("../sdk.js");
12
-
13
- (async () => {
14
- try {
15
- // Create client with logging enabled (default)
16
- const client = new TestDriver(process.env.TD_API_KEY, {
17
- os: "windows",
18
- logging: true, // This enables the awesome logs!
19
- });
20
-
21
- console.log("\n🚀 Starting TestDriver SDK Example...\n");
22
-
23
- // Connect to sandbox - you'll see: 🔌 Connected
24
- await client.connect({ headless: true });
25
-
26
- // Navigate to a test page
27
- await client.focusApplication("Google Chrome");
28
- await client.type("https://example.com");
29
- await client.pressKeys(["enter"]);
30
-
31
- // Wait for page load
32
- await new Promise((resolve) => setTimeout(resolve, 3000));
33
-
34
- // Find an element - you'll see: 🔍 Found "heading..." · 📍 (x, y) · ⏱️ XXXms · ⚡ cached
35
- const heading = await client.find("heading that says Example Domain");
36
-
37
- if (heading.found()) {
38
- // Click the element - you'll see: 👆 Click "heading..."
39
- await heading.click();
40
- }
41
-
42
- // Find another element
43
- const link = await client.find("More information link");
44
-
45
- if (link.found()) {
46
- // Hover over it - you'll see: 👉 Hover "More information link"
47
- await link.hover();
48
- }
49
-
50
- // Scroll down - you'll see: 📜 Scroll
51
- await client.scroll("down", 300);
52
-
53
- // Take a screenshot - you'll see: 📸 Screenshot
54
- const screenshot = await client.screenshot();
55
- console.log(`\n📸 Screenshot captured (${screenshot.length} bytes)\n`);
56
-
57
- // Disconnect - you'll see: 🔌 Disconnected
58
- await client.disconnect();
59
-
60
- console.log("\n✅ Example completed successfully!\n");
61
- } catch (error) {
62
- console.error(`\n❌ Error: ${error.message}\n`);
63
- process.exit(1);
64
- }
65
- })();