Skip to content

cursor-ide/vsce-testing

Repository files navigation

@vsce/testing

🧪 The high-fidelity, Deno-native test runner for modern VS Code extensions

JSR Scope JSR JSR Score GitHub CI Last Updated License

@vsce/testing runs your Deno-first, web-compatible VS Code extensions inside the actual Web Extension host that ships with desktop VS Code. No complex mocks, no Node.js toolchain—just real APIs, deterministic results, and a one-liner developer experience.

Heads-up! This package is primarily a library API. For the full batteries-included developer experience (watch mode, coloured reporter, scaffolding commands, etc.) install @vsce/cli. If you just need a quick runner, @vsce/testing ships with a minimal CLI – see the Thin CLI section below.


✨ Features

Category Details
🦕 Deno-Native Written in TypeScript for the Deno runtime—no npm, no ts-node, no polyfills.
🎯 Real Extension Host Launches desktop VS Code in Web-extension mode for 100 % API fidelity.
One-Command DX bundleAndRunDesktop() bundles the extension + tests and streams results.
🧩 Unit & E2E Lightweight in-process mocks for unit tests, full host runner for integration / E2E.
🔒 Zero Node Deps All file-system, crypto, and timer APIs rely on Deno + Web standards.
📝 Strict Types Ships its own types and re-exports helpers from @typed/vscode for IntelliSense.

📥 Installation

# Recommended: add to your import map
deno add @vsce/testing

@vsce/testing targets Deno ≥1.44 and VS Code ≥1.90.


🚀 Quick Start

deno run -A jsr:@vsce/testing/run.ts --project /abs/path/to/extension --test /abs/path/to/tests/all.ts

Write normal Deno tests in all.ts:

import { assertEquals } from "jsr:@std/assert";
import * as vscode from "@typed/vscode";

Deno.test("command returns hello", async () => {
  const result = await vscode.commands.executeCommand("myExt.hello");
  assertEquals(result, "hello from extension");
});

Run with deno task test:ext (example task):

{
  "tasks": {
    "test:ext": "deno run -A tests/run.ts"
  }
}

Programmatic API:

import { bundleAndRunDesktop } from "jsr:@vsce/testing";

const exitCode = await bundleAndRunDesktop({
  projectDir: "/abs/path/to/extension",   // contains package.json & src/
  testEntry:  "/abs/path/to/tests/all.ts", // Deno test entry-point
});
Deno.exit(exitCode);

🏃 Thin CLI

Need a one-liner without writing a runner script? Use the built-in wrapper:

deno run -A jsr:@vsce/testing/run.ts --project . --test tests/all.ts

Flags:

Flag Description
-p, --project Extension root folder (contains package.json).
-t, --test Deno test entry file to execute inside VS Code.
--code-bin Path to VS Code executable (falls back to code).

For a full-featured experience (watch mode, better output, template helpers) install @vsce/cli once it is available.


🔧 Public API (excerpt)

Function Purpose
runExtension(entry, opts?) In-process harness with minimal mocks—ideal for unit tests.
runExtensionDesktop(opts) Spawns desktop VS Code and executes your pre-bundled test module.
bundleAndRunDesktop(opts) Bundles the extension via @vsce/bundler and your test module, then calls runExtensionDesktop().
MockExtensionContext Typed stub implementing vscode.ExtensionContext.
MockWorkspaceFs In-memory implementation of vscode.workspace.fs.
withTempWorkspace(fn) Helper that creates a fresh MockWorkspaceFs for the callback.

Full type signatures live in the source—hover in VS Code for details.


🏗️ How It Works

  1. Bundle – Uses @vsce/bundler to create a single, web-safe JS file for your extension.
  2. Emit Tests – Leverages @deno/emit to produce a Node-loadable bundle of your Deno tests.
  3. Launch VS Code – Spawns the code executable (configurable via CODE_BIN) with --extensionDevelopmentPath + --extensionTestsPath.
  4. Driver Scripthost_driver.js runs inside VS Code’s Node context, dynamically imports your test bundle, and propagates the exit code.
  5. Streaming Output – Stdout / stderr from VS Code are piped back to your terminal for real-time feedback.

🖥️ CI Example

name: extension-tests

on: [push, pull_request]

jobs:
  vsce-tests:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: denoland/setup-deno@v1
        with:
          deno-version: "v1.x"
      - name: Install VS Code
        run: sudo apt-get update && sudo apt-get install -y code
      - name: Run extension tests
        run: deno task test:ext
        env:
          CODE_BIN: code  # path to VS Code if not on PATH

Web Extension Support

Why Web Extensions?

This package is optimized for the VSCode Web Extensions runtime as our pragmatic path to bringing VSCode extension development to Deno. While our ideal would be full parity with the Node.js extension development environment, the web extension runtime represents the best available approach given current VSCode architecture limitations.

The Reality:

  • 🎯 Goal: Enable Deno-native VSCode extension development
  • ⚠️ Challenge: VSCode's extension host is deeply integrated with Node.js
  • Solution: Leverage the web extension runtime for Deno compatibility
  • 🪄 Future: Working toward fuller Node.js runtime parity as the ecosystem evolves

Universal Compatibility

The web extension runtime enables you to create extensions that run everywhere - both desktop VSCode and web-based environments (vscode.dev, github.dev, GitHub Codespaces):

import * as vscode from "@typed/vscode";

// Web extensions run on BOTH desktop and web VSCode
export function activate(context: vscode.ExtensionContext): void {
  // Full VSCode API support: TreeView, Commands, Language Features, etc.
  const provider = new MyTreeDataProvider();
  vscode.window.createTreeView('myView', { treeDataProvider: provider });
  
  // Limitation: Node.js APIs are not available (browser sandbox restrictions)
  // However, we can use Deno's web API's as a drop-in replacement for some Node.js APIs
  // The extension works identically on desktop and web!
}

Key Benefits:

  • Universal compatibility - One extension runs on desktop AND web VSCode
  • Full VSCode API access - Commands, UI, language features, etc.
  • Modern deployment - Works in vscode.dev, github.dev, Codespaces
  • ⚠️ Browser limitations - No Node.js/filesystem APIs (applies to web runtime only)

🚧 Deno VSCode Extension Ecosystem (WIP) 🚧

@typed/vscode is part of a complete ecosystem for Deno-based VSCode extension development. Explore these complementary packages:

🛠️ Development Tools

@vsce/cli - Command-line tools for Deno VSCode extensions

deno add @vsce/cli
  • Project scaffolding and templates
  • Development server with hot reload
  • Build and packaging utilities
  • Extension testing and validation

@vsce/create - Project generator for new extensions

deno add @vsce/create
  • Interactive project setup
  • Multiple template options (basic, language server, tree view, etc.)
  • Deno-optimized project structure
  • Best practices and conventions built-in

🔧 Build and Bundle

@vsce/bundler - Web extension bundler for Deno

deno add @vsce/bundler
  • Bundle Deno code for VSCode web extensions
  • Tree shaking and optimization
  • Source map support
  • Multi-target builds (desktop + web)

🧪 Testing Framework

@vsce/testing - Testing utilities for VSCode extensions

deno add @vsce/testing
  • Mock VSCode APIs for unit testing
  • Extension host simulation
  • Language server testing utilities
  • TreeView and UI component testing

Runtime Compatibility

Environment Support Notes
VSCode Desktop ✅ Full All APIs available
VSCode Web ✅ Most APIs No Node.js/filesystem APIs
Deno Runtime ✅ Type-checking For development and testing
GitHub Codespaces ✅ Full Web + server APIs
vscode.dev ✅ Web APIs Browser-based development

📚 Docs & Resources


License

MIT License - see LICENSE for details.


Happy coding with Deno + VSCode! 🦕⚡

Part of the @vsce ecosystem for Deno-based VSCode extension development.