Skip to main content

Overview

The vscode() preset automatically sets up Visual Studio Code with TestDriver and Dashcam recording. Perfect for testing VS Code extensions and IDE workflows.
Recommended Pattern (v7.1+): Use TestDriver() hook + provision.vscode() for more flexibility:
import { TestDriver } from 'testdriverai/vitest/hooks';

test('my test', async (context) => {
  const testdriver = TestDriver(context);
  await testdriver.provision.vscode({ 
    workspace: '/tmp/project',
    extensions: ['ms-python.python']
  });
  // ...
});
The vscode() preset is still supported but the direct API provides better control and clearer lifecycle management.

Quick Start

import { test } from 'vitest';
import { vscode } from 'testdriverai/presets';

test('extension test', async (context) => {
  const { vscode } = await vscode(context, {
    workspace: '/tmp/test-project',
    extensions: ['ms-python.python']
  });
  
  await vscode.find('File menu').click();
  await vscode.find('New File').click();
  await vscode.find('Python file type').click();
});

Signature

vscode(context, options): Promise<VSCodeResult>

Parameters

context
object
required
Vitest test context - automatically passed to your test function
options
object
Configuration options for VS Code

Returns

testdriver
TestDriver
required
TestDriver instance ready to use
vscode
TestDriver
required
Alias for testdriver (semantic clarity for VS Code testing)
dashcam
Dashcam
Dashcam instance for test recording (if enabled)

Examples

Basic Extension Testing

import { test } from 'vitest';
import { vscode } from 'testdriverai/presets';

test('python extension creates new file', async (context) => {
  const { vscode } = await vscode(context, {
    workspace: '/tmp/python-project',
    extensions: ['ms-python.python']
  });
  
  // Open command palette
  await vscode.pressKeys(['cmd', 'shift', 'p']);
  
  // Create new Python file
  await vscode.type('Python: Create New File');
  await vscode.pressKeys(['enter']);
  
  // Verify file was created
  await vscode.assert('Untitled Python file is open');
});

Testing Multiple Extensions

import { test } from 'vitest';
import { vscode } from 'testdriverai/presets';

test('eslint and prettier integration', async (context) => {
  const { vscode } = await vscode(context, {
    workspace: '/tmp/js-project',
    extensions: [
      'dbaeumer.vscode-eslint',
      'esbenp.prettier-vscode'
    ]
  });
  
  // Open a JavaScript file
  await vscode.find('File').click();
  await vscode.find('Open File').click();
  await vscode.type('src/index.js');
  await vscode.pressKeys(['enter']);
  
  // Format document
  await vscode.pressKeys(['shift', 'alt', 'f']);
  
  await vscode.assert('Document is formatted');
});

Empty Workspace

import { test } from 'vitest';
import { vscode } from 'testdriverai/presets';

test('empty workspace welcome screen', async (context) => {
  const { vscode } = await vscode(context, {
    // No workspace specified - opens to welcome screen
  });
  
  await vscode.find('Open Folder button').click();
  await vscode.type('/tmp/my-project');
  await vscode.pressKeys(['enter']);
  
  await vscode.assert('Folder is opened');
});

Testing on Different Operating Systems

import { test } from 'vitest';
import { vscode } from 'testdriverai/presets';

test('windows vscode test', async (context) => {
  const { vscode } = await vscode(context, {
    workspace: 'C:\\Users\\TestUser\\project',
    os: 'windows'
  });
  
  await vscode.find('Explorer view').click();
});

test('mac vscode test', async (context) => {
  const { vscode } = await vscode(context, {
    workspace: '/Users/testuser/project',
    os: 'mac'
  });
  
  await vscode.find('Explorer view').click();
});

Extension Settings

import { test } from 'vitest';
import { vscode } from 'testdriverai/presets';

test('configure extension settings', async (context) => {
  const { vscode } = await vscode(context, {
    extensions: ['ms-python.python']
  });
  
  // Open settings
  await vscode.pressKeys(['cmd', ',']);
  
  // Search for Python settings
  await vscode.find('Search settings').type('python.linting');
  
  // Enable linting
  await vscode.find('Python > Linting: Enabled checkbox').click();
  
  await vscode.assert('Linting is enabled');
});

Debugging Workflow

import { test } from 'vitest';
import { vscode } from 'testdriverai/presets';

test('debug javascript file', async (context) => {
  const { vscode, dashcam } = await vscode(context, {
    workspace: '/tmp/debug-test',
    extensions: ['ms-vscode.js-debug']
  });
  
  // Open file
  await vscode.find('index.js in Explorer').click();
  
  // Set breakpoint
  await vscode.find('line 10 gutter').click();
  
  // Start debugging
  await vscode.pressKeys(['F5']);
  
  // Wait for breakpoint
  await vscode.assert('Debugger paused at breakpoint');
  
  // Step over
  await vscode.pressKeys(['F10']);
  
  await vscode.assert('Debugger moved to next line');
  
  // Dashcam captures entire debug session
});

What It Does

When you call vscode(), it automatically:
  1. Initializes TestDriver - Creates and connects to sandbox
  2. Sets up Dashcam - Authenticates and starts recording (if enabled)
  3. Installs Extensions - Downloads and installs specified extensions
  4. Launches VS Code - Opens VS Code with your workspace
  5. Waits for Ready - Ensures VS Code is focused and loaded
  6. Returns Instances - Provides ready-to-use testdriver, vscode alias, and dashcam
At test end:
  • Dashcam automatically stops and saves replay URL
  • TestDriver automatically disconnects
  • All cleanup is handled for you

Common Patterns

File Explorer Interaction

test('create new folder', async (context) => {
  const { vscode } = await vscode(context, {
    workspace: '/tmp/test-workspace'
  });
  
  // Right-click in Explorer
  await vscode.find('Explorer view').click({ button: 'right' });
  await vscode.find('New Folder').click();
  await vscode.type('src');
  await vscode.pressKeys(['enter']);
  
  await vscode.assert('src folder appears in Explorer');
});

Terminal Commands

test('run npm install', async (context) => {
  const { vscode } = await vscode(context, {
    workspace: '/tmp/node-project'
  });
  
  // Open integrated terminal
  await vscode.pressKeys(['ctrl', '`']);
  
  // Run command
  await vscode.type('npm install');
  await vscode.pressKeys(['enter']);
  
  // Wait for completion
  await vscode.assert('node_modules folder created');
});

Search and Replace

test('find and replace', async (context) => {
  const { vscode } = await vscode(context, {
    workspace: '/tmp/project'
  });
  
  // Open file
  await vscode.find('app.js').click();
  
  // Open find/replace
  await vscode.pressKeys(['cmd', 'h']);
  
  // Enter search term
  await vscode.find('Find input').type('oldFunction');
  
  // Enter replacement
  await vscode.find('Replace input').type('newFunction');
  
  // Replace all
  await vscode.find('Replace All button').click();
  
  await vscode.assert('All occurrences replaced');
});

Git Integration

test('commit changes', async (context) => {
  const { vscode } = await vscode(context, {
    workspace: '/tmp/git-project',
    extensions: ['vscode.git']
  });
  
  // Open Source Control
  await vscode.find('Source Control icon').click();
  
  // Stage changes
  await vscode.find('Stage All Changes button').click();
  
  // Enter commit message
  await vscode.find('Commit message input').type('Initial commit');
  
  // Commit
  await vscode.find('Commit button').click();
  
  await vscode.assert('Changes committed');
});

Extension ID Reference

Common extension IDs for testing:
ExtensionID
Pythonms-python.python
ESLintdbaeumer.vscode-eslint
Prettieresbenp.prettier-vscode
GitLenseamodio.gitlens
Live Serverritwickdey.liveserver
Dockerms-azuretools.vscode-docker
REST Clienthumao.rest-client
Debugger for Chromemsjsdiag.debugger-for-chrome
Find more extension IDs on the VS Code Marketplace.

Using with provision()

The vscode() preset can also be called via the unified provision() function:
import { provision } from 'testdriverai/presets';

test('using provision', async (context) => {
  const { vscode } = await provision('vscode', {
    workspace: '/tmp/project',
    extensions: ['ms-python.python']
  }, context);
  
  // Same functionality as vscode() directly
});

Error Handling

test('handles missing extension', async (context) => {
  try {
    const { vscode } = await vscode(context, {
      extensions: ['non.existent.extension']
    });
    
    // Will throw error if extension installation fails
  } catch (error) {
    // Cleanup still happens automatically
    expect(error.message).toContain('extension');
  }
});

See Also