@vscode/test-web 0.0.13 → 0.0.17

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/out/index.js CHANGED
@@ -1,233 +1,365 @@
1
- #!/usr/bin/env node
2
- "use strict";
3
- /* eslint-disable header/header */
4
- Object.defineProperty(exports, "__esModule", { value: true });
5
- exports.open = exports.runTests = void 0;
6
- /*---------------------------------------------------------------------------------------------
7
- * Copyright (c) Microsoft Corporation. All rights reserved.
8
- * Licensed under the MIT License. See License.txt in the project root for license information.
9
- *--------------------------------------------------------------------------------------------*/
10
- const main_1 = require("./server/main");
11
- const download_1 = require("./server/download");
12
- const playwright = require("playwright");
13
- const minimist = require("minimist");
14
- const path = require("path");
15
- /**
16
- * Runs the tests in a browser.
17
- *
18
- * @param options The options defining browser type, extension and test location.
19
- */
20
- async function runTests(options) {
21
- var _a;
22
- const config = {
23
- extensionDevelopmentPath: options.extensionDevelopmentPath,
24
- extensionTestsPath: options.extensionTestsPath,
25
- build: await getBuild(options.version),
26
- folderUri: options.folderUri,
27
- folderMountPath: options.folderPath
28
- };
29
- const port = 3000;
30
- const server = await (0, main_1.runServer)(port, config);
31
- const endpoint = `http://localhost:${port}`;
32
- const result = await openInBrowser({
33
- browserType: options.browserType,
34
- endpoint,
35
- headless: (_a = options.headless) !== null && _a !== void 0 ? _a : true,
36
- devTools: options.devTools,
37
- waitForDebugger: options.waitForDebugger,
38
- });
39
- server.close();
40
- if (result) {
41
- return;
42
- }
43
- throw new Error('Test failed');
44
- }
45
- exports.runTests = runTests;
46
- async function getBuild(version) {
47
- if (version === 'sources') {
48
- return { type: 'sources' };
49
- }
50
- return await (0, download_1.downloadAndUnzipVSCode)(version === 'stable' ? 'stable' : 'insider');
51
- }
52
- async function open(options) {
53
- var _a;
54
- const config = {
55
- extensionDevelopmentPath: options.extensionDevelopmentPath,
56
- build: await getBuild(options.version),
57
- folderUri: options.folderUri,
58
- folderMountPath: options.folderPath
59
- };
60
- const port = 3000;
61
- await (0, main_1.runServer)(port, config);
62
- const endpoint = `http://localhost:${port}`;
63
- await openInBrowser({
64
- browserType: options.browserType,
65
- endpoint,
66
- headless: (_a = options.headless) !== null && _a !== void 0 ? _a : false,
67
- devTools: options.devTools,
68
- waitForDebugger: options.waitForDebugger
69
- });
70
- }
71
- exports.open = open;
72
- const width = 1200;
73
- const height = 800;
74
- function openInBrowser(options) {
75
- return new Promise(async (s) => {
76
- var _a;
77
- const args = [];
78
- if (process.platform === 'linux' && options.browserType === 'chromium') {
79
- args.push('--no-sandbox');
80
- }
81
- if (options.waitForDebugger) {
82
- args.push(`--remote-debugging-port=${options.waitForDebugger}`);
83
- }
84
- const browser = await playwright[options.browserType].launch({ headless: options.headless, args, devtools: options.devTools });
85
- const context = await browser.newContext();
86
- const page = (_a = context.pages()[0]) !== null && _a !== void 0 ? _a : await context.newPage();
87
- if (options.waitForDebugger) {
88
- await page.waitForFunction(() => '__jsDebugIsReady' in globalThis);
89
- }
90
- await page.setViewportSize({ width, height });
91
- await page.goto(options.endpoint);
92
- await page.exposeFunction('codeAutomationLog', (type, args) => {
93
- console[type](...args);
94
- });
95
- await page.exposeFunction('codeAutomationExit', async (code) => {
96
- try {
97
- await browser.close();
98
- }
99
- catch (error) {
100
- console.error(`Error when closing browser: ${error}`);
101
- }
102
- s(code === 0);
103
- });
104
- });
105
- }
106
- function validateStringOrUndefined(options, name) {
107
- const value = options[name];
108
- if (value === undefined || (typeof value === 'string')) {
109
- return value;
110
- }
111
- console.log(`'${name}' needs to be a string value.`);
112
- showHelp();
113
- process.exit(-1);
114
- }
115
- async function validatePathOrUndefined(options, name, isFile) {
116
- const loc = validateStringOrUndefined(options, name);
117
- return loc && validatePath(loc, isFile);
118
- }
119
- function validateBooleanOrUndefined(options, name) {
120
- const value = options[name];
121
- if (value === undefined || (typeof value === 'boolean')) {
122
- return value;
123
- }
124
- console.log(`'${name}' needs to be a boolean value.`);
125
- showHelp();
126
- process.exit(-1);
127
- }
128
- function valdiateBrowserType(browserType) {
129
- if (browserType === 'undefined') {
130
- return 'chromium';
131
- }
132
- if ((typeof browserType === 'string') && ['chromium', 'firefox', 'webkit'].includes(browserType)) {
133
- return browserType;
134
- }
135
- console.log(`Invalid browser type.`);
136
- showHelp();
137
- process.exit(-1);
138
- }
139
- async function validatePath(loc, isFile) {
140
- loc = path.resolve(loc);
141
- if (isFile) {
142
- if (!await (0, download_1.fileExists)(loc)) {
143
- console.log(`'${loc}' must be an existing file.`);
144
- process.exit(-1);
145
- }
146
- }
147
- else {
148
- if (!await (0, download_1.directoryExists)(loc)) {
149
- console.log(`'${loc}' must be an existing folder.`);
150
- process.exit(-1);
151
- }
152
- }
153
- return loc;
154
- }
155
- function validateVersion(version) {
156
- if (version === undefined || ((typeof version === 'string') && ['insiders', 'stable', 'sources'].includes(version))) {
157
- return version;
158
- }
159
- console.log(`Invalid version.`);
160
- showHelp();
161
- process.exit(-1);
162
- }
163
- function validatePortNumber(port) {
164
- if (typeof port === 'string') {
165
- const number = Number.parseInt(port);
166
- if (!Number.isNaN(number) && number >= 0) {
167
- return number;
168
- }
169
- }
170
- return undefined;
171
- }
172
- function showHelp() {
173
- console.log('Usage:');
174
- console.log(` --browserType 'chromium' | 'firefox' | 'webkit': The browser to launch`);
175
- console.log(` --extensionDevelopmentPath path. [Optional]: A path pointing to a extension to include.`);
176
- console.log(` --extensionTestsPath path. [Optional]: A path to a test module to run`);
177
- console.log(` --version. 'insiders' (Default) | 'stable' | 'sources' [Optional]`);
178
- console.log(` --open-devtools. Opens the dev tools [Optional]`);
179
- console.log(` --headless. Whether to show the browser. Defaults to true when an extensionTestsPath is provided, otherwise false. [Optional]`);
180
- console.log(` folderPath. A local folder to open VS Code on. The folder content will be available as a virtual file system`);
181
- }
182
- async function cliMain() {
183
- const options = { string: ['extensionDevelopmentPath', 'extensionTestsPath', 'browserType', 'version', 'waitForDebugger', 'folder-uri', 'mount'], boolean: ['open-devtools', 'headless'] };
184
- const args = minimist(process.argv.slice(2), options);
185
- const browserType = valdiateBrowserType(args.browserType);
186
- const version = validateVersion(args.version);
187
- const extensionTestsPath = await validatePathOrUndefined(args, 'extensionTestsPath', true);
188
- const extensionDevelopmentPath = await validatePathOrUndefined(args, 'extensionDevelopmentPath');
189
- const headless = validateBooleanOrUndefined(args, 'headless');
190
- const devTools = validateBooleanOrUndefined(args, 'open-devtools');
191
- const port = validatePortNumber(args.waitForDebugger);
192
- let folderUri = validateStringOrUndefined(args, 'folder-uri');
193
- let folderPath;
194
- const inputs = args._;
195
- if (inputs.length) {
196
- const input = await validatePath(inputs[0]);
197
- if (input) {
198
- folderPath = input;
199
- if (folderUri) {
200
- console.log(`Local folder provided as input, ignoring 'folder-uri'`);
201
- folderUri = undefined;
202
- }
203
- }
204
- }
205
- if (extensionTestsPath) {
206
- runTests({
207
- extensionTestsPath,
208
- extensionDevelopmentPath,
209
- browserType,
210
- version,
211
- devTools,
212
- waitForDebugger: port,
213
- folderUri,
214
- folderPath,
215
- headless
216
- });
217
- }
218
- else {
219
- open({
220
- extensionDevelopmentPath,
221
- browserType,
222
- version,
223
- devTools,
224
- waitForDebugger: port,
225
- folderUri,
226
- folderPath,
227
- headless
228
- });
229
- }
230
- }
231
- if (require.main === module) {
232
- cliMain();
233
- }
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ /* eslint-disable header/header */
4
+ Object.defineProperty(exports, "__esModule", { value: true });
5
+ exports.open = exports.runTests = void 0;
6
+ /*---------------------------------------------------------------------------------------------
7
+ * Copyright (c) Microsoft Corporation. All rights reserved.
8
+ * Licensed under the MIT License. See License.txt in the project root for license information.
9
+ *--------------------------------------------------------------------------------------------*/
10
+ const main_1 = require("./server/main");
11
+ const download_1 = require("./server/download");
12
+ const playwright = require("playwright");
13
+ const minimist = require("minimist");
14
+ const path = require("path");
15
+ /**
16
+ * Runs the tests in a browser.
17
+ *
18
+ * @param options The options defining browser type, extension and test location.
19
+ */
20
+ async function runTests(options) {
21
+ var _a, _b, _c;
22
+ const config = {
23
+ extensionDevelopmentPath: options.extensionDevelopmentPath,
24
+ extensionTestsPath: options.extensionTestsPath,
25
+ build: await getBuild(options),
26
+ folderUri: options.folderUri,
27
+ folderMountPath: options.folderPath,
28
+ hideServerLog: (_a = options.hideServerLog) !== null && _a !== void 0 ? _a : true,
29
+ extensionPaths: options.extensionPaths
30
+ };
31
+ const host = (_b = options.host) !== null && _b !== void 0 ? _b : 'localhost';
32
+ const port = (_c = options.port) !== null && _c !== void 0 ? _c : 3000;
33
+ const server = await (0, main_1.runServer)(host, port, config);
34
+ return new Promise(async (s, e) => {
35
+ const endpoint = `http://${host}:${port}`;
36
+ const context = await openBrowser(endpoint, options);
37
+ context.once('close', () => server.close());
38
+ await context.exposeFunction('codeAutomationLog', (type, args) => {
39
+ console[type](...args);
40
+ });
41
+ await context.exposeFunction('codeAutomationExit', async (code) => {
42
+ var _a;
43
+ try {
44
+ await ((_a = context.browser()) === null || _a === void 0 ? void 0 : _a.close());
45
+ }
46
+ catch (error) {
47
+ console.error(`Error when closing browser: ${error}`);
48
+ }
49
+ server.close();
50
+ if (code === 0) {
51
+ s();
52
+ }
53
+ else {
54
+ e(new Error('Test failed'));
55
+ }
56
+ });
57
+ });
58
+ }
59
+ exports.runTests = runTests;
60
+ async function getBuild(options) {
61
+ if (options.vsCodeDevPath) {
62
+ return {
63
+ type: 'sources',
64
+ location: options.vsCodeDevPath
65
+ };
66
+ }
67
+ const quality = options.quality || options.version;
68
+ return await (0, download_1.downloadAndUnzipVSCode)(quality === 'stable' ? 'stable' : 'insider');
69
+ }
70
+ async function open(options) {
71
+ var _a, _b, _c;
72
+ const config = {
73
+ extensionDevelopmentPath: options.extensionDevelopmentPath,
74
+ extensionTestsPath: options.extensionTestsPath,
75
+ build: await getBuild(options),
76
+ folderUri: options.folderUri,
77
+ folderMountPath: options.folderPath,
78
+ hideServerLog: (_a = options.hideServerLog) !== null && _a !== void 0 ? _a : true,
79
+ extensionPaths: options.extensionPaths
80
+ };
81
+ const host = (_b = options.host) !== null && _b !== void 0 ? _b : 'localhost';
82
+ const port = (_c = options.port) !== null && _c !== void 0 ? _c : 3000;
83
+ const server = await (0, main_1.runServer)(host, port, config);
84
+ const endpoint = `http://${host}:${port}`;
85
+ const context = await openBrowser(endpoint, options);
86
+ context.once('close', () => server.close());
87
+ return {
88
+ dispose: () => {
89
+ var _a;
90
+ server.close();
91
+ (_a = context.browser()) === null || _a === void 0 ? void 0 : _a.close();
92
+ }
93
+ };
94
+ }
95
+ exports.open = open;
96
+ const width = 1200;
97
+ const height = 800;
98
+ async function openBrowser(endpoint, options) {
99
+ var _a, _b;
100
+ const args = [];
101
+ if (process.platform === 'linux' && options.browserType === 'chromium') {
102
+ args.push('--no-sandbox');
103
+ }
104
+ if (options.waitForDebugger) {
105
+ args.push(`--remote-debugging-port=${options.waitForDebugger}`);
106
+ }
107
+ const headless = (_a = options.headless) !== null && _a !== void 0 ? _a : options.extensionTestsPath !== undefined;
108
+ const browser = await playwright[options.browserType].launch({ headless, args, devtools: options.devTools });
109
+ const context = await browser.newContext();
110
+ if (options.permissions) {
111
+ context.grantPermissions(options.permissions);
112
+ }
113
+ // forcefully close browser if last page is closed. workaround for https://github.com/microsoft/playwright/issues/2946
114
+ let openPages = 0;
115
+ context.on('page', page => {
116
+ openPages++;
117
+ page.once('close', () => {
118
+ openPages--;
119
+ if (openPages === 0) {
120
+ browser.close();
121
+ }
122
+ });
123
+ });
124
+ const page = (_b = context.pages()[0]) !== null && _b !== void 0 ? _b : await context.newPage();
125
+ if (options.waitForDebugger) {
126
+ await page.waitForFunction(() => '__jsDebugIsReady' in globalThis);
127
+ }
128
+ if (options.verbose) {
129
+ page.on('console', (message) => {
130
+ console.log(message.text());
131
+ });
132
+ }
133
+ await page.setViewportSize({ width, height });
134
+ await page.goto(endpoint);
135
+ return context;
136
+ }
137
+ function validateStringOrUndefined(options, name) {
138
+ const value = options[name];
139
+ if (value === undefined || (typeof value === 'string')) {
140
+ return value;
141
+ }
142
+ console.log(`'${name}' needs to be a string value.`);
143
+ showHelp();
144
+ process.exit(-1);
145
+ }
146
+ async function validatePathOrUndefined(options, name, isFile) {
147
+ const loc = validateStringOrUndefined(options, name);
148
+ return loc && validatePath(loc, isFile);
149
+ }
150
+ function validateBooleanOrUndefined(options, name) {
151
+ const value = options[name];
152
+ if (value === undefined || (typeof value === 'boolean')) {
153
+ return value;
154
+ }
155
+ console.log(`'${name}' needs to be a boolean value.`);
156
+ showHelp();
157
+ process.exit(-1);
158
+ }
159
+ function valdiateBrowserType(browserType) {
160
+ if (browserType === undefined) {
161
+ return 'chromium';
162
+ }
163
+ if ((typeof browserType === 'string') && ['chromium', 'firefox', 'webkit'].includes(browserType)) {
164
+ return browserType;
165
+ }
166
+ console.log(`Invalid browser type.`);
167
+ showHelp();
168
+ process.exit(-1);
169
+ }
170
+ function valdiatePermissions(permissions) {
171
+ if (permissions === undefined) {
172
+ return undefined;
173
+ }
174
+ function isValidPermission(p) {
175
+ return typeof p === 'string';
176
+ }
177
+ if (isValidPermission(permissions)) {
178
+ return [permissions];
179
+ }
180
+ if (Array.isArray(permissions) && permissions.every(isValidPermission)) {
181
+ return permissions;
182
+ }
183
+ console.log(`Invalid permission`);
184
+ showHelp();
185
+ process.exit(-1);
186
+ }
187
+ async function valdiateExtensionPaths(extensionPaths) {
188
+ if (extensionPaths === undefined) {
189
+ return undefined;
190
+ }
191
+ if (!Array.isArray(extensionPaths)) {
192
+ extensionPaths = [extensionPaths];
193
+ }
194
+ if (Array.isArray(extensionPaths)) {
195
+ const res = [];
196
+ for (const extensionPath of extensionPaths) {
197
+ if (typeof extensionPath === 'string') {
198
+ res.push(await validatePath(extensionPath));
199
+ }
200
+ else {
201
+ break;
202
+ }
203
+ }
204
+ return res;
205
+ }
206
+ console.log(`Invalid extensionPath`);
207
+ showHelp();
208
+ process.exit(-1);
209
+ }
210
+ async function validatePath(loc, isFile) {
211
+ loc = path.resolve(loc);
212
+ if (isFile) {
213
+ if (!await (0, download_1.fileExists)(loc)) {
214
+ console.log(`'${loc}' must be an existing file.`);
215
+ process.exit(-1);
216
+ }
217
+ }
218
+ else {
219
+ if (!await (0, download_1.directoryExists)(loc)) {
220
+ console.log(`'${loc}' must be an existing folder.`);
221
+ process.exit(-1);
222
+ }
223
+ }
224
+ return loc;
225
+ }
226
+ function validateQuality(quality, version, vsCodeDevPath) {
227
+ if (version) {
228
+ console.log(`--version has been replaced by --quality`);
229
+ quality = quality || version;
230
+ }
231
+ if (vsCodeDevPath && quality) {
232
+ console.log(`Sources folder is provided as input, quality is ignored.`);
233
+ return undefined;
234
+ }
235
+ if (quality === undefined || ((typeof quality === 'string') && ['insiders', 'stable'].includes(quality))) {
236
+ return quality;
237
+ }
238
+ if (version === 'sources') {
239
+ console.log(`Instead of version=sources use 'sourcesPath' with the location of the VS Code repository.`);
240
+ }
241
+ else {
242
+ console.log(`Invalid quality.`);
243
+ }
244
+ showHelp();
245
+ process.exit(-1);
246
+ }
247
+ function validatePortNumber(port) {
248
+ if (typeof port === 'string') {
249
+ const number = Number.parseInt(port);
250
+ if (!Number.isNaN(number) && number >= 0) {
251
+ return number;
252
+ }
253
+ }
254
+ return undefined;
255
+ }
256
+ function showHelp() {
257
+ console.log('Usage:');
258
+ console.log(` --browserType 'chromium' | 'firefox' | 'webkit': The browser to launch. [Optional, defaults to 'chromium']`);
259
+ console.log(` --extensionDevelopmentPath path: A path pointing to an extension under development to include. [Optional]`);
260
+ console.log(` --extensionTestsPath path: A path to a test module to run. [Optional]`);
261
+ console.log(` --quality 'insiders' | 'stable' [Optional, default 'insiders', ignored when running from sources]`);
262
+ console.log(` --sourcesPath path: If provided, running from VS Code sources at the given location [Optional]`);
263
+ console.log(` --open-devtools: If set, opens the dev tools [Optional]`);
264
+ console.log(` --headless: Whether to hide the browser. Defaults to true when an extensionTestsPath is provided, otherwise false. [Optional]`);
265
+ console.log(` --permission: Permission granted in the opened browser: e.g. 'clipboard-read', 'clipboard-write': [Optional, Multiple]`);
266
+ console.log(` --folder-uri: workspace to open VS Code on. Ignored when folderPath is provided [Optional]`);
267
+ console.log(` --extensionPath: A path pointing to a folder containing additional extensions to include [Optional, Multiple]`);
268
+ console.log(` --host: The host name the server is opened on [Optional, defaults to localhost]`);
269
+ console.log(` --port: The port the server is opened on [Optional, defaults to 3000]`);
270
+ console.log(` --open-devtools: If set, opens the dev tools [Optional]`);
271
+ console.log(` --verbose: If set, prints out more information when running the server [Optional]`);
272
+ console.log(` --hideServerLog: Whether to hide the server log. Defaults to true when an extensionTestsPath is provided, otherwise false. [Optional]`);
273
+ console.log(` folderPath. A local folder to open VS Code on. The folder content will be available as a virtual file system. [Optional]`);
274
+ }
275
+ async function cliMain() {
276
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
277
+ const manifest = require('../package.json');
278
+ console.log(`${manifest.name}: ${manifest.version}`);
279
+ const options = {
280
+ string: ['extensionDevelopmentPath', 'extensionTestsPath', 'browserType', 'quality', 'version', 'waitForDebugger', 'folder-uri', 'permission', 'extensionPath', 'sourcesPath', 'host', 'port'],
281
+ boolean: ['open-devtools', 'headless', 'hideServerLog', 'help', 'verbose'],
282
+ unknown: arg => {
283
+ if (arg.startsWith('-')) {
284
+ console.log(`Unknown argument ${arg}`);
285
+ showHelp();
286
+ process.exit();
287
+ }
288
+ return true;
289
+ }
290
+ };
291
+ const args = minimist(process.argv.slice(2), options);
292
+ if (args.help) {
293
+ showHelp();
294
+ process.exit();
295
+ }
296
+ const browserType = valdiateBrowserType(args.browserType);
297
+ const extensionTestsPath = await validatePathOrUndefined(args, 'extensionTestsPath', true);
298
+ const extensionDevelopmentPath = await validatePathOrUndefined(args, 'extensionDevelopmentPath');
299
+ const extensionPaths = await valdiateExtensionPaths(args.extensionPath);
300
+ const vsCodeDevPath = await validatePathOrUndefined(args, 'sourcesPath');
301
+ const quality = validateQuality(args.quality, args.version, vsCodeDevPath);
302
+ const devTools = validateBooleanOrUndefined(args, 'open-devtools');
303
+ const headless = validateBooleanOrUndefined(args, 'headless');
304
+ const permissions = valdiatePermissions(args.permission);
305
+ const hideServerLog = validateBooleanOrUndefined(args, 'hideServerLog');
306
+ const verbose = validateBooleanOrUndefined(args, 'verbose');
307
+ const port = validatePortNumber(args.port);
308
+ const host = validateStringOrUndefined(args, 'host');
309
+ const waitForDebugger = validatePortNumber(args.waitForDebugger);
310
+ let folderUri = validateStringOrUndefined(args, 'folder-uri');
311
+ let folderPath;
312
+ const inputs = args._;
313
+ if (inputs.length) {
314
+ const input = await validatePath(inputs[0]);
315
+ if (input) {
316
+ folderPath = input;
317
+ if (folderUri) {
318
+ console.log(`Local folder provided as input, ignoring 'folder-uri'`);
319
+ folderUri = undefined;
320
+ }
321
+ }
322
+ }
323
+ if (extensionTestsPath) {
324
+ runTests({
325
+ extensionTestsPath,
326
+ extensionDevelopmentPath,
327
+ browserType,
328
+ quality,
329
+ devTools,
330
+ waitForDebugger,
331
+ folderUri,
332
+ folderPath,
333
+ headless,
334
+ hideServerLog,
335
+ permissions,
336
+ extensionPaths,
337
+ vsCodeDevPath,
338
+ verbose,
339
+ host,
340
+ port
341
+ });
342
+ }
343
+ else {
344
+ open({
345
+ extensionDevelopmentPath,
346
+ browserType,
347
+ quality,
348
+ devTools,
349
+ waitForDebugger,
350
+ folderUri,
351
+ folderPath,
352
+ headless,
353
+ hideServerLog,
354
+ permissions,
355
+ extensionPaths,
356
+ vsCodeDevPath,
357
+ verbose,
358
+ host,
359
+ port
360
+ });
361
+ }
362
+ }
363
+ if (require.main === module) {
364
+ cliMain();
365
+ }