Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@vscode/test-web

Package Overview
Dependencies
Maintainers
16
Versions
59
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@vscode/test-web - npm Package Compare versions

Comparing version 0.0.13 to 0.0.14

.yarnrc

11

CHANGELOG.md
# Changelog
## 0.0.14
* new option `--extensionPath` : A path pointing to a folder containing additional extensions to include. Argument can be provided multiple times.
* new option `--permission`: Permission granted to the opened browser: e.g. clipboard-read, clipboard-write. See full list of options [here](https://playwright.dev/docs/1.14/emulation#permissions). Argument can be provided multiple times.
* new option `--hideServerLog`: If set, hides the server log. Defaults to true when an extensionTestsPath is provided, otherwise false.
* close server when browser is closed
## 0.0.9
* new option `folderPath`: A local folder to open VS Code on. The folder content will be available as a virtual file system and opened as workspace.
### 0.0.1 |

@@ -4,0 +15,0 @@

6

fs-provider/dist/fsExtensionMain.js

@@ -28,7 +28,7 @@ /******/ (() => { // webpackBootstrap

function isEntry(e) {
return e && (e.type == vscode_1.FileType.Directory || e.type == vscode_1.FileType.File) && typeof e.name === 'string' && e.name.length > 0;
return e && (e.type === vscode_1.FileType.Directory || e.type === vscode_1.FileType.File) && typeof e.name === 'string' && e.name.length > 0;
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function isStat(e) {
return e && (e.type == vscode_1.FileType.Directory || e.type == vscode_1.FileType.File) && typeof e.ctime === 'number' && typeof e.mtime === 'number' && typeof e.size === 'number';
return e && (e.type === vscode_1.FileType.Directory || e.type === vscode_1.FileType.File) && typeof e.ctime === 'number' && typeof e.mtime === 'number' && typeof e.size === 'number';
}

@@ -559,3 +559,3 @@ function newFileStat(type, size) {

context.subscriptions.push(disposable);
console.log(`vscode-test-web-support fs provider registeres for ${fsProvider_1.SCHEME}, mount ${serverUri.toString()}`);
console.log(`vscode-test-web-support fs provider registers for ${fsProvider_1.SCHEME}, initial content from ${serverUri.toString()}`);
}

@@ -562,0 +562,0 @@ exports.activate = activate;

@@ -45,2 +45,6 @@ #!/usr/bin/env node

/**
* Do not show the server log. Defaults to `true` if a extensionTestsPath is provided, `false` otherwise.
*/
hideServerLog?: boolean;
/**
* Expose browser debugging on this port number, and wait for the debugger to attach before running tests.

@@ -60,3 +64,16 @@ */

folderUri?: string;
/**
* Permissions granted to the opened browser. An list of permissions can be found at
* https://playwright.dev/docs/api/class-browsercontext#browser-context-grant-permissions
* Example: [ 'clipboard-read', 'clipboard-write' ]
*/
permissions?: string[];
/**
* Absolute paths pointing to built-in extensions to include.
*/
extensionPaths?: string[];
}
export interface Disposable {
dispose(): void;
}
/**

@@ -70,2 +87,2 @@ * Runs the tests in a browser.

}): Promise<void>;
export declare function open(options: Options): Promise<void>;
export declare function open(options: Options): Promise<Disposable>;

@@ -21,3 +21,2 @@ #!/usr/bin/env node

async function runTests(options) {
var _a;
const config = {

@@ -28,19 +27,32 @@ extensionDevelopmentPath: options.extensionDevelopmentPath,

folderUri: options.folderUri,
folderMountPath: options.folderPath
folderMountPath: options.folderPath,
hideServerLog: true,
extensionPaths: options.extensionPaths
};
const port = 3000;
const server = await (0, main_1.runServer)(port, config);
const endpoint = `http://localhost:${port}`;
const result = await openInBrowser({
browserType: options.browserType,
endpoint,
headless: (_a = options.headless) !== null && _a !== void 0 ? _a : true,
devTools: options.devTools,
waitForDebugger: options.waitForDebugger,
return new Promise(async (s, e) => {
const endpoint = `http://localhost:${port}`;
const context = await openBrowser(endpoint, options);
context.once('close', () => server.close());
await context.exposeFunction('codeAutomationLog', (type, args) => {
console[type](...args);
});
await context.exposeFunction('codeAutomationExit', async (code) => {
var _a;
try {
await ((_a = context.browser()) === null || _a === void 0 ? void 0 : _a.close());
}
catch (error) {
console.error(`Error when closing browser: ${error}`);
}
server.close();
if (code === 0) {
s();
}
else {
e(new Error('Test failed'));
}
});
});
server.close();
if (result) {
return;
}
throw new Error('Test failed');
}

@@ -55,19 +67,22 @@ exports.runTests = runTests;

async function open(options) {
var _a;
const config = {
extensionDevelopmentPath: options.extensionDevelopmentPath,
extensionTestsPath: options.extensionTestsPath,
build: await getBuild(options.version),
folderUri: options.folderUri,
folderMountPath: options.folderPath
folderMountPath: options.folderPath,
extensionPaths: options.extensionPaths
};
const port = 3000;
await (0, main_1.runServer)(port, config);
const server = await (0, main_1.runServer)(port, config);
const endpoint = `http://localhost:${port}`;
await openInBrowser({
browserType: options.browserType,
endpoint,
headless: (_a = options.headless) !== null && _a !== void 0 ? _a : false,
devTools: options.devTools,
waitForDebugger: options.waitForDebugger
});
const context = await openBrowser(endpoint, options);
context.once('close', () => server.close());
return {
dispose: () => {
var _a;
server.close();
(_a = context.browser()) === null || _a === void 0 ? void 0 : _a.close();
}
};
}

@@ -77,33 +92,35 @@ exports.open = open;

const height = 800;
function openInBrowser(options) {
return new Promise(async (s) => {
var _a;
const args = [];
if (process.platform === 'linux' && options.browserType === 'chromium') {
args.push('--no-sandbox');
}
if (options.waitForDebugger) {
args.push(`--remote-debugging-port=${options.waitForDebugger}`);
}
const browser = await playwright[options.browserType].launch({ headless: options.headless, args, devtools: options.devTools });
const context = await browser.newContext();
const page = (_a = context.pages()[0]) !== null && _a !== void 0 ? _a : await context.newPage();
if (options.waitForDebugger) {
await page.waitForFunction(() => '__jsDebugIsReady' in globalThis);
}
await page.setViewportSize({ width, height });
await page.goto(options.endpoint);
await page.exposeFunction('codeAutomationLog', (type, args) => {
console[type](...args);
});
await page.exposeFunction('codeAutomationExit', async (code) => {
try {
await browser.close();
async function openBrowser(endpoint, options) {
var _a, _b;
const args = [];
if (process.platform === 'linux' && options.browserType === 'chromium') {
args.push('--no-sandbox');
}
if (options.waitForDebugger) {
args.push(`--remote-debugging-port=${options.waitForDebugger}`);
}
const headless = (_a = options.headless) !== null && _a !== void 0 ? _a : options.extensionDevelopmentPath !== undefined;
const browser = await playwright[options.browserType].launch({ headless, args, devtools: options.devTools });
const context = await browser.newContext();
if (options.permissions) {
context.grantPermissions(options.permissions);
}
// forcefully close browser if last page is closed. workaround for https://github.com/microsoft/playwright/issues/2946
let openPages = 0;
context.on('page', page => {
openPages++;
page.once('close', () => {
openPages--;
if (openPages === 0) {
browser.close();
}
catch (error) {
console.error(`Error when closing browser: ${error}`);
}
s(code === 0);
});
});
const page = (_b = context.pages()[0]) !== null && _b !== void 0 ? _b : await context.newPage();
if (options.waitForDebugger) {
await page.waitForFunction(() => '__jsDebugIsReady' in globalThis);
}
await page.setViewportSize({ width, height });
await page.goto(endpoint);
return context;
}

@@ -133,3 +150,3 @@ function validateStringOrUndefined(options, name) {

function valdiateBrowserType(browserType) {
if (browserType === 'undefined') {
if (browserType === undefined) {
return 'chromium';

@@ -144,2 +161,42 @@ }

}
function valdiatePermissions(permissions) {
if (permissions === undefined) {
return undefined;
}
function isValidPermission(p) {
return typeof p === 'string';
}
if (isValidPermission(permissions)) {
return [permissions];
}
if (Array.isArray(permissions) && permissions.every(isValidPermission)) {
return permissions;
}
console.log(`Invalid permission`);
showHelp();
process.exit(-1);
}
async function valdiateExtensionPaths(extensionPaths) {
if (extensionPaths === undefined) {
return undefined;
}
if (!Array.isArray(extensionPaths)) {
extensionPaths = [extensionPaths];
}
if (Array.isArray(extensionPaths)) {
const res = [];
for (const extensionPath of extensionPaths) {
if (typeof extensionPath === 'string') {
res.push(await validatePath(extensionPath));
}
else {
break;
}
}
return res;
}
console.log(`Invalid extensionPath`);
showHelp();
process.exit(-1);
}
async function validatePath(loc, isFile) {

@@ -180,20 +237,37 @@ loc = path.resolve(loc);

console.log('Usage:');
console.log(` --browserType 'chromium' | 'firefox' | 'webkit': The browser to launch`);
console.log(` --extensionDevelopmentPath path. [Optional]: A path pointing to a extension to include.`);
console.log(` --extensionTestsPath path. [Optional]: A path to a test module to run`);
console.log(` --version. 'insiders' (Default) | 'stable' | 'sources' [Optional]`);
console.log(` --open-devtools. Opens the dev tools [Optional]`);
console.log(` --headless. Whether to show the browser. Defaults to true when an extensionTestsPath is provided, otherwise false. [Optional]`);
console.log(` folderPath. A local folder to open VS Code on. The folder content will be available as a virtual file system`);
console.log(` --browserType 'chromium' | 'firefox' | 'webkit': The browser to launch. [Optional, default 'chromium']`);
console.log(` --extensionDevelopmentPath path: A path pointing to an extension under development to include. [Optional]`);
console.log(` --extensionTestsPath path: A path to a test module to run. [Optional]`);
console.log(` --version 'insiders' | 'stable' | 'sources' [Optional, default 'insiders']`);
console.log(` --open-devtools: If set, opens the dev tools [Optional]`);
console.log(` --headless: Whether to hide the browser. Defaults to true when an extensionTestsPath is provided, otherwise false. [Optional]`);
console.log(` --hideServerLog: Whether to hide the server log. Defaults to true when an extensionTestsPath is provided, otherwise false. [Optional]`);
console.log(` --permission: Permission granted in the opened browser: e.g. 'clipboard-read', 'clipboard-write': [Optional, Multiple]`);
console.log(` --folder-uri: workspace to open VS Code on. Ignored when folderPath is provided [Optional]`);
console.log(` --extensionPath: A path pointing to a folder containing additional extensions to include [Optional, Multiple]`);
console.log(` folderPath. A local folder to open VS Code on. The folder content will be available as a virtual file system. [Optional]`);
}
async function cliMain() {
const options = { string: ['extensionDevelopmentPath', 'extensionTestsPath', 'browserType', 'version', 'waitForDebugger', 'folder-uri', 'mount'], boolean: ['open-devtools', 'headless'] };
const options = {
string: ['extensionDevelopmentPath', 'extensionTestsPath', 'browserType', 'version', 'waitForDebugger', 'folder-uri', 'permission', 'extensionPath'],
boolean: ['open-devtools', 'headless', 'hideServerLog'],
unknown: arg => {
if (arg.startsWith('-')) {
console.log(`Unknown argument ${arg}`);
return false;
}
return true;
}
};
const args = minimist(process.argv.slice(2), options);
const browserType = valdiateBrowserType(args.browserType);
const version = validateVersion(args.version);
const extensionTestsPath = await validatePathOrUndefined(args, 'extensionTestsPath', true);
const extensionDevelopmentPath = await validatePathOrUndefined(args, 'extensionDevelopmentPath');
const extensionPaths = await valdiateExtensionPaths(args.extensionPath);
const version = validateVersion(args.version);
const devTools = validateBooleanOrUndefined(args, 'open-devtools');
const headless = validateBooleanOrUndefined(args, 'headless');
const devTools = validateBooleanOrUndefined(args, 'open-devtools');
const port = validatePortNumber(args.waitForDebugger);
const permissions = valdiatePermissions(args.permission);
const hideServerLog = validateBooleanOrUndefined(args, 'hideServerLog');
const waitForDebugger = validatePortNumber(args.waitForDebugger);
let folderUri = validateStringOrUndefined(args, 'folder-uri');

@@ -219,6 +293,9 @@ let folderPath;

devTools,
waitForDebugger: port,
waitForDebugger,
folderUri,
folderPath,
headless
headless,
hideServerLog,
permissions,
extensionPaths
});

@@ -232,6 +309,9 @@ }

devTools,
waitForDebugger: port,
waitForDebugger,
folderUri,
folderPath,
headless
headless,
hideServerLog,
permissions,
extensionPaths
});

@@ -238,0 +318,0 @@ }

@@ -16,3 +16,5 @@ "use strict";

const app = new Koa();
app.use(morgan('dev'));
if (!config.hideServerLog) {
app.use(morgan('dev'));
}
// this is here such that the iframe worker can fetch the extension files

@@ -24,6 +26,2 @@ app.use((ctx, next) => {

app.use(kmount('/static', kstatic(path.join(__dirname, '../static'))));
if (config.extensionPath) {
console.log('Serving extensions from ' + config.extensionPath);
app.use(kmount('/static/extensions', kstatic(config.extensionPath, { hidden: true })));
}
if (config.extensionDevelopmentPath) {

@@ -37,2 +35,8 @@ console.log('Serving dev extensions from ' + config.extensionDevelopmentPath);

(0, mounts_1.configureMounts)(config, app);
if (config.extensionPaths) {
config.extensionPaths.forEach((extensionPath, index) => {
console.log('Serving additional built-in extensions from ' + extensionPath);
app.use(kmount(`/static/extensions/${index}`, kstatic(extensionPath, { hidden: true })));
});
}
app.use((0, workbench_1.default)(config));

@@ -39,0 +43,0 @@ return app;

@@ -14,3 +14,3 @@ "use strict";

const mountPrefix = '/static/mount';
exports.fsProviderExtensionPrefix = '/static/fsproviderextension';
exports.fsProviderExtensionPrefix = '/static/extensions/fs';
exports.fsProviderFolderUri = 'vscode-test-web://mount/';

@@ -17,0 +17,0 @@ function configureMounts(config, app) {

@@ -55,8 +55,10 @@ "use strict";

const options = {};
if (config.extensionPath) {
options.additionalBuiltinExtensions = await (0, extensions_1.scanForExtensions)(config.extensionPath, {
scheme: ctx.protocol,
authority: ctx.host,
path: '/static/extensions',
});
if (config.extensionPaths) {
await Promise.all(config.extensionPaths.map(async (extensionPath, index) => {
options.additionalBuiltinExtensions = await (0, extensions_1.scanForExtensions)(extensionPath, {
scheme: ctx.protocol,
authority: ctx.host,
path: `/static/extensions/${index}`,
});
}));
}

@@ -63,0 +65,0 @@ if (config.extensionDevelopmentPath) {

{
"name": "@vscode/test-web",
"version": "0.0.13",
"version": "0.0.14",
"scripts": {
"init": "yarn --cwd=fs-provider && yarn --cwd=sample",
"install-extensions": "yarn --cwd=fs-provider && yarn --cwd=sample",
"compile": "tsc -p ./ && yarn compile-fs-provider",

@@ -7,0 +7,0 @@ "watch": "tsc -w -p ./",

# @vscode/test-web
![Test Status Badge](https://github.com/microsoft/vscode-test-web/workflows/Tests/badge.svg)
This module helps testing [VS Code web extensions](https://code.visualstudio.com/api/extension-guides/web-extensions) locally.
[![Test Status Badge](https://github.com/microsoft/vscode-test-web/workflows/Tests/badge.svg)](https://github.com/microsoft/vscode-test-web/actions/workflows/tests.yml)
[![npm Package](https://img.shields.io/npm/v/@vscode/test-web.svg?style=flat-square)](https://www.npmjs.org/package/@vscode/test-web)
[![NPM Downloads](https://img.shields.io/npm/dm/@vscode/test-web.svg)](https://npmjs.org/package/@vscode/test-web)
The node module runs a local web server that serves VS Code for the browser including the extensions located at the given local path. Additionally the extension tests are automatically run.

@@ -33,3 +36,3 @@

VS Code Browser will open on a virtual workspace (scheme `vscode-test-web`), backed by a file system provider that gets the file/folder data from the local disk. Changes to the file system are kept in memory and are not written back to disk.
VS Code for the Web will open on a virtual workspace (scheme `vscode-test-web`), backed by a file system provider that gets the file/folder data from the local disk. Changes to the file system are kept in memory and are not written back to disk.

@@ -59,12 +62,16 @@ Via API:

CLI options:
```
--browserType 'chromium' | 'firefox' | 'webkit': The browser to launch
--extensionDevelopmentPath path. [Optional]: A path pointing to a extension to include.
--extensionTestsPath path. [Optional]: A path to a test module to run
--version. 'insiders' (Default) | 'stable' | 'sources' [Optional]
--open-devtools. Opens the dev tools [Optional]
--headless. Whether to show the browser. Defaults to true when an extensionTestsPath is provided, otherwise false. [Optional]
folderPath. A local folder to open VS Code on. The folder content will be available as a virtual file system`
```
|Option|Argument Description||
|-----|-----|----|
| --browserType | The browser to launch: `chromium` (default), `firefox` or `webkit` |
| --extensionDevelopmentPath | A path pointing to an extension under development to include. |
| --extensionTestsPath | A path to a test module to run. |
| --version | `insiders` (default), `stable` or `sources`.<br>For sources, also run `yarn web` in a vscode repo |
| --open-devtools| If set, opens the dev tools |
| --headless| If set, hides the browser. Defaults to true when an extensionTestsPath is provided, otherwise false. |
| --hideServerLog| If set, hides the server log. Defaults to true when an extensionTestsPath is provided, otherwise false. |
| --permission| Permission granted to the opened browser: e.g. `clipboard-read`, `clipboard-write`. See [full list of options](https://playwright.dev/docs/api/class-browsercontext#browser-context-grant-permissions). Argument can be provided multiple times. |
| --folder-uri | URI of the workspace to open VS Code on. Ignored when `folderPath` is provided |
| --extensionPath | A path pointing to a folder containing additional extensions to include. Argument can be provided multiple times. |
| folderPath | A local folder to open VS Code on. The folder content will be available as a virtual file system and opened as workspace. |

@@ -75,3 +82,3 @@ Corresponding options are available in the API.

- `yarn install`
- `yarn && yarn install-extensions`
- Make necessary changes in [`src`](./src)

@@ -78,0 +85,0 @@ - `yarn compile` (or `yarn watch`)

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc