testdriverai 7.1.0 → 7.1.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.
- package/.env.example +2 -0
- package/.github/workflows/linux-tests.yml +28 -0
- package/agent/index.js +18 -45
- package/agent/interface.js +13 -2
- package/agent/lib/commands.js +1 -1
- package/agent/lib/redraw.js +1 -1
- package/agent/lib/sandbox.js +30 -2
- package/agent/lib/valid-version.js +2 -2
- package/debugger/index.html +1 -1
- package/docs/docs.json +140 -131
- package/docs/v6/getting-started/self-hosting.mdx +3 -2
- package/docs/v7/_drafts/agents.mdx +852 -0
- package/docs/v7/_drafts/auto-cache-key.mdx +167 -0
- package/docs/v7/{guides → _drafts}/caching-selectors.mdx +125 -17
- package/docs/v7/_drafts/dashcam-title-feature.mdx +89 -0
- package/docs/v7/_drafts/error-handling.mdx +501 -0
- package/docs/v7/_drafts/implementation-plan.mdx +994 -0
- package/docs/v7/_drafts/init-command.mdx +95 -0
- package/docs/v7/_drafts/optimal-sdk-design.mdx +1348 -0
- package/docs/v7/_drafts/plugin-migration.mdx +222 -0
- package/docs/v7/_drafts/prompt-cache.mdx +200 -0
- package/docs/{QUICK_START_TEST_RECORDING.md → v7/_drafts/quick-start-test-recording.mdx} +3 -3
- package/docs/v7/_drafts/sdk-logging.mdx +222 -0
- package/docs/v7/_drafts/sdk-migration.mdx +474 -0
- package/docs/v7/_drafts/sdk-v7-complete.mdx +345 -0
- package/docs/v7/{guides → _drafts}/self-hosting.mdx +1 -1
- package/docs/v7/{guides → _drafts}/troubleshooting.mdx +2 -2
- package/docs/v7/{guides → _drafts}/vitest-plugin.mdx +4 -4
- package/docs/v7/api/{ai.mdx → act.mdx} +24 -24
- package/docs/v7/api/client.mdx +1 -1
- package/docs/v7/api/dashcam.mdx +2 -2
- package/docs/v7/api/elements.mdx +143 -41
- package/docs/v7/api/find.mdx +258 -0
- package/docs/v7/api/type.mdx +51 -7
- package/docs/v7/features/ai-native.mdx +427 -0
- package/docs/v7/features/easy-to-write.mdx +351 -0
- package/docs/v7/features/enterprise.mdx +540 -0
- package/docs/v7/features/fast.mdx +424 -0
- package/docs/v7/features/observable.mdx +623 -0
- package/docs/v7/features/powerful.mdx +531 -0
- package/docs/v7/features/scalable.mdx +417 -0
- package/docs/v7/features/stable.mdx +514 -0
- package/docs/v7/getting-started/configuration.mdx +1 -1
- package/docs/v7/getting-started/generating-tests.mdx +525 -0
- package/docs/v7/getting-started/installation.mdx +486 -0
- package/docs/v7/getting-started/quickstart.mdx +51 -5
- package/docs/v7/getting-started/running-and-debugging.mdx +511 -0
- package/docs/v7/getting-started/setting-up-in-ci.mdx +612 -0
- package/docs/v7/getting-started/writing-tests.mdx +535 -0
- package/docs/v7/overview/what-is-testdriver.mdx +398 -0
- package/docs/v7/playwright.mdx +3 -3
- package/docs/v7/presets/chrome.mdx +16 -0
- package/docs/v7/presets/electron.mdx +18 -0
- package/docs/v7/presets/vscode.mdx +19 -0
- package/examples/run-tests-with-recording.sh +70 -0
- package/examples/screenshot-example.js +63 -0
- package/examples/sdk-awesome-logs-demo.js +177 -0
- package/examples/sdk-cache-thresholds.js +96 -0
- package/examples/sdk-element-properties.js +155 -0
- package/examples/sdk-simple-example.js +65 -0
- package/examples/test-recording-example.test.js +166 -0
- package/interfaces/cli/commands/init.js +358 -0
- package/interfaces/vitest-plugin.mjs +214 -10
- package/{src → lib}/core/Dashcam.js +41 -4
- package/{src → lib}/vitest/hooks.mjs +118 -100
- package/lib/vitest/setup.mjs +44 -0
- package/package.json +9 -10
- package/sdk.d.ts +15 -2
- package/sdk.js +72 -17
- package/{self-hosted.yml → setup/aws/self-hosted.yml} +1 -1
- package/{testdriver/acceptance-sdk → test/manual}/test-console-logs.test.mjs +1 -1
- package/test/manual/test-find-api.js +73 -0
- package/test/manual/test-init.sh +54 -0
- package/test/manual/test-prompt-cache.js +96 -0
- package/test/manual/test-provision-auth.mjs +22 -0
- package/test/manual/test-sandbox-render.js +28 -0
- package/test/manual/test-sdk-methods.js +15 -0
- package/test/manual/test-sdk-refactor.js +53 -0
- package/test/manual/test-stack-trace.mjs +57 -0
- package/test/testdriver/assert.test.mjs +41 -0
- package/{testdriver/acceptance-sdk → test/testdriver}/auto-cache-key-demo.test.mjs +1 -1
- package/{testdriver/acceptance-sdk → test/testdriver}/drag-and-drop.test.mjs +1 -1
- package/{testdriver/acceptance-sdk → test/testdriver}/element-not-found.test.mjs +1 -1
- package/{testdriver/acceptance-sdk → test/testdriver}/exec-js.test.mjs +1 -1
- package/{testdriver/acceptance-sdk → test/testdriver}/exec-output.test.mjs +3 -3
- package/{testdriver/acceptance-sdk → test/testdriver}/exec-pwsh.test.mjs +3 -3
- package/{testdriver/acceptance-sdk → test/testdriver}/focus-window.test.mjs +1 -1
- package/{testdriver/acceptance-sdk → test/testdriver}/formatted-logging.test.mjs +1 -1
- package/{testdriver/acceptance-sdk → test/testdriver}/hover-image.test.mjs +1 -1
- package/{testdriver/acceptance-sdk → test/testdriver}/hover-text-with-description.test.mjs +1 -1
- package/{testdriver/acceptance-sdk → test/testdriver}/hover-text.test.mjs +1 -1
- package/{testdriver/acceptance-sdk → test/testdriver}/match-image.test.mjs +1 -1
- package/{testdriver/acceptance-sdk → test/testdriver}/press-keys.test.mjs +1 -1
- package/{testdriver/acceptance-sdk → test/testdriver}/prompt.test.mjs +2 -2
- package/{testdriver/acceptance-sdk → test/testdriver}/scroll-keyboard.test.mjs +1 -1
- package/{testdriver/acceptance-sdk → test/testdriver}/scroll-until-image.test.mjs +1 -1
- package/{testdriver/acceptance-sdk → test/testdriver}/scroll-until-text.test.mjs +1 -1
- package/{testdriver/acceptance-sdk → test/testdriver}/scroll.test.mjs +1 -1
- package/{src/vitest/lifecycle.mjs → test/testdriver/setup/lifecycleHelpers.mjs} +84 -99
- package/test/testdriver/setup/testHelpers.mjs +653 -0
- package/{testdriver/acceptance-sdk → test/testdriver}/type.test.mjs +1 -1
- package/vitest.config.mjs +8 -59
- package/.github/dependabot.yml +0 -11
- package/.github/workflows/acceptance-linux.yml +0 -75
- package/.github/workflows/acceptance-sdk-tests.yml +0 -133
- package/.github/workflows/acceptance-tests.yml +0 -130
- package/.github/workflows/lint.yml +0 -27
- package/.github/workflows/publish-canary.yml +0 -40
- package/.github/workflows/publish-latest.yml +0 -61
- package/.github/workflows/test-install.yml +0 -29
- package/.vscode/extensions.json +0 -3
- package/.vscode/launch.json +0 -22
- package/.vscode/settings.json +0 -14
- package/AGENTS.md +0 -550
- package/CODEOWNERS +0 -2
- package/_testdriver/acceptance/assert.yaml +0 -7
- package/_testdriver/acceptance/dashcam.yaml +0 -9
- package/_testdriver/acceptance/drag-and-drop.yaml +0 -49
- package/_testdriver/acceptance/embed.yaml +0 -9
- package/_testdriver/acceptance/exec-js.yaml +0 -29
- package/_testdriver/acceptance/exec-output.yaml +0 -43
- package/_testdriver/acceptance/exec-shell.yaml +0 -40
- package/_testdriver/acceptance/focus-window.yaml +0 -16
- package/_testdriver/acceptance/hover-image.yaml +0 -18
- package/_testdriver/acceptance/hover-text-with-description.yaml +0 -29
- package/_testdriver/acceptance/hover-text.yaml +0 -14
- package/_testdriver/acceptance/if-else.yaml +0 -31
- package/_testdriver/acceptance/match-image.yaml +0 -15
- package/_testdriver/acceptance/press-keys.yaml +0 -35
- package/_testdriver/acceptance/prompt.yaml +0 -11
- package/_testdriver/acceptance/remember.yaml +0 -27
- package/_testdriver/acceptance/screenshots/cart.png +0 -0
- package/_testdriver/acceptance/scroll-keyboard.yaml +0 -34
- package/_testdriver/acceptance/scroll-until-image.yaml +0 -26
- package/_testdriver/acceptance/scroll-until-text.yaml +0 -20
- package/_testdriver/acceptance/scroll.yaml +0 -33
- package/_testdriver/acceptance/snippets/login.yaml +0 -29
- package/_testdriver/acceptance/snippets/match-cart.yaml +0 -8
- package/_testdriver/acceptance/type.yaml +0 -29
- package/_testdriver/behavior/failure.yaml +0 -7
- package/_testdriver/behavior/hover-text.yaml +0 -13
- package/_testdriver/behavior/lifecycle/postrun.yaml +0 -10
- package/_testdriver/behavior/lifecycle/prerun.yaml +0 -8
- package/_testdriver/behavior/lifecycle/provision.yaml +0 -8
- package/_testdriver/behavior/secrets.yaml +0 -7
- package/_testdriver/edge-cases/dashcam-chrome.yaml +0 -8
- package/_testdriver/edge-cases/exec-pwsh-multiline.yaml +0 -10
- package/_testdriver/edge-cases/js-exception.yaml +0 -8
- package/_testdriver/edge-cases/js-promise.yaml +0 -19
- package/_testdriver/edge-cases/lifecycle/postrun.yaml +0 -10
- package/_testdriver/edge-cases/prompt-in-middle.yaml +0 -23
- package/_testdriver/edge-cases/prompt-nested.yaml +0 -7
- package/_testdriver/edge-cases/success-test.yaml +0 -9
- package/_testdriver/examples/android/example.yaml +0 -12
- package/_testdriver/examples/android/lifecycle/postrun.yaml +0 -11
- package/_testdriver/examples/android/lifecycle/provision.yaml +0 -47
- package/_testdriver/examples/android/readme.md +0 -7
- package/_testdriver/examples/chrome-extension/lifecycle/provision.yaml +0 -74
- package/_testdriver/examples/desktop/lifecycle/prerun.yaml +0 -0
- package/_testdriver/examples/desktop/lifecycle/provision.yaml +0 -64
- package/_testdriver/examples/vscode-extension/lifecycle/provision.yaml +0 -73
- package/_testdriver/examples/web/lifecycle/postrun.yaml +0 -7
- package/_testdriver/examples/web/lifecycle/prerun.yaml +0 -22
- package/_testdriver/lifecycle/postrun.yaml +0 -8
- package/_testdriver/lifecycle/prerun.yaml +0 -15
- package/_testdriver/lifecycle/provision.yaml +0 -25
- package/docs/v7/guides/ci-cd/azure.mdx +0 -587
- package/docs/v7/guides/ci-cd/circleci.mdx +0 -523
- package/docs/v7/guides/ci-cd/github-actions.mdx +0 -457
- package/docs/v7/guides/ci-cd/gitlab.mdx +0 -498
- package/docs/v7/guides/ci-cd/jenkins.mdx +0 -664
- package/docs/v7/guides/ci-cd/travis.mdx +0 -438
- package/scripts/view-test-results.mjs +0 -96
- package/src/vitest/extended.mjs +0 -108
- package/src/vitest/index.mjs +0 -64
- package/src/vitest/utils.mjs +0 -150
- package/styles/.vale-config/2-MDX.ini +0 -5
- package/styles/Microsoft/AMPM.yml +0 -9
- package/styles/Microsoft/Accessibility.yml +0 -30
- package/styles/Microsoft/Acronyms.yml +0 -64
- package/styles/Microsoft/Adverbs.yml +0 -272
- package/styles/Microsoft/Auto.yml +0 -11
- package/styles/Microsoft/Avoid.yml +0 -14
- package/styles/Microsoft/Contractions.yml +0 -50
- package/styles/Microsoft/Dashes.yml +0 -13
- package/styles/Microsoft/DateFormat.yml +0 -8
- package/styles/Microsoft/DateNumbers.yml +0 -40
- package/styles/Microsoft/DateOrder.yml +0 -8
- package/styles/Microsoft/Ellipses.yml +0 -9
- package/styles/Microsoft/FirstPerson.yml +0 -16
- package/styles/Microsoft/Foreign.yml +0 -13
- package/styles/Microsoft/Gender.yml +0 -8
- package/styles/Microsoft/GenderBias.yml +0 -42
- package/styles/Microsoft/GeneralURL.yml +0 -11
- package/styles/Microsoft/HeadingAcronyms.yml +0 -7
- package/styles/Microsoft/HeadingColons.yml +0 -8
- package/styles/Microsoft/HeadingPunctuation.yml +0 -13
- package/styles/Microsoft/Headings.yml +0 -28
- package/styles/Microsoft/Hyphens.yml +0 -14
- package/styles/Microsoft/Negative.yml +0 -13
- package/styles/Microsoft/Ordinal.yml +0 -13
- package/styles/Microsoft/OxfordComma.yml +0 -8
- package/styles/Microsoft/Passive.yml +0 -183
- package/styles/Microsoft/Percentages.yml +0 -7
- package/styles/Microsoft/Plurals.yml +0 -7
- package/styles/Microsoft/Quotes.yml +0 -7
- package/styles/Microsoft/RangeTime.yml +0 -13
- package/styles/Microsoft/Semicolon.yml +0 -8
- package/styles/Microsoft/SentenceLength.yml +0 -6
- package/styles/Microsoft/Spacing.yml +0 -8
- package/styles/Microsoft/Suspended.yml +0 -7
- package/styles/Microsoft/Terms.yml +0 -42
- package/styles/Microsoft/URLFormat.yml +0 -9
- package/styles/Microsoft/Units.yml +0 -16
- package/styles/Microsoft/Vocab.yml +0 -25
- package/styles/Microsoft/We.yml +0 -11
- package/styles/Microsoft/Wordiness.yml +0 -127
- package/styles/Microsoft/meta.json +0 -4
- package/styles/alex/Ablist.yml +0 -274
- package/styles/alex/Condescending.yml +0 -16
- package/styles/alex/Gendered.yml +0 -110
- package/styles/alex/LGBTQ.yml +0 -55
- package/styles/alex/OCD.yml +0 -10
- package/styles/alex/Press.yml +0 -12
- package/styles/alex/ProfanityLikely.yml +0 -1289
- package/styles/alex/ProfanityMaybe.yml +0 -282
- package/styles/alex/ProfanityUnlikely.yml +0 -251
- package/styles/alex/README.md +0 -27
- package/styles/alex/Race.yml +0 -85
- package/styles/alex/Suicide.yml +0 -26
- package/styles/alex/meta.json +0 -4
- package/styles/config/vocabularies/Docs/accept.txt +0 -47
- package/styles/config/vocabularies/Docs/reject.txt +0 -4
- package/styles/proselint/Airlinese.yml +0 -8
- package/styles/proselint/AnimalLabels.yml +0 -48
- package/styles/proselint/Annotations.yml +0 -9
- package/styles/proselint/Apologizing.yml +0 -8
- package/styles/proselint/Archaisms.yml +0 -52
- package/styles/proselint/But.yml +0 -8
- package/styles/proselint/Cliches.yml +0 -782
- package/styles/proselint/CorporateSpeak.yml +0 -30
- package/styles/proselint/Currency.yml +0 -5
- package/styles/proselint/Cursing.yml +0 -15
- package/styles/proselint/DateCase.yml +0 -7
- package/styles/proselint/DateMidnight.yml +0 -7
- package/styles/proselint/DateRedundancy.yml +0 -10
- package/styles/proselint/DateSpacing.yml +0 -7
- package/styles/proselint/DenizenLabels.yml +0 -52
- package/styles/proselint/Diacritical.yml +0 -95
- package/styles/proselint/GenderBias.yml +0 -45
- package/styles/proselint/GroupTerms.yml +0 -39
- package/styles/proselint/Hedging.yml +0 -8
- package/styles/proselint/Hyperbole.yml +0 -6
- package/styles/proselint/Jargon.yml +0 -11
- package/styles/proselint/LGBTOffensive.yml +0 -13
- package/styles/proselint/LGBTTerms.yml +0 -15
- package/styles/proselint/Malapropisms.yml +0 -8
- package/styles/proselint/Needless.yml +0 -358
- package/styles/proselint/Nonwords.yml +0 -38
- package/styles/proselint/Oxymorons.yml +0 -22
- package/styles/proselint/P-Value.yml +0 -6
- package/styles/proselint/RASSyndrome.yml +0 -30
- package/styles/proselint/README.md +0 -12
- package/styles/proselint/Skunked.yml +0 -13
- package/styles/proselint/Spelling.yml +0 -17
- package/styles/proselint/Typography.yml +0 -11
- package/styles/proselint/Uncomparables.yml +0 -50
- package/styles/proselint/Very.yml +0 -6
- package/styles/proselint/meta.json +0 -15
- package/styles/write-good/Cliches.yml +0 -702
- package/styles/write-good/E-Prime.yml +0 -32
- package/styles/write-good/Illusions.yml +0 -11
- package/styles/write-good/Passive.yml +0 -183
- package/styles/write-good/README.md +0 -27
- package/styles/write-good/So.yml +0 -5
- package/styles/write-good/ThereIs.yml +0 -6
- package/styles/write-good/TooWordy.yml +0 -221
- package/styles/write-good/Weasel.yml +0 -29
- package/styles/write-good/meta.json +0 -4
- package/test/dashcam.test.js +0 -137
- package/test/mcp-example-test.yaml +0 -27
- package/test/test_parser.js +0 -47
- package/testdriver/acceptance-sdk/QUICK_REFERENCE.md +0 -61
- package/testdriver/acceptance-sdk/README.md +0 -128
- package/testdriver/acceptance-sdk/TEST_REPORTING.md +0 -245
- package/testdriver/acceptance-sdk/assert.test.mjs +0 -26
- package/testdriver/acceptance-sdk/hooks-example.test.mjs +0 -38
- package/testdriver/acceptance-sdk/presets-example.test.mjs +0 -87
- package/testdriver/acceptance-sdk/setup/testHelpers.mjs +0 -420
- package/testdriver/acceptance-sdk/sully-ai.test.mjs +0 -234
- package/testdriver/acceptance-sdk/type-checking-demo.js +0 -49
- package/vale.ini +0 -18
- package/vitest.config.example.js +0 -19
- package/vitest.config.mjs.bak +0 -44
- /package/docs/{ARCHITECTURE.md → v7/_drafts/architecture.mdx} +0 -0
- /package/docs/{AWESOME_LOGS_QUICK_REF.md → v7/_drafts/awesome-logs-quick-ref.mdx} +0 -0
- /package/docs/v7/{guides → _drafts}/best-practices.mdx +0 -0
- /package/docs/v7/{guides → _drafts}/caching-ai.mdx +0 -0
- /package/docs/v7/{guides → _drafts}/caching.mdx +0 -0
- /package/docs/{MIGRATION.md → v7/_drafts/cli-to-sdk-migration.mdx} +0 -0
- /package/{CONTRIBUTING.md → docs/v7/_drafts/contributing.mdx} +0 -0
- /package/docs/v7/{progressive-apis/CORE.md → _drafts/core.mdx} +0 -0
- /package/docs/v7/{guides → _drafts}/debugging.mdx +0 -0
- /package/docs/v7/{guides → _drafts}/faq.mdx +0 -0
- /package/docs/v7/{progressive-apis/HOOKS.md → _drafts/hooks.mdx} +0 -0
- /package/docs/v7/{guides → _drafts}/migration.mdx +0 -0
- /package/docs/v7/{guides → _drafts}/performance.mdx +0 -0
- /package/docs/{PRESETS.md → v7/_drafts/presets.mdx} +0 -0
- /package/docs/v7/{progressive-apis/PROGRESSIVE_DISCLOSURE.md → _drafts/progressive-disclosure.mdx} +0 -0
- /package/docs/v7/{progressive-apis/PROVISION.md → _drafts/provision.mdx} +0 -0
- /package/docs/{SDK_AWESOME_LOGS.md → v7/_drafts/sdk-awesome-logs.mdx} +0 -0
- /package/docs/{sdk-browser-rendering.md → v7/_drafts/sdk-browser-rendering.mdx} +0 -0
- /package/docs/{TEST_RECORDING.md → v7/_drafts/test-recording.mdx} +0 -0
- /package/docs/v7/{guides → _drafts}/vitest.mdx +0 -0
- /package/docs/v7/{README.md → overview/readme.mdx} +0 -0
- /package/{src → lib}/core/index.d.ts +0 -0
- /package/{src → lib}/core/index.js +0 -0
- /package/{src → lib}/presets/index.mjs +0 -0
- /package/{src → lib}/vitest/hooks.d.ts +0 -0
- /package/{debug-locate-response.js → test/manual/debug-locate-response.js} +0 -0
- /package/{verify-element-api.js → test/manual/verify-element-api.js} +0 -0
- /package/{verify-types.js → test/manual/verify-types.js} +0 -0
- /package/{testdriver/acceptance-sdk → test/testdriver}/chrome-extension.test.mjs +0 -0
- /package/{testdriver/acceptance-sdk → test/testdriver}/setup/globalTeardown.mjs +0 -0
- /package/{testdriver/acceptance-sdk → test/testdriver}/setup/vitestSetup.mjs +0 -0
package/sdk.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
|
|
1
|
+
// Auto-load environment variables from .env file if it exists
|
|
2
|
+
require("dotenv").config();
|
|
2
3
|
|
|
3
4
|
const fs = require("fs");
|
|
4
5
|
const path = require("path");
|
|
@@ -1123,8 +1124,8 @@ class TestDriverSDK {
|
|
|
1123
1124
|
? options.redrawThreshold
|
|
1124
1125
|
: { diffThreshold: options.redrawThreshold };
|
|
1125
1126
|
} else {
|
|
1126
|
-
// Default:
|
|
1127
|
-
this.redrawOptions = { enabled:
|
|
1127
|
+
// Default: enabled (as of v7.2)
|
|
1128
|
+
this.redrawOptions = { enabled: true };
|
|
1128
1129
|
}
|
|
1129
1130
|
// Keep redrawThreshold for backwards compatibility in connect()
|
|
1130
1131
|
this.redrawThreshold = this.redrawOptions;
|
|
@@ -1178,7 +1179,7 @@ class TestDriverSDK {
|
|
|
1178
1179
|
*/
|
|
1179
1180
|
get dashcam() {
|
|
1180
1181
|
if (!this._dashcam) {
|
|
1181
|
-
const { Dashcam } = require("./
|
|
1182
|
+
const { Dashcam } = require("./lib/core/index.js");
|
|
1182
1183
|
// Don't pass apiKey - let Dashcam use its default key
|
|
1183
1184
|
this._dashcam = new Dashcam(this);
|
|
1184
1185
|
}
|
|
@@ -1222,6 +1223,19 @@ class TestDriverSDK {
|
|
|
1222
1223
|
|
|
1223
1224
|
// If dashcam is available and recording, add web logs for this domain
|
|
1224
1225
|
if (this._dashcam) {
|
|
1226
|
+
|
|
1227
|
+
// Create the log file on the remote machine
|
|
1228
|
+
const shell = this.os === "windows" ? "pwsh" : "sh";
|
|
1229
|
+
const logPath = this.os === "windows"
|
|
1230
|
+
? "C:\\Users\\testdriver\\Documents\\testdriver.log"
|
|
1231
|
+
: "/tmp/testdriver.log";
|
|
1232
|
+
|
|
1233
|
+
const createLogCmd = this.os === "windows"
|
|
1234
|
+
? `New-Item -ItemType File -Path "${logPath}" -Force | Out-Null`
|
|
1235
|
+
: `touch ${logPath}`;
|
|
1236
|
+
|
|
1237
|
+
await this.exec(shell, createLogCmd, 10000, true);
|
|
1238
|
+
|
|
1225
1239
|
console.log('[provision.chrome] Adding web logs to dashcam...');
|
|
1226
1240
|
try {
|
|
1227
1241
|
const urlObj = new URL(url);
|
|
@@ -1229,6 +1243,9 @@ class TestDriverSDK {
|
|
|
1229
1243
|
const pattern = `*${domain}*`;
|
|
1230
1244
|
await this._dashcam.addWebLog(pattern, 'Web Logs');
|
|
1231
1245
|
console.log(`[provision.chrome] ✅ Web logs added to dashcam (pattern: ${pattern})`);
|
|
1246
|
+
|
|
1247
|
+
await this._dashcam.addFileLog(logPath, "TestDriver Log");
|
|
1248
|
+
|
|
1232
1249
|
} catch (error) {
|
|
1233
1250
|
console.warn('[provision.chrome] ⚠️ Failed to add web logs:', error.message);
|
|
1234
1251
|
}
|
|
@@ -1472,6 +1489,9 @@ class TestDriverSDK {
|
|
|
1472
1489
|
this.agent.sandboxOs = connectOptions.os;
|
|
1473
1490
|
} else if (this.sandboxOs) {
|
|
1474
1491
|
this.agent.sandboxOs = this.sandboxOs;
|
|
1492
|
+
} else {
|
|
1493
|
+
// Fall back to this.os (which defaults to "linux")
|
|
1494
|
+
this.agent.sandboxOs = this.os;
|
|
1475
1495
|
}
|
|
1476
1496
|
|
|
1477
1497
|
// Set redrawThreshold on agent's cliArgs.options
|
|
@@ -1506,13 +1526,8 @@ class TestDriverSDK {
|
|
|
1506
1526
|
this._setupCommandMethods();
|
|
1507
1527
|
|
|
1508
1528
|
this.connected = true;
|
|
1509
|
-
|
|
1510
|
-
// Expose whether we reconnected to an existing sandbox or created a new one
|
|
1511
|
-
this.isReconnected = this.agent.isReconnected || false;
|
|
1512
|
-
|
|
1513
1529
|
this.analytics.track("sdk.connect", {
|
|
1514
1530
|
sandboxId: this.instance?.instanceId,
|
|
1515
|
-
isReconnected: this.isReconnected,
|
|
1516
1531
|
});
|
|
1517
1532
|
|
|
1518
1533
|
return this.instance;
|
|
@@ -1525,13 +1540,19 @@ class TestDriverSDK {
|
|
|
1525
1540
|
* @returns {Promise<void>}
|
|
1526
1541
|
*/
|
|
1527
1542
|
async disconnect() {
|
|
1543
|
+
// Track disconnect event if we were connected
|
|
1528
1544
|
if (this.connected && this.instance) {
|
|
1529
|
-
// Track disconnect event
|
|
1530
1545
|
this.analytics.track("sdk.disconnect");
|
|
1546
|
+
}
|
|
1531
1547
|
|
|
1532
|
-
|
|
1533
|
-
|
|
1548
|
+
// Always close the sandbox WebSocket connection to clean up resources
|
|
1549
|
+
// This ensures we don't leave orphaned connections even if connect() failed
|
|
1550
|
+
if (this.sandbox && typeof this.sandbox.close === 'function') {
|
|
1551
|
+
this.sandbox.close();
|
|
1534
1552
|
}
|
|
1553
|
+
|
|
1554
|
+
this.connected = false;
|
|
1555
|
+
this.instance = null;
|
|
1535
1556
|
}
|
|
1536
1557
|
|
|
1537
1558
|
/**
|
|
@@ -2197,6 +2218,9 @@ class TestDriverSDK {
|
|
|
2197
2218
|
* @private
|
|
2198
2219
|
*/
|
|
2199
2220
|
_setupLogging() {
|
|
2221
|
+
// Track the last fatal error message to throw on exit
|
|
2222
|
+
let lastFatalError = null;
|
|
2223
|
+
|
|
2200
2224
|
// Set up markdown logger
|
|
2201
2225
|
createMarkdownLogger(this.emitter);
|
|
2202
2226
|
|
|
@@ -2219,6 +2243,11 @@ class TestDriverSDK {
|
|
|
2219
2243
|
if (this.loggingEnabled) {
|
|
2220
2244
|
const event = this.emitter.event;
|
|
2221
2245
|
console.error(event, ":", data);
|
|
2246
|
+
|
|
2247
|
+
// Capture fatal errors
|
|
2248
|
+
if (event === events.error.fatal) {
|
|
2249
|
+
lastFatalError = data;
|
|
2250
|
+
}
|
|
2222
2251
|
}
|
|
2223
2252
|
});
|
|
2224
2253
|
|
|
@@ -2245,6 +2274,19 @@ class TestDriverSDK {
|
|
|
2245
2274
|
}
|
|
2246
2275
|
});
|
|
2247
2276
|
|
|
2277
|
+
// Handle exit events - throw error with meaningful message instead of calling process.exit
|
|
2278
|
+
// This allows test frameworks like Vitest to properly catch and display the error
|
|
2279
|
+
this.emitter.on(events.exit, (exitCode) => {
|
|
2280
|
+
if (exitCode !== 0) {
|
|
2281
|
+
// Create an error with the fatal error message if available
|
|
2282
|
+
const errorMessage = lastFatalError || 'TestDriver fatal error';
|
|
2283
|
+
const error = new Error(errorMessage);
|
|
2284
|
+
error.name = 'TestDriverFatalError';
|
|
2285
|
+
error.exitCode = exitCode;
|
|
2286
|
+
throw error;
|
|
2287
|
+
}
|
|
2288
|
+
});
|
|
2289
|
+
|
|
2248
2290
|
// Handle show window events for sandbox visualization
|
|
2249
2291
|
this.emitter.on("show-window", async (url) => {
|
|
2250
2292
|
if (this.loggingEnabled) {
|
|
@@ -2380,7 +2422,7 @@ class TestDriverSDK {
|
|
|
2380
2422
|
);
|
|
2381
2423
|
await sdk.auth();
|
|
2382
2424
|
|
|
2383
|
-
const platform = options.platform || this.config.TD_PLATFORM || "
|
|
2425
|
+
const platform = options.platform || this.config.TD_PLATFORM || "linux";
|
|
2384
2426
|
|
|
2385
2427
|
// Auto-detect sandbox ID from the active sandbox if not provided
|
|
2386
2428
|
const sandboxId = options.sandboxId || this.agent?.sandbox?.id || null;
|
|
@@ -2545,21 +2587,34 @@ class TestDriverSDK {
|
|
|
2545
2587
|
*
|
|
2546
2588
|
* @example
|
|
2547
2589
|
* // Simple execution
|
|
2548
|
-
* await client.
|
|
2590
|
+
* await client.act('Click the submit button');
|
|
2549
2591
|
*
|
|
2550
2592
|
* @example
|
|
2551
2593
|
* // With validation loop
|
|
2552
|
-
* const result = await client.
|
|
2594
|
+
* const result = await client.act('Fill out the contact form', { validateAndLoop: true });
|
|
2553
2595
|
* console.log(result); // AI's final assessment
|
|
2554
2596
|
*/
|
|
2555
|
-
async
|
|
2597
|
+
async act(task) {
|
|
2556
2598
|
this._ensureConnected();
|
|
2557
2599
|
|
|
2558
|
-
this.analytics.track("sdk.
|
|
2600
|
+
this.analytics.track("sdk.act", { task });
|
|
2559
2601
|
|
|
2560
2602
|
// Use the agent's exploratoryLoop method directly
|
|
2561
2603
|
return await this.agent.exploratoryLoop(task, false, true, false);
|
|
2562
2604
|
}
|
|
2605
|
+
|
|
2606
|
+
/**
|
|
2607
|
+
* @deprecated Use act() instead
|
|
2608
|
+
* Execute a natural language task using AI
|
|
2609
|
+
*
|
|
2610
|
+
* @param {string} task - Natural language description of what to do
|
|
2611
|
+
* @param {Object} options - Execution options
|
|
2612
|
+
* @param {boolean} [options.validateAndLoop=false] - Whether to validate completion and retry if incomplete
|
|
2613
|
+
* @returns {Promise<string|void>} Final AI response if validateAndLoop is true
|
|
2614
|
+
*/
|
|
2615
|
+
async ai(task) {
|
|
2616
|
+
return await this.act(task);
|
|
2617
|
+
}
|
|
2563
2618
|
}
|
|
2564
2619
|
|
|
2565
2620
|
module.exports = TestDriverSDK;
|
|
@@ -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-
|
|
81
|
+
AMI_ID: ami-086b5b4b86d78987c
|
|
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
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import { describe, expect, it } from "vitest";
|
|
7
|
-
import { TestDriver } from "../../
|
|
7
|
+
import { TestDriver } from "../../lib/vitest/hooks.mjs";
|
|
8
8
|
|
|
9
9
|
describe("Console Log Test", () => {
|
|
10
10
|
it("should capture console logs and send them to dashcam", async (context) => {
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Quick test of the new find() API
|
|
5
|
+
* This is a simple smoke test to verify the Element class works
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const TestDriver = require("../sdk");
|
|
9
|
+
|
|
10
|
+
async function testFindAPI() {
|
|
11
|
+
console.log("Testing new find() API...\n");
|
|
12
|
+
|
|
13
|
+
const client = new TestDriver("test-key", {
|
|
14
|
+
logging: false,
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
// Test 1: Create element without connecting
|
|
18
|
+
console.log("✓ Test 1: Creating Element instance");
|
|
19
|
+
const element = client.find("test element");
|
|
20
|
+
console.log(" Element description:", element.description);
|
|
21
|
+
console.log(" Element found():", element.found());
|
|
22
|
+
console.log(" Element coordinates:", element.getCoordinates());
|
|
23
|
+
|
|
24
|
+
// Test 2: Verify element methods exist
|
|
25
|
+
console.log("\n✓ Test 2: Verifying Element methods");
|
|
26
|
+
console.log(" Has find():", typeof element.find === "function");
|
|
27
|
+
console.log(" Has click():", typeof element.click === "function");
|
|
28
|
+
console.log(" Has hover():", typeof element.hover === "function");
|
|
29
|
+
console.log(
|
|
30
|
+
" Has doubleClick():",
|
|
31
|
+
typeof element.doubleClick === "function",
|
|
32
|
+
);
|
|
33
|
+
console.log(" Has rightClick():", typeof element.rightClick === "function");
|
|
34
|
+
console.log(" Has mouseDown():", typeof element.mouseDown === "function");
|
|
35
|
+
console.log(" Has mouseUp():", typeof element.mouseUp === "function");
|
|
36
|
+
console.log(" Has found():", typeof element.found === "function");
|
|
37
|
+
console.log(
|
|
38
|
+
" Has getCoordinates():",
|
|
39
|
+
typeof element.getCoordinates === "function",
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
// Test 3: Verify error handling for clicking unfound element
|
|
43
|
+
console.log("\n✓ Test 3: Error handling for unfound element");
|
|
44
|
+
try {
|
|
45
|
+
await element.click();
|
|
46
|
+
console.log(" ❌ Should have thrown error");
|
|
47
|
+
} catch (error) {
|
|
48
|
+
console.log(" ✓ Correctly throws error:", error.message);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Test 4: Verify TypeScript types exist (if running from TypeScript)
|
|
52
|
+
console.log("\n✓ Test 4: SDK methods");
|
|
53
|
+
console.log(" Has find():", typeof client.find === "function");
|
|
54
|
+
console.log(
|
|
55
|
+
" Has deprecated hoverText():",
|
|
56
|
+
typeof client.hoverText === "undefined" ? "not yet connected" : "exists",
|
|
57
|
+
);
|
|
58
|
+
console.log(
|
|
59
|
+
" Has deprecated waitForText():",
|
|
60
|
+
typeof client.waitForText === "undefined" ? "not yet connected" : "exists",
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
console.log("\n✅ All basic tests passed!");
|
|
64
|
+
console.log(
|
|
65
|
+
"\nNote: Full integration tests require connection to TestDriver sandbox.",
|
|
66
|
+
);
|
|
67
|
+
console.log("See examples/sdk-find-example.js for complete usage examples.");
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
testFindAPI().catch((error) => {
|
|
71
|
+
console.error("Test failed:", error);
|
|
72
|
+
process.exit(1);
|
|
73
|
+
});
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# Test script for the init command
|
|
4
|
+
# Usage: ./test-init.sh
|
|
5
|
+
|
|
6
|
+
set -e
|
|
7
|
+
|
|
8
|
+
echo "🧪 Testing testdriverai init command..."
|
|
9
|
+
echo ""
|
|
10
|
+
|
|
11
|
+
# Cleanup function
|
|
12
|
+
cleanup() {
|
|
13
|
+
echo "🧹 Cleaning up test directories..."
|
|
14
|
+
rm -rf /tmp/testdriver-test-*
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
trap cleanup EXIT
|
|
18
|
+
|
|
19
|
+
# Test 1: Full init with all features
|
|
20
|
+
echo "1️⃣ Testing full initialization (package.json, tests, workflow, npm install)..."
|
|
21
|
+
cd /tmp
|
|
22
|
+
mkdir -p testdriver-test-init
|
|
23
|
+
cd testdriver-test-init
|
|
24
|
+
node /Users/ianjennings/Development/cli/bin/testdriverai.js init
|
|
25
|
+
echo ""
|
|
26
|
+
echo "✅ Files created:"
|
|
27
|
+
find . -type f -not -path "./node_modules/*" | sort
|
|
28
|
+
echo ""
|
|
29
|
+
echo "📄 package.json:"
|
|
30
|
+
cat package.json
|
|
31
|
+
echo ""
|
|
32
|
+
echo "📄 vitest.config.js:"
|
|
33
|
+
cat vitest.config.js
|
|
34
|
+
echo ""
|
|
35
|
+
echo "📄 GitHub workflow:"
|
|
36
|
+
cat .github/workflows/testdriver.yml
|
|
37
|
+
echo ""
|
|
38
|
+
echo "📄 First 15 lines of tests/example.test.js:"
|
|
39
|
+
head -15 tests/example.test.js
|
|
40
|
+
echo ""
|
|
41
|
+
echo "📦 Installed dependencies:"
|
|
42
|
+
npm list --depth=0
|
|
43
|
+
echo ""
|
|
44
|
+
echo "---"
|
|
45
|
+
echo ""
|
|
46
|
+
|
|
47
|
+
# Test 2: Help command
|
|
48
|
+
echo "2️⃣ Testing help command..."
|
|
49
|
+
node /Users/ianjennings/Development/cli/bin/testdriverai.js init --help
|
|
50
|
+
echo ""
|
|
51
|
+
echo "---"
|
|
52
|
+
echo ""
|
|
53
|
+
|
|
54
|
+
echo "✅ All tests passed!"
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Simple test to verify prompt caching functionality
|
|
5
|
+
*
|
|
6
|
+
* This test demonstrates that:
|
|
7
|
+
* 1. First .prompt() call makes an API request and caches the YAML response
|
|
8
|
+
* 2. Second .prompt() call with the same prompt uses the cached YAML
|
|
9
|
+
* 3. Cache can be disabled with TD_NO_PROMPT_CACHE=true
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
const TestDriver = require("./sdk.js");
|
|
13
|
+
const promptCache = require("./agent/lib/cache.js");
|
|
14
|
+
|
|
15
|
+
async function testPromptCache() {
|
|
16
|
+
console.log("Testing prompt caching functionality...\n");
|
|
17
|
+
|
|
18
|
+
const client = new TestDriver(process.env.TD_API_KEY, {
|
|
19
|
+
os: "linux",
|
|
20
|
+
logging: true,
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
try {
|
|
24
|
+
// Connect to sandbox
|
|
25
|
+
console.log("Connecting to sandbox...");
|
|
26
|
+
await client.connect();
|
|
27
|
+
console.log("Connected!\n");
|
|
28
|
+
|
|
29
|
+
const testPrompt = "click the search button";
|
|
30
|
+
|
|
31
|
+
// Clear cache for this prompt to start fresh
|
|
32
|
+
const cachePath = promptCache.getCachePath(testPrompt);
|
|
33
|
+
console.log(`Cache path for "${testPrompt}": ${cachePath}\n`);
|
|
34
|
+
|
|
35
|
+
// Test 1: First call (should make API request and cache)
|
|
36
|
+
console.log("Test 1: First .ai() call (should cache the response)");
|
|
37
|
+
const stats1 = promptCache.getCacheStats();
|
|
38
|
+
console.log(`Cache before: ${stats1.count} files`);
|
|
39
|
+
|
|
40
|
+
await client.ai(testPrompt);
|
|
41
|
+
|
|
42
|
+
const stats2 = promptCache.getCacheStats();
|
|
43
|
+
console.log(`Cache after: ${stats2.count} files`);
|
|
44
|
+
console.log(
|
|
45
|
+
`Cache hit: ${promptCache.hasCache(testPrompt) ? "YES" : "NO"}\n`,
|
|
46
|
+
);
|
|
47
|
+
|
|
48
|
+
// Test 2: Second call (should use cache)
|
|
49
|
+
console.log(
|
|
50
|
+
"Test 2: Second .ai() call with same prompt (should use cache)",
|
|
51
|
+
);
|
|
52
|
+
console.log('Look for "(using cached response)" message above...\n');
|
|
53
|
+
await client.ai(testPrompt);
|
|
54
|
+
|
|
55
|
+
// Test 3: Third call with cache disabled (should make API call)
|
|
56
|
+
console.log(
|
|
57
|
+
"\nTest 3: Third .ai() call with cache=false (should bypass cache)",
|
|
58
|
+
);
|
|
59
|
+
await client.ai(testPrompt, false);
|
|
60
|
+
|
|
61
|
+
// Test 4: Show cache contents
|
|
62
|
+
console.log("\nTest 4: Cache contents");
|
|
63
|
+
const cachedYaml = promptCache.readCache(testPrompt);
|
|
64
|
+
if (cachedYaml) {
|
|
65
|
+
console.log("Cached YAML preview (first 500 chars):");
|
|
66
|
+
console.log(cachedYaml.substring(0, 500));
|
|
67
|
+
console.log("...\n");
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Test 5: Cache statistics
|
|
71
|
+
console.log("Test 5: Cache statistics");
|
|
72
|
+
const finalStats = promptCache.getCacheStats();
|
|
73
|
+
console.log(`Total cached prompts: ${finalStats.count}`);
|
|
74
|
+
console.log(`Cache files:`, finalStats.files.slice(0, 5));
|
|
75
|
+
|
|
76
|
+
console.log("\n✅ Prompt caching test completed!");
|
|
77
|
+
console.log("\nTo disable caching, pass false: client.ai(prompt, false)");
|
|
78
|
+
console.log("To clear cache, delete .testdriver/.cache/*.yaml files");
|
|
79
|
+
} catch (error) {
|
|
80
|
+
console.error("❌ Test failed:", error.message);
|
|
81
|
+
throw error;
|
|
82
|
+
} finally {
|
|
83
|
+
// Disconnect
|
|
84
|
+
await client.disconnect();
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Run the test
|
|
89
|
+
if (require.main === module) {
|
|
90
|
+
testPromptCache().catch((error) => {
|
|
91
|
+
console.error("Test error:", error);
|
|
92
|
+
process.exit(1);
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
module.exports = testPromptCache;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Quick test to verify provision() authentication works
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { test } from 'vitest';
|
|
6
|
+
import { provision } from '../../lib/presets/index.mjs';
|
|
7
|
+
|
|
8
|
+
test('provision auth test', async (context) => {
|
|
9
|
+
console.log('Starting provision...');
|
|
10
|
+
|
|
11
|
+
const { testdriver, dashcam } = await provision('chrome', {
|
|
12
|
+
url: 'http://testdriver-sandbox.vercel.app/',
|
|
13
|
+
}, context);
|
|
14
|
+
|
|
15
|
+
console.log('✅ Provision complete!');
|
|
16
|
+
console.log('TestDriver:', testdriver);
|
|
17
|
+
console.log('Dashcam:', dashcam);
|
|
18
|
+
|
|
19
|
+
// Try a simple find
|
|
20
|
+
const result = await testdriver.find('any element');
|
|
21
|
+
console.log('Find result:', result);
|
|
22
|
+
});
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
const TestDriver = require("./sdk.js");
|
|
2
|
+
|
|
3
|
+
async function test() {
|
|
4
|
+
console.log("Testing sandbox rendering...");
|
|
5
|
+
|
|
6
|
+
const client = new TestDriver(process.env.TD_API_KEY, {
|
|
7
|
+
os: process.env.TEST_PLATFORM || "linux",
|
|
8
|
+
headless: false, // Should open browser
|
|
9
|
+
logging: true,
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
try {
|
|
13
|
+
console.log("Connecting to sandbox...");
|
|
14
|
+
const instance = await client.connect();
|
|
15
|
+
console.log("Connected to instance:", instance);
|
|
16
|
+
|
|
17
|
+
// Wait a bit to see if browser opens
|
|
18
|
+
await new Promise((resolve) => setTimeout(resolve, 5000));
|
|
19
|
+
|
|
20
|
+
await client.disconnect();
|
|
21
|
+
console.log("Test completed successfully");
|
|
22
|
+
} catch (error) {
|
|
23
|
+
console.error("Test failed:", error);
|
|
24
|
+
process.exit(1);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
test();
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
const SDK = require("./sdk.js");
|
|
2
|
+
|
|
3
|
+
const client = new SDK("test-key");
|
|
4
|
+
|
|
5
|
+
// Get all public methods (non-private, non-constructor)
|
|
6
|
+
const methods = Object.getOwnPropertyNames(Object.getPrototypeOf(client))
|
|
7
|
+
.filter((m) => !m.startsWith("_") && m !== "constructor")
|
|
8
|
+
.sort();
|
|
9
|
+
|
|
10
|
+
console.log("Public SDK Methods:");
|
|
11
|
+
console.log(methods.join(", "));
|
|
12
|
+
console.log("\nTotal:", methods.length, "methods");
|
|
13
|
+
|
|
14
|
+
// Check if commands will be set up after connect
|
|
15
|
+
console.log("\nCommands before connect:", client.commands);
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Quick test to verify SDK refactoring works correctly
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const TestDriver = require("./sdk.js");
|
|
8
|
+
|
|
9
|
+
async function test() {
|
|
10
|
+
console.log("Testing SDK refactor...\n");
|
|
11
|
+
|
|
12
|
+
// Test 1: SDK construction
|
|
13
|
+
console.log("✓ Test 1: Creating SDK instance");
|
|
14
|
+
const client = new TestDriver(process.env.TD_API_KEY || "test-key", {
|
|
15
|
+
logging: false,
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
console.log(" - agent exists:", !!client.agent);
|
|
19
|
+
console.log(" - emitter exists:", !!client.emitter);
|
|
20
|
+
console.log(" - config exists:", !!client.config);
|
|
21
|
+
console.log(" - session exists:", !!client.session);
|
|
22
|
+
console.log(" - apiClient exists:", !!client.apiClient);
|
|
23
|
+
console.log(" - analytics exists:", !!client.analytics);
|
|
24
|
+
console.log(" - sandbox exists:", !!client.sandbox);
|
|
25
|
+
console.log(" - system exists:", !!client.system);
|
|
26
|
+
|
|
27
|
+
// Test 2: Check agent methods are accessible
|
|
28
|
+
console.log("\n✓ Test 2: Checking agent methods");
|
|
29
|
+
console.log(
|
|
30
|
+
" - agent.exploratoryLoop exists:",
|
|
31
|
+
typeof client.agent.exploratoryLoop,
|
|
32
|
+
);
|
|
33
|
+
console.log(" - agent.buildEnv exists:", typeof client.agent.buildEnv);
|
|
34
|
+
console.log(
|
|
35
|
+
" - agent.getRecentSandboxId exists:",
|
|
36
|
+
typeof client.agent.getRecentSandboxId,
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
// Test 3: Check SDK methods
|
|
40
|
+
console.log("\n✓ Test 3: Checking SDK methods");
|
|
41
|
+
console.log(" - ai() exists:", typeof client.ai);
|
|
42
|
+
console.log(" - auth() exists:", typeof client.auth);
|
|
43
|
+
console.log(" - connect() exists:", typeof client.connect);
|
|
44
|
+
console.log(" - disconnect() exists:", typeof client.disconnect);
|
|
45
|
+
|
|
46
|
+
console.log("\n✅ All basic tests passed!");
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
test().catch((error) => {
|
|
50
|
+
console.error("\n❌ Test failed:", error.message);
|
|
51
|
+
console.error(error.stack);
|
|
52
|
+
process.exit(1);
|
|
53
|
+
});
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Quick test to verify stack trace filtering works
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
// Mock the MatchError similar to commands.js
|
|
6
|
+
class MatchError extends Error {
|
|
7
|
+
constructor(message, fatal = false) {
|
|
8
|
+
super(message);
|
|
9
|
+
this.fatal = fatal;
|
|
10
|
+
this.attachScreenshot = true;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// Simulate SDK wrapper with stack filtering (improved version)
|
|
15
|
+
class TestSDK {
|
|
16
|
+
constructor() {
|
|
17
|
+
const command = async (message) => {
|
|
18
|
+
// Simulate the command throwing an error
|
|
19
|
+
throw new MatchError(`AI Assertion failed: ${message}`, true);
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
// Wrap the method with proper stack trace handling
|
|
23
|
+
this.assert = async function (...args) {
|
|
24
|
+
// Capture the call site for better error reporting
|
|
25
|
+
const callSite = {};
|
|
26
|
+
Error.captureStackTrace(callSite, this.assert);
|
|
27
|
+
|
|
28
|
+
try {
|
|
29
|
+
return await command(...args);
|
|
30
|
+
} catch (error) {
|
|
31
|
+
// Replace the stack trace to point to the actual caller
|
|
32
|
+
if (Error.captureStackTrace && callSite.stack) {
|
|
33
|
+
const errorMessage = error.stack?.split("\n")[0];
|
|
34
|
+
const callerStack = callSite.stack?.split("\n").slice(1);
|
|
35
|
+
error.stack = errorMessage + "\n" + callerStack.join("\n");
|
|
36
|
+
}
|
|
37
|
+
throw error;
|
|
38
|
+
}
|
|
39
|
+
}.bind(this);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Test it
|
|
44
|
+
async function runTest() {
|
|
45
|
+
const client = new TestSDK();
|
|
46
|
+
|
|
47
|
+
try {
|
|
48
|
+
console.log("Testing stack trace...\n");
|
|
49
|
+
await client.assert("home page appears"); // Line 42 - this should show in stack
|
|
50
|
+
} catch (error) {
|
|
51
|
+
console.log("Error caught!");
|
|
52
|
+
console.log("Stack trace:");
|
|
53
|
+
console.log(error.stack);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
runTest();
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TestDriver SDK - Assert Test (Vitest)
|
|
3
|
+
* Converted from: testdriver/acceptance/assert.yaml
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { describe, expect, it } from "vitest";
|
|
7
|
+
import { TestDriver } from "../../lib/vitest/hooks.mjs";
|
|
8
|
+
|
|
9
|
+
describe("Assert Test", () => {
|
|
10
|
+
it("should assert the testdriver login page shows", async (context) => {
|
|
11
|
+
const testdriver = TestDriver(context, { newSandbox: true });
|
|
12
|
+
|
|
13
|
+
// provision.chrome() automatically calls ready() and starts dashcam
|
|
14
|
+
await testdriver.provision.chrome({
|
|
15
|
+
url: 'http://testdriver-sandbox.vercel.app/login',
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
// Assert the TestDriver.ai Sandbox login page is displayed
|
|
19
|
+
const result = await testdriver.assert(
|
|
20
|
+
"the TestDriver.ai Sandbox login page is displayed",
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
expect(result).toBeTruthy();
|
|
24
|
+
});
|
|
25
|
+
// it("should assert the testdriver login page shows 2", async (context) => {
|
|
26
|
+
// const testdriver = TestDriver(context, { newSandbox: true });
|
|
27
|
+
|
|
28
|
+
// // provision.chrome() automatically calls ready() and starts dashcam
|
|
29
|
+
// await testdriver.provision.chrome({
|
|
30
|
+
// url: 'http://testdriver-sandbox.vercel.app/login',
|
|
31
|
+
// });
|
|
32
|
+
|
|
33
|
+
// // Assert the TestDriver.ai Sandbox login page is displayed
|
|
34
|
+
// const result = await testdriver.assert(
|
|
35
|
+
// "the TestDriver.ai Sandbox login page is displayed",
|
|
36
|
+
// );
|
|
37
|
+
|
|
38
|
+
// expect(result).toBeTruthy();
|
|
39
|
+
// });
|
|
40
|
+
});
|
|
41
|
+
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
import { describe, expect, it } from "vitest";
|
|
10
|
-
import { TestDriver } from "../../
|
|
10
|
+
import { TestDriver } from "../../lib/vitest/hooks.mjs";
|
|
11
11
|
|
|
12
12
|
describe("Auto Cache Key Demo", () => {
|
|
13
13
|
it("should use auto-generated cache key based on file hash", async (context) => {
|