testdriverai 6.0.17 → 6.0.18

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/agent/index.js CHANGED
@@ -152,9 +152,23 @@ class TestDriverAgent extends EventEmitter2 {
152
152
  // temporary file for command history
153
153
  this.commandHistoryFile = path.join(os.homedir(), ".testdriver_history");
154
154
 
155
+ // Flag to indicate if the agent should stop execution
156
+ this.stopped = false;
157
+
155
158
  this.emitter.emit(events.log.log, JSON.stringify(environment));
156
159
  this.emitter.emit(events.log.log, JSON.stringify(cliArgs));
157
160
  }
161
+
162
+ // Stop method to immediately halt execution
163
+ stop() {
164
+ this.stopped = true;
165
+ this.emitter.emit(
166
+ events.log.narration,
167
+ theme.dim("stopping execution..."),
168
+ true,
169
+ );
170
+ }
171
+
158
172
  // single function to handle all program exits
159
173
  // allows us to save the current state, run lifecycle hooks, and track analytics
160
174
  async exit(failed = true, shouldSave = false, shouldRunPostrun = false) {
@@ -328,6 +342,16 @@ class TestDriverAgent extends EventEmitter2 {
328
342
  // this checks that the task is "really done" using a screenshot of the desktop state
329
343
  // it's likely that the task will not be complete and the AI will respond with more codeblocks to execute
330
344
  async check() {
345
+ // Check if execution has been stopped
346
+ if (this.stopped) {
347
+ this.emitter.emit(
348
+ events.log.narration,
349
+ theme.dim("execution stopped"),
350
+ true,
351
+ );
352
+ return;
353
+ }
354
+
331
355
  this.checkCount++;
332
356
 
333
357
  if (this.checkCount >= this.checkLimit) {
@@ -469,8 +493,28 @@ class TestDriverAgent extends EventEmitter2 {
469
493
  dry = false,
470
494
  shouldSave = false,
471
495
  ) {
496
+ // Check if execution has been stopped
497
+ if (this.stopped) {
498
+ this.emitter.emit(
499
+ events.log.narration,
500
+ theme.dim("execution stopped"),
501
+ true,
502
+ );
503
+ return;
504
+ }
505
+
472
506
  if (commands?.length) {
473
507
  for (const command of commands) {
508
+ // Check if execution has been stopped before each command
509
+ if (this.stopped) {
510
+ this.emitter.emit(
511
+ events.log.narration,
512
+ theme.dim("execution stopped"),
513
+ true,
514
+ );
515
+ return;
516
+ }
517
+
474
518
  // Update current command tracking
475
519
  const commandIndex = commands.indexOf(command);
476
520
  this.sourceMapper.setCurrentCommand(commandIndex);
@@ -507,9 +551,29 @@ class TestDriverAgent extends EventEmitter2 {
507
551
  dry = false,
508
552
  shouldSave = false,
509
553
  ) {
554
+ // Check if execution has been stopped
555
+ if (this.stopped) {
556
+ this.emitter.emit(
557
+ events.log.narration,
558
+ theme.dim("execution stopped"),
559
+ true,
560
+ );
561
+ return;
562
+ }
563
+
510
564
  depth = depth + 1;
511
565
 
512
566
  for (const codeblock of codeblocks) {
567
+ // Check if execution has been stopped before each codeblock
568
+ if (this.stopped) {
569
+ this.emitter.emit(
570
+ events.log.narration,
571
+ theme.dim("execution stopped"),
572
+ true,
573
+ );
574
+ return;
575
+ }
576
+
513
577
  let commands;
514
578
 
515
579
  try {
@@ -542,8 +606,22 @@ class TestDriverAgent extends EventEmitter2 {
542
606
  validateAndLoop = false,
543
607
  dry = false,
544
608
  shouldSave = false,
609
+ isLoopContinuation = false,
545
610
  ) {
546
- this.executionHistory.push({ prompt: this.lastPrompt, commands: [] });
611
+ // Check if execution has been stopped
612
+ if (this.stopped) {
613
+ this.emitter.emit(
614
+ events.log.narration,
615
+ theme.dim("execution stopped"),
616
+ true,
617
+ );
618
+ return;
619
+ }
620
+
621
+ // Only create new execution history entry if this is not a loop continuation
622
+ if (!isLoopContinuation) {
623
+ this.executionHistory.push({ prompt: this.lastPrompt, commands: [] });
624
+ }
547
625
 
548
626
  if (shouldSave) {
549
627
  await this.save({ silent: true });
@@ -583,7 +661,13 @@ class TestDriverAgent extends EventEmitter2 {
583
661
  "check thinks more needs to be done",
584
662
  );
585
663
 
586
- return await this.aiExecute(response, validateAndLoop);
664
+ return await this.aiExecute(
665
+ response,
666
+ validateAndLoop,
667
+ dry,
668
+ shouldSave,
669
+ true,
670
+ );
587
671
  } else {
588
672
  this.emitter.emit(events.log.debug, "seems complete, returning");
589
673
 
@@ -738,6 +822,16 @@ commands:
738
822
  validateAndLoop = false,
739
823
  shouldSave = true,
740
824
  ) {
825
+ // Check if execution has been stopped
826
+ if (this.stopped) {
827
+ this.emitter.emit(
828
+ events.log.narration,
829
+ theme.dim("execution stopped"),
830
+ true,
831
+ );
832
+ return;
833
+ }
834
+
741
835
  this.lastPrompt = currentTask;
742
836
  this.checkCount = 0;
743
837
 
@@ -1867,7 +1961,15 @@ Please check your network connection, TD_API_KEY, or the service status.`,
1867
1961
  }
1868
1962
  }
1869
1963
  if (lifecycleFile) {
1870
- await this.run(lifecycleFile, false, false);
1964
+ // Store current source mapping state before running lifecycle file
1965
+ const previousContext = this.sourceMapper.saveContext();
1966
+
1967
+ try {
1968
+ await this.run(lifecycleFile, false, false);
1969
+ } finally {
1970
+ // Restore previous source mapping state after lifecycle file execution
1971
+ this.sourceMapper.restoreContext(previousContext);
1972
+ }
1871
1973
  }
1872
1974
  } // Unified command definitions that work for both CLI and interactive modes
1873
1975
  getCommandDefinitions() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "testdriverai",
3
- "version": "6.0.17",
3
+ "version": "6.0.18",
4
4
  "description": "Next generation autonomous AI agent for end-to-end testing of web & desktop",
5
5
  "main": "index.js",
6
6
  "bin": {
@@ -11,7 +11,6 @@ steps:
11
11
  - command: wait-for-text
12
12
  text: Add to Chrome
13
13
  timeout: 15000
14
-
15
14
  - prompt: Install the extension by clicking Add to Chrome
16
15
  commands:
17
16
  - command: hover-text
@@ -21,7 +20,6 @@ steps:
21
20
  - command: wait-for-text
22
21
  text: Add extension
23
22
  timeout: 5000
24
-
25
23
  - prompt: Confirm extension installation
26
24
  commands:
27
25
  - command: hover-text
@@ -1,65 +1,11 @@
1
1
  version: 6.0.0
2
- session: 67f00511acbd9ccac373edf7
3
2
  steps:
4
3
  - prompt: launch chrome
5
4
  commands:
6
5
  - command: exec
7
6
  lang: pwsh
8
7
  code: |
9
- Write-Host "Initializing new npm project..."
10
-
11
- cd $env:TEMP
12
- Write-Host "Changed directory to TEMP: $env:TEMP"
13
-
14
- Write-Host "Running 'npm init -y'..."
15
- npm init -y
16
-
17
- Write-Host "Installing dependencies: @puppeteer/browsers and dashcam-chrome..."
18
- npm install @puppeteer/browsers dashcam-chrome
19
-
20
- Write-Host "Installing Chromium via '@puppeteer/browsers'..."
21
- npx @puppeteer/browsers install chrome
22
-
23
- # Define paths
24
- $extensionPath = Join-Path (Get-Location) "node_modules/dashcam-chrome/build"
25
- $profilePath = Join-Path $env:TEMP "chrome-profile-$(Get-Random)"
26
- $defaultDir = Join-Path $profilePath "Default"
27
- $prefsPath = Join-Path $defaultDir "Preferences"
28
-
29
- Write-Host "Extension path: $extensionPath"
30
- Write-Host "Chrome user data dir: $profilePath"
31
-
32
- # Create a clean profile + Preferences to disable password manager & autofill
33
- Remove-Item $profilePath -Recurse -Force -ErrorAction SilentlyContinue
34
- New-Item $defaultDir -ItemType Directory -Force | Out-Null
35
-
36
- $prefs = @{
37
- "credentials_enable_service" = $false
38
- "profile" = @{
39
- "password_manager_enabled" = $false
40
- }
41
- "autofill" = @{
42
- "profile_enabled" = $false
43
- "address_enabled" = $false
44
- "credit_card_enabled" = $false
45
- }
46
- } | ConvertTo-Json -Depth 6
47
-
48
- # Write Preferences before Chrome starts (ASCII/UTF8 is fine)
49
- $prefs | Set-Content -Path $prefsPath -Encoding ASCII
50
-
51
- # Build args
52
- $chromeArgs = @(
53
- "--start-maximized",
54
- "--load-extension=$extensionPath",
55
- "--user-data-dir=$profilePath",
56
- "--no-first-run",
57
- "--no-default-browser-check",
58
- "--disable-infobars"
59
- "${TD_WEBSITE}"
60
- ) -join ' '
61
-
62
- Start-Process "cmd.exe" -ArgumentList "/c", "npx @puppeteer/browsers launch chrome -- $chromeArgs"
8
+ Start-Process "C:/Program Files/Google/Chrome/Application/chrome.exe" -ArgumentList "--start-maximized", "--guest", "https://testdriver-sandbox.vercel.app/login"
63
9
  - command: wait-for-text
64
- text: ${TD_WEBSITE}
10
+ text: "TestDriver.ai Sandbox"
65
11
  timeout: 60000
@@ -1,66 +0,0 @@
1
- version: 6.0.0
2
- session: 67f00511acbd9ccac373edf7
3
- steps:
4
- - prompt: Setup environment and variables
5
- commands:
6
- - command: exec
7
- lang: pwsh
8
- code: |
9
- # Enable strict mode and verbose output
10
- Set-StrictMode -Version Latest
11
- $ErrorActionPreference = "Stop"
12
-
13
- # Set Chrome and extension info
14
- $chromeInstallerUrl = "https://dl.google.com/chrome/install/latest/chrome_installer.exe"
15
- $chromeInstallPath = "$env:ProgramFiles\Google\Chrome\Application\chrome.exe"
16
- $extensionId = "aapbdbdomjkkjkaonfhkkikfgjllcleb" # Google Translate
17
-
18
- Write-Host "Chrome installer URL: $chromeInstallerUrl"
19
- Write-Host "Chrome install path: $chromeInstallPath"
20
- Write-Host "Extension ID: $extensionId"
21
-
22
- - prompt: Check and install Chrome if needed
23
- commands:
24
- - command: exec
25
- lang: pwsh
26
- code: |
27
- $chromeInstallerUrl = "https://dl.google.com/chrome/install/latest/chrome_installer.exe"
28
- $chromeInstallPath = "$env:ProgramFiles\Google\Chrome\Application\chrome.exe"
29
-
30
- # Download Chrome if not installed
31
- if (!(Test-Path $chromeInstallPath)) {
32
- Write-Host "Chrome not found at $chromeInstallPath. Downloading..."
33
- $chromeInstaller = "$env:TEMP\chrome_installer.exe"
34
- try {
35
- Write-Host "Downloading Chrome installer..."
36
- Invoke-WebRequest -Uri $chromeInstallerUrl -OutFile $chromeInstaller
37
- Write-Host "Installing Chrome..."
38
- Start-Process -FilePath $chromeInstaller -Wait
39
- Write-Host "Chrome installation completed."
40
- } catch {
41
- Write-Error "Failed to install Chrome: $_"
42
- exit 1
43
- }
44
- } else {
45
- Write-Host "Chrome is already installed at: $chromeInstallPath"
46
- }
47
-
48
- - prompt: Launch Chrome and install extension from Chrome Web Store
49
- commands:
50
- - command: exec
51
- lang: pwsh
52
- code: |
53
- $chromeInstallPath = "$env:ProgramFiles\Google\Chrome\Application\chrome.exe"
54
- $extensionId = "aapbdbdomjkkjkaonfhkkikfgjllcleb" # Google Translate
55
- $webStoreUrl = "https://chrome.google.com/webstore/detail/$extensionId"
56
-
57
- # Launch Chrome with the Web Store page for the extension
58
- try {
59
- Write-Host "Launching Chrome and opening Chrome Web Store for extension..."
60
- Start-Process -FilePath $chromeInstallPath -ArgumentList "--start-maximized", "--new-window", "$webStoreUrl"
61
- Write-Host "Chrome launched successfully. Extension page should be open."
62
- Write-Host "You can now use TestDriver to automate clicking 'Add to Chrome' button."
63
- } catch {
64
- Write-Error "Failed to launch Chrome: $_"
65
- exit 1
66
- }
@@ -1,46 +0,0 @@
1
- version: 6.0.6
2
- session: 687eb092664035296ec57e6a
3
- steps:
4
- - prompt: click the right arrow in arc browser
5
- commands:
6
- - command: focus-application
7
- name: Arc
8
- - command: hover-image
9
- description: right arrow button in the Arc browser
10
- action: click
11
- method: turbo
12
- - prompt: >-
13
- /explore complete the arc onboarding. when asked to log in, use the email
14
- 11354345965.1@testdriver.ai and password FakePassword123
15
- commands:
16
- - command: hover-text
17
- text: Sign In
18
- description: sign-in link on the onboarding page
19
- action: click
20
- - prompt: >-
21
- /explore complete the arc onboarding. when asked to log in, use the email
22
- 11354345965.1@testdriver.ai and password FakePassword123
23
- commands:
24
- - command: hover-text
25
- text: Email
26
- description: email input field
27
- action: click
28
- - command: type
29
- text: 11354345965.1@testdriver.ai
30
- - command: hover-text
31
- text: Password
32
- description: password input field
33
- action: click
34
- - command: type
35
- text: FakePassword123
36
- - command: hover-text
37
- text: Sign In
38
- description: sign-in button to log in
39
- action: click
40
- - prompt: click the rigth arrow in arc browser
41
- commands:
42
- - command: hover-image
43
- description: >-
44
- white button with a right arrow in the center of the screen below the
45
- text "Meet the internet, again."
46
- action: click
@@ -1,4 +0,0 @@
1
- version: 6.0.6
2
- session: 687eb092664035296ec57e6a
3
- steps:
4
- - prompt: click on something in vs code
@@ -1,4 +0,0 @@
1
- # TODO
2
-
3
- - [ ] Install extension
4
- - [ ] Test extension
@@ -1,6 +0,0 @@
1
- version: 6.0.6
2
- steps:
3
- - prompt: log in
4
- - prompt: add an item to the cart
5
- - prompt: click on the cart icon
6
- - prompt: complete checkout