Experimenting with a VSCode extension that requires the act of launching a folder/workspace

Currently, I am developing a custom VSCode extension that considers the path of the file being opened within the workspace.

To create a reproducible test scenario, I want to open the test folder itself in VSCode and then proceed to open the test file within it. The code snippet for this action is as follows:

import * as vscode from "vscode";

test("whatever", async function() {
    let workspaceUri = vscode.Uri.file(__dirname);
    // however, the execution halts at this point...
    await vscode.commands.executeCommand("vscode.openFolder", workspaceUri);
    await vscode.workspace.openTextDocument(__filename);
})

The issue arises when attempting this process, leading to the tests prematurely stopping before even testing my actual code. A similar problem is discussed here.

Is there a workaround or method through which I can safely open a workspace and utilize it during tests?

Answer №1

For detailed information on testing extensions, be sure to consult the documentation: Testing-extensions-docs

In your extension's development .vscode/launch.json file, you have the ability to include arguments as outlined in the documentation:

"args": ["file or folder name", "--extensionDevelopmentPath=${workspaceRoot}", "--extensionTestsPath=${workspaceRoot}/out/test" ]

You can construct a testing directory structure containing all necessary files within the specified folder mentioned in the configuration, and ensure that these directories/files are added to your .vscodeignore (the default test directory is already present there).

The alternative approach I have been using involves employing a bash script with the following code snippet:

#!/bin/bash

# $0 = command itself
# $1 = extension-directory(relative path)
# $2 = process-id of code to kill

[ -z "$1" ] && { echo "path argument not provided"; exit 1; }
[ -z "$2" ] || { xkill -id $2; }

cd $1
vsce package
file=$(find . -name "*.vsix")
code --install-extension $file
code &
echo $!

All that remains is opening a folder in the launched code instance and executing required commands. Establishing a suitable testing environment appears to offer more advantages in the long run, particularly if it is anticipated that numerous tests will need to be conducted.

Answer №2

The solution provided did not suit my needs in the year 2023. I encountered difficulties trying to open a workspace in VS Code by modifying the launch.json.

Instead, I found that using @vscode/test-electron runTests with a launchArgs argument proved to be effective. By specifying a directory as the first argument, it would open as a workspace.

await runTests({extensionDevelopmentPath, 
                extensionTestsPath, 
                launchArgs:[path_to_directory] 
               });

During testing, I utilized a temporary directory created using tmp-promise. Here is an excerpt from my `runTests.ts`:

import * as path from "path";
import { runTests } from "@vscode/test-electron";
import { file, dir } from 'tmp-promise';

async function main() {
  try {
    const extensionDevelopmentPath = path.resolve(__dirname, "../../");
    const extensionTestsPath = path.resolve(__dirname, "./suite/index");

    const {path:tempdir, cleanup} = await dir({unsafeCleanup:true});
    await runTests({extensionDevelopmentPath, 
                    extensionTestsPath, 
                    launchArgs:[tempdir] });
    cleanup();
  } catch (err) {
    console.error("Failed to run tests");
    process.exit(1);
  }
}

main();

For reference and further guidance, consider exploring the sample in the VS Code test repository for an updated example to work with.

Answer №3

If you want to open a workspace or folder in your VSCode instance, you can utilize VSBrowser.instance.openResources(path);

import { WebDriver, VSBrowser } from 'vscode-extension-tester';
const path = require('path');
...

suite('Unique Test suite ABC', () => {
    const custom_project_path = path.join(__dirname, "custom", "project", "folder");
    
    setup(async () => {
        driver = VSBrowser.instance.driver;
        driver.manage().timeouts().implicitlyWait(1000);
    });

    test("Access a workspace in VSCode instance", async () => {
        await VSBrowser.instance.openResources(path.resolve(custom_project_path));
    });

});

...

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Build an object using a deeply nested JSON structure

I am working with a JSON object received from my server in Angular and I want to create a custom object based on this data. { "showsHall": [ { "movies": [ "5b428ceb9d5b8e4228d14225", "5b428d229d5b8e4 ...

Is there a way to access the final child element within a mat-accordion component using Material-UI and Angular 8?

I have a mat-accordion element with multiple expansion panels that are generated dynamically. How can I programmatically select and expand the last mat-expansion-panel element? <mat-accordion> <mat-expansion-panel> text 0 </mat-ex ...

Steps for utilizing Bazel to compile TypeScript

Calling all Bazel (Blaze) experts: I'm curious about the best method for integrating Bazel as a build system for cutting-edge web applications built in Typescript. Is there a preferred setup or perhaps a template that demonstrates this integration? T ...

Encountering errors while working with React props in typing

In my application, I am utilizing ANT Design and React with 2 components in the mix: //PARENT const Test = () => { const [state, setState] = useState([]); function onChange( pagination: TablePaginationConfig, filters: Record<string, ...

Defining a structure for an entity in which its attributes distinguish between different data types and an array combination

I strongly believe that the best way to showcase this concept is through a clear example: enum EventType { A, B, C }; type MyEvent = [EventType.A, number] | [EventType.B, string] | [EventType.C, number, string]; const eventsGrouped: Record<Event ...

The CastError occurred because the attempt to add a string value to an array failed when converting it to a string

An issue I am encountering: *CastError: Cast to string failed for value "[ 'ZTM', 'NASA' ]" (type Array) at path "customers" at model.Query.exec (/Users/mike/Documents/NodeJS-applications/NASA-project/server/node_modules/mongoose/lib/qu ...

Show a nested JSON object when the specific key is not recognized

I received the following data from my API: { "id": 82, "shortname": "testing2", "fullname": "test2", "address": "addrtest2", "telephone" ...

Is there a way to implement a pipe function in TypeScript?

Introducing a unique pipe function implemented in plain JavaScript: const customPipe = (f, ...fs) => x => f === undefined ? x : customPipe(...fs)(f(x)) const exampleFunction = customPipe( x => x + 1, x => `wow ${x * 2} this is an amaz ...

Stop webpack from stripping out the crypto module in the nodejs API

Working on a node-js API within an nx workspace, I encountered a challenge with using the core crypto node-js module. It seems like webpack might be stripping it out. The code snippet causing the issue is: crypto.getRandomValues(new Uint32Array(1))[0].toS ...

What is the best way to eliminate the content of an element using javascript/typescript?

The progress bar I'm working with looks like this: <progress class="progress is-small" value="20" max="100">20%</progress> My goal is to use javascript to remove value="20", resulting in: <progre ...

Unable to locate the reference for 'bootstrap'

After trying to implement Bootstrap toast in an Angular Component, the following error message is displayed: "Cannot find name 'bootstrap'" Here is the HTML code similar to the Bootstrap documentation: <div class="toast" r ...

Error TS2345: The function with arguments of type '(req: any, res: any, ctx: any) => any' cannot be assigned to the parameter of type 'HttpResponseResolver<PathParams<string>'

Encountered an issue in a React TypeScript test case involving mock data. The error message received was: TS2345: Argument of type '(req: any, res: any, ctx: any) => any' is not assignable to parameter of type 'HttpResponseResolver<P ...

What causes interface to generate TS2345 error, while type does not?

In the code below: type FooType = { foo: string } function fooType(a: FooType & Partial<Record<string, string>>) { } function barType(a: FooType) { fooType(a) } interface FooInterface { foo: string } function fooInterface(a: FooInt ...

Find the TypeScript data type of an array that may be empty

Struggling to determine the TypeScript type of data being passed into my React component. The data could either be related to cats or dogs: my-component.tsx: export const MyComponent = { props: { data: any; // Ideally looking to utilize the union type & ...

Angular's observables were unable to be subscribed to in either the constructor or ngOnInit() functions

Currently, I am incorporating an observable concept into my application. In this setup, a service is called by component1 to emit an event that is then subscribed to by component 2. Below is the code snippet for reference: Service Code export class Mes ...

Vue composable yields a string value

I am currently using a Vue composable method that looks like this: import { ref } from 'vue'; const useCalculator = (num1: number, num2: number, operation: string) => { const result = ref(0); switch (operation) { case 'add& ...

Can you explain the purpose of FunctionConstructor in typeScript?

As I delved into the Typescript Ecmascript source code, I stumbled upon this intriguing snippet: interface FunctionConstructor { /** * Creates a new function. * @param args A list of arguments the function accepts. */ new(...args: st ...

Angular 8 combined with Mmenu light JS

Looking for guidance on integrating the Mmenu light JS plugin into an Angular 8 project. Wondering where to incorporate the 'mmenu-light.js' code. Any insights or advice would be greatly appreciated. Thank you! ...

Tips for transforming an Observable stream into an Observable Array

My goal is to fetch a list of dogs from a database and return it as an Observable<Dog[]>. However, whenever I attempt to convert the incoming stream to an array by using toArray() or any other method, no data is returned when calling the retrieveDo ...

Accessing the media player of your system while developing a VSCode extension using a nodejs backend: A comprehensive guide

I am currently utilizing the play-sound library in my project. I have experimented with two different code snippets, each resulting in a unique outcome, none of which are successful. When I implement const player = require('play-sound')({player: ...