Archived
1
0

chore(vscode): update to 1.54.2

This commit is contained in:
Joe Previte
2021-03-11 10:27:10 -07:00
1459 changed files with 53404 additions and 51004 deletions

View File

@ -1,6 +1,6 @@
{
"name": "vscode-automation",
"version": "1.53.0",
"version": "1.54.0",
"description": "VS Code UI automation driver",
"author": {
"name": "Microsoft Corporation"
@ -35,4 +35,4 @@
"vscode-uri": "^2.0.3",
"watch": "^1.0.2"
}
}
}

View File

@ -51,6 +51,10 @@ export class Application {
return !!this.options.remote;
}
get web(): boolean {
return !!this.options.web;
}
private _workspacePathOrFolder: string;
get workspacePathOrFolder(): string {
return this._workspacePathOrFolder;
@ -69,7 +73,12 @@ export class Application {
await this.code.waitForElement('.explorer-folders-view');
if (expectWalkthroughPart) {
await this.code.waitForActiveElement(`.editor-instance[data-editor-id="workbench.editor.walkThroughPart"] > div > div[tabIndex="0"]`);
if (this.quality === Quality.Stable) {
// TODO@bpasero remove me in March 2021
await this.code.waitForActiveElement(`.editor-instance[data-editor-id="workbench.editor.walkThroughPart"] > div > div[tabIndex="0"]`);
} else {
await this.code.waitForElement(`.editor-instance > div > div.welcomePageFocusElement[tabIndex="0"]`);
}
}
}

View File

@ -120,7 +120,7 @@ export async function spawn(options: SpawnOptions): Promise<Code> {
let child: cp.ChildProcess | undefined;
let connectDriver: typeof connectElectronDriver;
copyExtension(options, 'vscode-notebook-tests');
copyExtension(options.extensionsPath, 'vscode-notebook-tests');
if (options.web) {
await launch(options.userDataDir, options.workspacePath, options.codePath, options.extensionsPath);
@ -138,23 +138,36 @@ export async function spawn(options: SpawnOptions): Promise<Code> {
'--disable-telemetry',
'--no-cached-data',
'--disable-updates',
'--disable-keytar',
'--disable-crash-reporter',
`--extensions-dir=${options.extensionsPath}`,
`--user-data-dir=${options.userDataDir}`,
'--driver', handle
];
if (process.platform === 'linux') {
args.push('--disable-gpu'); // Linux has trouble in VMs to render properly with GPU enabled
}
if (options.remote) {
// Replace workspace path with URI
args[0] = `--${options.workspacePath.endsWith('.code-workspace') ? 'file' : 'folder'}-uri=vscode-remote://test+test/${URI.file(options.workspacePath).path}`;
if (codePath) {
// running against a build: copy the test resolver extension
copyExtension(options, 'vscode-test-resolver');
copyExtension(options.extensionsPath, 'vscode-test-resolver');
}
args.push('--enable-proposed-api=vscode.vscode-test-resolver');
const remoteDataDir = `${options.userDataDir}-server`;
mkdirp.sync(remoteDataDir);
if (codePath) {
// running against a build: copy the test resolver extension into remote extensions dir
const remoteExtensionsDir = path.join(remoteDataDir, 'extensions');
mkdirp.sync(remoteExtensionsDir);
copyExtension(remoteExtensionsDir, 'vscode-notebook-tests');
}
env['TESTRESOLVER_DATA_FOLDER'] = remoteDataDir;
}
@ -186,11 +199,11 @@ export async function spawn(options: SpawnOptions): Promise<Code> {
return connect(connectDriver, child, outPath, handle, options.logger);
}
async function copyExtension(options: SpawnOptions, extId: string): Promise<void> {
const testResolverExtPath = path.join(options.extensionsPath, extId);
if (!fs.existsSync(testResolverExtPath)) {
async function copyExtension(extensionsPath: string, extId: string): Promise<void> {
const dest = path.join(extensionsPath, extId);
if (!fs.existsSync(dest)) {
const orig = path.join(repoPath, 'extensions', extId);
await new Promise((c, e) => ncp(orig, testResolverExtPath, err => err ? e(err) : c()));
await new Promise<void>((c, e) => ncp(orig, dest, err => err ? e(err) : c()));
}
}

View File

@ -32,6 +32,12 @@ export class Extensions extends Viewlet {
await this.code.waitAndClick(SEARCH_BOX);
await this.code.waitForActiveElement(SEARCH_BOX);
await this.code.waitForTypeInEditor(SEARCH_BOX, `@id:${id}`);
await this.code.waitForElement(`div.extensions-viewlet[id="workbench.view.extensions"] .monaco-list-row[data-extension-id="${id}"]`);
}
async openExtension(id: string): Promise<any> {
await this.searchForExtension(id);
await this.code.waitAndClick(`div.extensions-viewlet[id="workbench.view.extensions"] .monaco-list-row[data-extension-id="${id}"]`);
}
async installExtension(id: string, waitUntilEnabled: boolean): Promise<void> {

View File

@ -101,6 +101,7 @@ export async function launch(userDataDir: string, _workspacePath: string, codeSe
VSCODE_REMOTE_SERVER_PATH: codeServerPath,
...process.env
};
const args = ['--browser', 'none', '--driver', 'web', '--extensions-dir', extPath];
let serverLocation: string | undefined;
if (codeServerPath) {
serverLocation = join(codeServerPath, `server.${process.platform === 'win32' ? 'cmd' : 'sh'}`);
@ -111,7 +112,7 @@ export async function launch(userDataDir: string, _workspacePath: string, codeSe
}
server = spawn(
serverLocation,
['--browser', 'none', '--driver', 'web', '--extensions-dir', extPath],
args,
{ env }
);
server.stderr?.on('data', error => console.log(`Server stderr: ${error}`));

View File

@ -19,13 +19,13 @@ export class SettingsEditor {
await this.editor.waitForEditorFocus('settings.json', 1);
await this.code.dispatchKeybinding('right');
await this.editor.waitForTypeInEditor('settings.json', `"${setting}": ${value}`);
await this.editor.waitForTypeInEditor('settings.json', `"${setting}": ${value},`);
await this.editors.saveOpenedFile();
}
async clearUserSettings(): Promise<void> {
const settingsPath = path.join(this.userDataPath, 'User', 'settings.json');
await new Promise((c, e) => fs.writeFile(settingsPath, '{\n}', 'utf8', err => err ? e(err) : c()));
await new Promise<void>((c, e) => fs.writeFile(settingsPath, '{\n}', 'utf8', err => err ? e(err) : c()));
await this.openSettings();
await this.editor.waitForEditorContents('settings.json', c => c === '{}');

View File

@ -1,7 +1,7 @@
{
"compilerOptions": {
"module": "commonjs",
"target": "es2016",
"target": "es2017",
"strict": true,
"noUnusedParameters": false,
"noUnusedLocals": true,

View File

@ -2,7 +2,7 @@
Make sure you are on **Node v12.x**.
### Run
### Quick Overview
```bash
# Build extensions in repo (if needed)
@ -11,53 +11,60 @@ yarn && yarn compile
# Install Dependencies and Compile
yarn --cwd test/smoke
# Prepare OSS in repo*
node build/lib/preLaunch.js
# Dev (Electron)
yarn smoketest
# Dev (Web)
# Dev (Web - Must be run on distro)
yarn smoketest --web --browser [chromium|webkit]
# Build (Electron)
yarn smoketest --build <path latest built version> --stable-build <path to previous stable version>
yarn smoketest --build <path to latest version> --stable-build <path to stable version>
# Build (Web - read instructions below)
yarn smoketest --build <path to web server folder> --web --browser [chromium|webkit]
yarn smoketest --build <path to server web build> --web --browser [chromium|webkit]
# Remote (Electron)
yarn smoketest --build <path latest built version> --remote
yarn smoketest --build <path to latest version> --remote
```
### Run for a release
\* This step is necessary only when running without `--build` and OSS doesn't already exist in the `.build/electron` directory.
You must always run the smoketest version which matches the release you are testing. So, if you want to run the smoketest for a release build (e.g. `release/1.22`), you need that version of the smoke tests too:
### Running for a release (Endgame)
You must always run the smoketest version that matches the release you are testing. So, if you want to run the smoketest for a release build (e.g. `release/1.22`), you need to check out that version of the smoke tests too:
```bash
git fetch
git checkout release/1.22
yarn && yarn compile
yarn --cwd test/smoke
```
#### Electron
#### Electron with --build and --stable-build
In addition to the new build to be released you will need the previous stable build so that the smoketest can test the data migration.
The recommended way to make these builds available for the smoketest is by downloading their archive version (\*.zip) and extracting
them into two folders. Pass the folder paths to the smoketest as follows:
In addition to the vscode repository, you will need the latest build and the previous stable build, so that the smoketest can test data migration.
The recommended way to make these builds available for the smoketest is by downloading their archive versions (\*.zip) from the **[builds page](https://builds.code.visualstudio.com/)**, and extracting
them into two folders (e.g. with 'Extract All' on Windows). Pass the **absolute paths** of those folders to the smoketest as follows:
```bash
yarn smoketest --build <path latest built version> --stable-build <path to previous stable version>
yarn smoketest --build <path to latest version> --stable-build <path to stable version>
```
#### Web
There is no support for testing an old version to a new one yet.
Instead, simply configure the `--build` command line argument to point to the absolute path of the extracted server web build folder (e.g. `<rest of path here>/vscode-server-darwin-web` for macOS). The server web build is available from the builds page (see previous subsection).
**macOS**: if you have downloaded the server with web bits, make sure to run the following command before unzipping it to avoid security issues on startup:
```bash
xattr -d com.apple.quarantine <path to server with web folder zip>
```
There is no support for testing an old version to a new one yet, so simply configure the `--build` command line argument to point to
the web server folder which includes the web client bits (e.g. `vscode-server-darwin-web` for macOS).
**Note**: make sure to point to the server that includes the client bits!
### Debug

View File

@ -15,7 +15,9 @@ export function setup() {
return;
}
await app.workbench.settingsEditor.addUserSetting('webview.experimental.useIframes', 'true');
if (!app.web) {
await app.workbench.settingsEditor.addUserSetting('webview.experimental.useIframes', 'true');
}
await app.workbench.extensions.openExtensionsViewlet();
@ -23,15 +25,16 @@ export function setup() {
await app.workbench.extensions.waitForExtensionsViewlet();
if (app.remote) {
await app.reload();
}
await app.workbench.quickaccess.runCommand('Smoke Test Check');
await app.workbench.statusbar.waitForStatusbarText('smoke test', 'VS Code Smoke Test Check');
});
after(async function () {
const app = this.app as Application;
if (app.web) {
return;
}
await app.workbench.settingsEditor.clearUserSettings();
});

View File

@ -16,7 +16,7 @@ export function setup() {
after(async function () {
const app = this.app as Application;
cp.execSync('git checkout . --quiet', { cwd: app.workspacePathOrFolder });
cp.execSync('git reset --hard origin/master --quiet', { cwd: app.workspacePathOrFolder });
cp.execSync('git reset --hard HEAD --quiet', { cwd: app.workspacePathOrFolder });
});
afterEach(async function () {

View File

@ -11,7 +11,7 @@ export function setup() {
after(function () {
const app = this.app as Application;
cp.execSync('git checkout . --quiet', { cwd: app.workspacePathOrFolder });
cp.execSync('git reset --hard origin/master --quiet', { cwd: app.workspacePathOrFolder });
cp.execSync('git reset --hard HEAD --quiet', { cwd: app.workspacePathOrFolder });
});
it('searches for body & checks for correct result number', async function () {

View File

@ -3,7 +3,7 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Application, ApplicationOptions } from '../../../../automation';
import { Application, ApplicationOptions, Quality } from '../../../../automation';
import { join } from 'path';
export function setup(stableCodePath: string, testDataPath: string) {
@ -19,6 +19,7 @@ export function setup(stableCodePath: string, testDataPath: string) {
const stableOptions: ApplicationOptions = Object.assign({}, this.defaultOptions);
stableOptions.codePath = stableCodePath;
stableOptions.userDataDir = userDataDir;
stableOptions.quality = Quality.Stable;
const stableApp = new Application(stableOptions);
await stableApp!.start();
@ -58,6 +59,7 @@ export function setup(stableCodePath: string, testDataPath: string) {
const stableOptions: ApplicationOptions = Object.assign({}, this.defaultOptions);
stableOptions.codePath = stableCodePath;
stableOptions.userDataDir = userDataDir;
stableOptions.quality = Quality.Stable;
const stableApp = new Application(stableOptions);
await stableApp!.start();

View File

@ -6,7 +6,7 @@
import { Application, Quality } from '../../../../automation';
export function setup() {
describe('Localization', () => {
describe.skip('Localization', () => {
before(async function () {
const app = this.app as Application;
@ -20,7 +20,7 @@ export function setup() {
await app.restart({ extraArgs: ['--locale=DE'] });
});
it(`starts with 'DE' locale and verifies title and viewlets text is in German`, async function () {
it.skip(`starts with 'DE' locale and verifies title and viewlets text is in German`, async function () {
const app = this.app as Application;
if (app.quality === Quality.Dev) {

View File

@ -315,7 +315,7 @@ describe(`VSCode Smoke Tests (${opts.web ? 'Web' : 'Electron'})`, () => {
setupDataLanguagesTests();
setupDataEditorTests();
setupDataStatusbarTests(!!opts.web);
if (!opts.web) { setupDataExtensionTests(); }
setupDataExtensionTests();
if (!opts.web) { setupDataMultirootTests(); }
if (!opts.web) { setupDataLocalizationTests(); }
if (!opts.web) { setupLaunchTests(); }

View File

@ -1,13 +0,0 @@
{
"name": "splitview",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"devDependencies": {
"koa": "^2.5.1",
"koa-mount": "^3.0.0",
"koa-route": "^3.2.0",
"koa-static": "^5.0.0",
"mz": "^2.7.0"
}
}

View File

@ -1,260 +0,0 @@
<html>
<head>
<meta charset="utf-8">
<title>Splitview</title>
<style>
#container {
width: 800px;
height: 600px;
border: 1px solid black;
}
.view {
width: 100%;
height: 100%;
text-align: center;
vertical-align: middle;
color: white;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
font-weight: bold;
font-size: 20px;
display: flex;
justify-content: center;
align-items: center;
}
</style>
</head>
<body>
<div id="buttons"></div>
<div id="container"></div>
<script src="/static/vs/loader.js"></script>
<script>
require.config({ baseUrl: '/static' });
const params = location.search.split(/[?&]/);
const testGrid = params.findIndex(p => p === 'grid') >= 0;
const testDeserialization = params.findIndex(p => p === 'deserialize') >= 0;
if (testGrid) {
require(['vs/base/browser/ui/grid/grid', 'vs/base/common/event'], ({ Grid, Sizing, Direction, SerializableGrid }, { Event }) => {
const buttons = document.getElementById('buttons');
let grid;
class View {
static ID = 0;
constructor(label, minimumWidth, maximumWidth, minimumHeight, maximumHeight, snap) {
this.id = View.ID++;
this.label = label;
this.minimumWidth = minimumWidth;
this.maximumWidth = maximumWidth;
this.minimumHeight = minimumHeight;
this.maximumHeight = maximumHeight;
this.snap = snap;
this.onDidChange = Event.None;
this.element = document.createElement('div');
this.element.className = 'view';
this.element.style.backgroundColor = `hsl(${(this.id * 41) % 360}, 50%, 70%)`;
this.element.textContent = this.label;
this.button = document.createElement('button');
this.button.onclick = () => grid.setViewVisible(this, !grid.isViewVisible(this));
buttons.appendChild(this.button);
this.setVisible(true);
}
layout(width, height, top, left) {
this.element.innerHTML = `(${top}, ${left})<br />(${width}, ${height})`;
}
setVisible(visible) {
this.button.textContent = visible ? `hide ${this.label}` : `show ${this.label}`;
}
}
const editor = new View('editor', 200, Number.POSITIVE_INFINITY, 200, Number.POSITIVE_INFINITY);
const statusbar = new View('status', 0, Number.POSITIVE_INFINITY, 20, 20);
const activitybar = new View('activity', 50, 50, 0, Number.POSITIVE_INFINITY);
const sidebar = new View('sidebar', 200, Number.POSITIVE_INFINITY, 0, Number.POSITIVE_INFINITY, true);
const panel = new View('panel', 0, Number.POSITIVE_INFINITY, 200, Number.POSITIVE_INFINITY, true);
if (testDeserialization) {
const viewMap = {
['activitybar']: activitybar,
['editor']: editor,
['panel']: panel,
['sidebar']: sidebar,
['statusbar']: statusbar
};
const gridViewDescriptor = {
root: {
type: 'branch',
size: 800,
data: [
{
type: 'branch',
size: 580,
data: [
{
type: 'leaf',
size: activitybar.maximumWidth,
data: { type: 'activitybar' },
visible: true
},
{
type: 'leaf',
size: 200,
data: { type: 'sidebar' },
visible: true
},
{
type: 'branch',
size: 550,
data: [
{
type: 'leaf',
size: 380,
data: { type: 'editor' },
visible: true
},
{
type: 'leaf',
size: 200,
data: { type: 'panel' },
visible: true
}
]
}
]
},
{
type: 'leaf',
size: statusbar.maximumHeight,
data: { type: "statusbar" },
visible: true
}
]
},
orientation: 0,
width: 800,
height: 600
};
const fromJSON = ({ type }) => viewMap[type];
grid = SerializableGrid.deserialize(
gridViewDescriptor,
{ fromJSON },
{ proportionalLayout: false }
);
container.appendChild(grid.element);
grid.layout(800, 600);
} else {
grid = new Grid(editor, {});
const container = document.getElementById('container');
container.appendChild(grid.element);
grid.layout(800, 600);
grid.addView(statusbar, Sizing.Distribute, editor, Direction.Down);
grid.addView(activitybar, Sizing.Distribute, editor, Direction.Left);
grid.addView(sidebar, 250, editor, Direction.Left);
grid.addView(panel, 200, editor, Direction.Down);
}
});
}
else {
require(['vs/base/browser/ui/splitview/splitview', 'vs/base/common/event'], ({ SplitView, Sizing }, { Event }) => {
const buttons = document.getElementById('buttons');
let splitview;
class View {
static ID = 0;
constructor(minimumSize, maximumSize) {
this.id = View.ID++;
this.element = document.createElement('div');
this.element.className = 'view';
this.element.style.backgroundColor = `hsl(${(this.id * 41) % 360}, 50%, 70%)`;
this.element.textContent = `${this.id}`;
this.minimumSize = typeof minimumSize === 'number' ? minimumSize : 100;
this.maximumSize = typeof maximumSize === 'number' ? maximumSize : Number.POSITIVE_INFINITY;
this.onDidChange = Event.None;
this.snap = !minimumSize && !maximumSize;
this.button = document.createElement('button');
this.button.onclick = () => splitview.setViewVisible(this.id, !splitview.isViewVisible(this.id));
buttons.appendChild(this.button);
this.setVisible(true);
}
layout(size, orientation) {
this.element.style.lineHeight = `${size}px`;
}
setVisible(visible) {
this.button.textContent = visible ? `hide ${this.id}` : `show ${this.id}`;
}
}
const container = document.getElementById('container');
const views = [new View(100, 100), new View(), new View(), new View(), new View()];
if (testDeserialization) {
const splitViewDescriptor = {
views: [
{
view: views[0],
size: 100,
visible: true
},
{
view: views[1],
size: 100,
visible: false
},
{
view: views[2],
size: 100,
visible: true
},
{
view: views[3],
size: 200,
visible: true
},
{
view: views[4],
size: 200,
visible: true
}
]
};
splitview = new SplitView(container, { descriptor: splitViewDescriptor, orientation: 0 });
splitview.layout(600);
} else {
// Create a new split view from scratch
splitview = new SplitView(container, {});
splitview.layout(600);
splitview.addView(views[0], Sizing.Distribute);
splitview.addView(views[1], Sizing.Distribute);
splitview.addView(views[2], Sizing.Distribute);
splitview.addView(views[3], Sizing.Distribute);
splitview.addView(views[4], Sizing.Distribute);
}
});
}
</script>
</body>
</html>

View File

@ -1,19 +0,0 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
const fs = require('mz/fs');
const path = require('path');
const Koa = require('koa');
const _ = require('koa-route');
const serve = require('koa-static');
const mount = require('koa-mount');
const app = new Koa();
app.use(serve('public'));
app.use(mount('/static', serve('../../out')));
app.listen(3000);
console.log('http://localhost:3000');

View File

@ -1,341 +0,0 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1
accepts@^1.2.2:
version "1.3.5"
resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.5.tgz#eb777df6011723a3b14e8a72c0805c8e86746bd2"
integrity sha1-63d99gEXI6OxTopywIBcjoZ0a9I=
dependencies:
mime-types "~2.1.18"
negotiator "0.6.1"
any-promise@^1.0.0, any-promise@^1.1.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f"
integrity sha1-q8av7tzqUugJzcA3au0845Y10X8=
co@^4.6.0:
version "4.6.0"
resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184"
integrity sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=
content-disposition@~0.5.0:
version "0.5.2"
resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.2.tgz#0cf68bb9ddf5f2be7961c3a85178cb85dba78cb4"
integrity sha1-DPaLud318r55YcOoUXjLhdunjLQ=
content-type@^1.0.0:
version "1.0.4"
resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b"
integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==
cookies@~0.7.0:
version "0.7.1"
resolved "https://registry.yarnpkg.com/cookies/-/cookies-0.7.1.tgz#7c8a615f5481c61ab9f16c833731bcb8f663b99b"
integrity sha1-fIphX1SBxhq58WyDNzG8uPZjuZs=
dependencies:
depd "~1.1.1"
keygrip "~1.0.2"
debug@*, debug@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261"
integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==
dependencies:
ms "2.0.0"
debug@^2.6.1:
version "2.6.9"
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==
dependencies:
ms "2.0.0"
deep-equal@~1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5"
integrity sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=
delegates@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a"
integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=
depd@^1.1.0, depd@~1.1.1, depd@~1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9"
integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=
destroy@^1.0.3:
version "1.0.4"
resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80"
integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=
ee-first@1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d"
integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=
error-inject@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/error-inject/-/error-inject-1.0.0.tgz#e2b3d91b54aed672f309d950d154850fa11d4f37"
integrity sha1-4rPZG1Su1nLzCdlQ0VSFD6EdTzc=
escape-html@~1.0.1:
version "1.0.3"
resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988"
integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=
fresh@^0.5.2:
version "0.5.2"
resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7"
integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=
http-assert@^1.1.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/http-assert/-/http-assert-1.3.0.tgz#a31a5cf88c873ecbb5796907d4d6f132e8c01e4a"
integrity sha1-oxpc+IyHPsu1eWkH1NbxMujAHko=
dependencies:
deep-equal "~1.0.1"
http-errors "~1.6.1"
http-errors@^1.2.8, http-errors@^1.6.3, http-errors@~1.6.1, http-errors@~1.6.2:
version "1.6.3"
resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d"
integrity sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=
dependencies:
depd "~1.1.2"
inherits "2.0.3"
setprototypeof "1.1.0"
statuses ">= 1.4.0 < 2"
inherits@2.0.3:
version "2.0.3"
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=
is-generator-function@^1.0.3:
version "1.0.7"
resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.0.7.tgz#d2132e529bb0000a7f80794d4bdf5cd5e5813522"
integrity sha512-YZc5EwyO4f2kWCax7oegfuSr9mFz1ZvieNYBEjmukLxgXfBUbxAWGVF7GZf0zidYtoBl3WvC07YK0wT76a+Rtw==
isarray@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf"
integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=
keygrip@~1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/keygrip/-/keygrip-1.0.2.tgz#ad3297c557069dea8bcfe7a4fa491b75c5ddeb91"
integrity sha1-rTKXxVcGneqLz+ek+kkbdcXd65E=
koa-compose@^3.0.0, koa-compose@^3.2.1:
version "3.2.1"
resolved "https://registry.yarnpkg.com/koa-compose/-/koa-compose-3.2.1.tgz#a85ccb40b7d986d8e5a345b3a1ace8eabcf54de7"
integrity sha1-qFzLQLfZhtjlo0Wzoazo6rz1Tec=
dependencies:
any-promise "^1.1.0"
koa-compose@^4.0.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/koa-compose/-/koa-compose-4.1.0.tgz#507306b9371901db41121c812e923d0d67d3e877"
integrity sha512-8ODW8TrDuMYvXRwra/Kh7/rJo9BtOfPc6qO8eAfC80CnCvSjSl0bkRM24X6/XBBEyj0v1nRUQ1LyOy3dbqOWXw==
koa-convert@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/koa-convert/-/koa-convert-1.2.0.tgz#da40875df49de0539098d1700b50820cebcd21d0"
integrity sha1-2kCHXfSd4FOQmNFwC1CCDOvNIdA=
dependencies:
co "^4.6.0"
koa-compose "^3.0.0"
koa-is-json@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/koa-is-json/-/koa-is-json-1.0.0.tgz#273c07edcdcb8df6a2c1ab7d59ee76491451ec14"
integrity sha1-JzwH7c3Ljfaiwat9We52SRRR7BQ=
koa-mount@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/koa-mount/-/koa-mount-3.0.0.tgz#08cab3b83d31442ed8b7e75c54b1abeb922ec197"
integrity sha1-CMqzuD0xRC7Yt+dcVLGr65IuwZc=
dependencies:
debug "^2.6.1"
koa-compose "^3.2.1"
koa-route@^3.2.0:
version "3.2.0"
resolved "https://registry.yarnpkg.com/koa-route/-/koa-route-3.2.0.tgz#76298b99a6bcfa9e38cab6fe5c79a8733e758bce"
integrity sha1-dimLmaa8+p44yrb+XHmocz51i84=
dependencies:
debug "*"
methods "~1.1.0"
path-to-regexp "^1.2.0"
koa-send@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/koa-send/-/koa-send-5.0.0.tgz#5e8441e07ef55737734d7ced25b842e50646e7eb"
integrity sha512-90ZotV7t0p3uN9sRwW2D484rAaKIsD8tAVtypw/aBU+ryfV+fR2xrcAwhI8Wl6WRkojLUs/cB9SBSCuIb+IanQ==
dependencies:
debug "^3.1.0"
http-errors "^1.6.3"
mz "^2.7.0"
resolve-path "^1.4.0"
koa-static@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/koa-static/-/koa-static-5.0.0.tgz#5e92fc96b537ad5219f425319c95b64772776943"
integrity sha512-UqyYyH5YEXaJrf9S8E23GoJFQZXkBVJ9zYYMPGz919MSX1KuvAcycIuS0ci150HCoPf4XQVhQ84Qf8xRPWxFaQ==
dependencies:
debug "^3.1.0"
koa-send "^5.0.0"
koa@^2.5.1:
version "2.5.1"
resolved "https://registry.yarnpkg.com/koa/-/koa-2.5.1.tgz#79f8b95f8d72d04fe9a58a8da5ebd6d341103f9c"
integrity sha512-cchwbMeG2dv3E2xTAmheDAuvR53tPgJZN/Hf1h7bTzJLSPcFZp8/t5+bNKJ6GaQZoydhZQ+1GNruhKdj3lIrug==
dependencies:
accepts "^1.2.2"
content-disposition "~0.5.0"
content-type "^1.0.0"
cookies "~0.7.0"
debug "*"
delegates "^1.0.0"
depd "^1.1.0"
destroy "^1.0.3"
error-inject "~1.0.0"
escape-html "~1.0.1"
fresh "^0.5.2"
http-assert "^1.1.0"
http-errors "^1.2.8"
is-generator-function "^1.0.3"
koa-compose "^4.0.0"
koa-convert "^1.2.0"
koa-is-json "^1.0.0"
mime-types "^2.0.7"
on-finished "^2.1.0"
only "0.0.2"
parseurl "^1.3.0"
statuses "^1.2.0"
type-is "^1.5.5"
vary "^1.0.0"
media-typer@0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748"
integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=
methods@~1.1.0:
version "1.1.2"
resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee"
integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=
mime-db@~1.33.0:
version "1.33.0"
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.33.0.tgz#a3492050a5cb9b63450541e39d9788d2272783db"
integrity sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==
mime-types@^2.0.7, mime-types@~2.1.18:
version "2.1.18"
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.18.tgz#6f323f60a83d11146f831ff11fd66e2fe5503bb8"
integrity sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==
dependencies:
mime-db "~1.33.0"
ms@2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=
mz@^2.7.0:
version "2.7.0"
resolved "https://registry.yarnpkg.com/mz/-/mz-2.7.0.tgz#95008057a56cafadc2bc63dde7f9ff6955948e32"
integrity sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==
dependencies:
any-promise "^1.0.0"
object-assign "^4.0.1"
thenify-all "^1.0.0"
negotiator@0.6.1:
version "0.6.1"
resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9"
integrity sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=
object-assign@^4.0.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=
on-finished@^2.1.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947"
integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=
dependencies:
ee-first "1.1.1"
only@0.0.2:
version "0.0.2"
resolved "https://registry.yarnpkg.com/only/-/only-0.0.2.tgz#2afde84d03e50b9a8edc444e30610a70295edfb4"
integrity sha1-Kv3oTQPlC5qO3EROMGEKcCle37Q=
parseurl@^1.3.0:
version "1.3.2"
resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.2.tgz#fc289d4ed8993119460c156253262cdc8de65bf3"
integrity sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=
path-is-absolute@1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18=
path-to-regexp@^1.2.0:
version "1.7.0"
resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-1.7.0.tgz#59fde0f435badacba103a84e9d3bc64e96b9937d"
integrity sha1-Wf3g9DW62suhA6hOnTvGTpa5k30=
dependencies:
isarray "0.0.1"
resolve-path@^1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/resolve-path/-/resolve-path-1.4.0.tgz#c4bda9f5efb2fce65247873ab36bb4d834fe16f7"
integrity sha1-xL2p9e+y/OZSR4c6s2u02DT+Fvc=
dependencies:
http-errors "~1.6.2"
path-is-absolute "1.0.1"
setprototypeof@1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656"
integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==
"statuses@>= 1.4.0 < 2", statuses@^1.2.0:
version "1.5.0"
resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c"
integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=
thenify-all@^1.0.0:
version "1.6.0"
resolved "https://registry.yarnpkg.com/thenify-all/-/thenify-all-1.6.0.tgz#1a1918d402d8fc3f98fbf234db0bcc8cc10e9726"
integrity sha1-GhkY1ALY/D+Y+/I02wvMjMEOlyY=
dependencies:
thenify ">= 3.1.0 < 4"
"thenify@>= 3.1.0 < 4":
version "3.3.0"
resolved "https://registry.yarnpkg.com/thenify/-/thenify-3.3.0.tgz#e69e38a1babe969b0108207978b9f62b88604839"
integrity sha1-5p44obq+lpsBCCB5eLn2K4hgSDk=
dependencies:
any-promise "^1.0.0"
type-is@^1.5.5:
version "1.6.16"
resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.16.tgz#f89ce341541c672b25ee7ae3c73dee3b2be50194"
integrity sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q==
dependencies:
media-typer "0.3.0"
mime-types "~2.1.18"
vary@^1.0.0:
version "1.1.2"
resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc"
integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=

View File

@ -1,13 +0,0 @@
{
"name": "tree",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"devDependencies": {
"koa": "^2.5.1",
"koa-mount": "^3.0.0",
"koa-route": "^3.2.0",
"koa-static": "^5.0.0",
"mz": "^2.7.0"
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,403 +0,0 @@
<html>
<head>
<meta charset="utf-8">
<title>Tree</title>
<style>
#container {
width: 400;
height: 600;
border: 1px solid black;
}
.monaco-scrollable-element>.scrollbar>.slider {
background: rgba(100, 100, 100, .4);
}
.tl-contents {
flex: 1;
}
.monaco-list-row:hover:not(.selected):not(.focused) {
background: gainsboro !important;
}
</style>
</head>
<body>
<input type="text" id="filter" />
<button id="expandall">Expand All</button>
<button id="collapseall">Collapse All</button>
<button id="renderwidth">Render Width</button>
<button id="refresh">Refresh</button>
<div id="container"></div>
<script src="/static/vs/loader.js"></script>
<script>
function perf(name, fn) {
performance.mark('before ' + name);
const start = performance.now();
fn();
console.log(name + ' took', performance.now() - start);
performance.mark('after ' + name);
}
require.config({ baseUrl: '/static' });
require(['vs/base/browser/ui/tree/indexTree', 'vs/base/browser/ui/tree/objectTree', 'vs/base/browser/ui/tree/asyncDataTree', 'vs/base/browser/ui/tree/dataTree', 'vs/base/browser/ui/tree/tree', 'vs/base/common/iterator'], ({ IndexTree }, { CompressibleObjectTree }, { AsyncDataTree }, { DataTree }, { TreeVisibility }, { iter }) => {
function createIndexTree(opts) {
opts = opts || {};
const delegate = {
getHeight() { return 22; },
getTemplateId() { return 'template'; },
hasDynamicHeight() { return true; }
};
const renderer = {
templateId: 'template',
renderTemplate(container) { return container; },
renderElement(element, index, container) {
if (opts.supportDynamicHeights) {
let v = [];
for (let i = 1; i <= 5; i++) {
v.push(element.element);
}
container.innerHTML = v.join('<br />');
} else {
container.innerHTML = element.element;
}
},
disposeElement() { },
disposeTemplate() { }
};
const treeFilter = new class {
constructor() {
this.pattern = null;
let timeout;
filter.oninput = () => {
clearTimeout(timeout);
timeout = setTimeout(() => this.updatePattern(), 300);
};
}
updatePattern() {
if (!filter.value) {
this.pattern = null;
} else {
this.pattern = new RegExp(filter.value, 'i');
}
perf('refilter', () => tree.refilter());
}
filter(el) {
return (this.pattern ? this.pattern.test(el) : true) ? TreeVisibility.Visible : TreeVisibility.Recurse;
}
};
const tree = new IndexTree('test', container, delegate, [renderer], null, { ...opts, filter: treeFilter, setRowLineHeight: false });
return { tree, treeFilter };
}
function createCompressedObjectTree(opts) {
opts = opts || {};
const delegate = {
getHeight() { return 22; },
getTemplateId() { return 'template'; },
hasDynamicHeight() { return true; }
};
const renderer = {
templateId: 'template',
renderTemplate(container) { return container; },
renderElement(element, index, container) {
container.innerHTML = element.element.name;
},
renderCompressedElements(node, index, container, height) {
container.innerHTML = `🙈 ${node.element.elements.map(el => el.name).join('/')}`;
},
disposeElement() { },
disposeTemplate() { }
};
const treeFilter = new class {
constructor() {
this.pattern = null;
let timeout;
filter.oninput = () => {
clearTimeout(timeout);
timeout = setTimeout(() => this.updatePattern(), 300);
};
}
updatePattern() {
if (!filter.value) {
this.pattern = null;
} else {
this.pattern = new RegExp(filter.value, 'i');
}
perf('refilter', () => tree.refilter());
}
filter(el) {
return (this.pattern ? this.pattern.test(el) : true) ? TreeVisibility.Visible : TreeVisibility.Recurse;
}
};
const tree = new CompressibleObjectTree('test', container, delegate, [renderer], { ...opts, filter: treeFilter, setRowLineHeight: false, collapseByDefault: true, setRowLineHeight: true });
return { tree, treeFilter };
}
function createAsyncDataTree() {
const delegate = {
getHeight() { return 22; },
getTemplateId() { return 'template'; }
};
const renderer = {
templateId: 'template',
renderTemplate(container) { return container; },
renderElement(node, index, container) { container.textContent = node.element.element.name; },
disposeElement() { },
disposeTemplate() { }
};
const treeFilter = new class {
constructor() {
this.pattern = null;
let timeout;
filter.oninput = () => {
clearTimeout(timeout);
timeout = setTimeout(() => this.updatePattern(), 300);
};
}
updatePattern() {
if (!filter.value) {
this.pattern = null;
} else {
this.pattern = new RegExp(filter.value, 'i');
}
perf('refilter', () => tree.refilter());
}
filter(el) {
return (this.pattern ? this.pattern.test(el.name) : true) ? TreeVisibility.Visible : TreeVisibility.Recurse;
}
};
const sorter = new class {
compare(a, b) {
if (a.collapsible === b.collapsible) {
return a.name < b.name ? -1 : 1;
}
return a.collapsible ? -1 : 1;
}
};
const dataSource = new class {
hasChildren(element) {
return element === null || element.element.type === 'dir';
}
getChildren(element) {
return new Promise((c, e) => {
const xhr = new XMLHttpRequest();
xhr.open('GET', element ? `/api/readdir?path=${element.element.path}` : '/api/readdir');
xhr.send();
xhr.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
const els = JSON.parse(this.responseText).map(element => ({
element,
collapsible: element.type === 'dir'
}));
c(els);
}
};
});
}
}
const identityProvider = {
getId(node) {
return node.element.path;
}
};
const tree = new AsyncDataTree('test', container, delegate, [renderer], dataSource, { filter: treeFilter, sorter, identityProvider });
return { tree, treeFilter };
}
function createDataTree() {
const delegate = {
getHeight() { return 22; },
getTemplateId() { return 'template'; }
};
const renderer = {
templateId: 'template',
renderTemplate(container) { return container; },
renderElement(node, index, container) { container.textContent = node.element.name; },
disposeElement() { },
disposeTemplate() { }
};
const treeFilter = new class {
constructor() {
this.pattern = null;
let timeout;
filter.oninput = () => {
clearTimeout(timeout);
timeout = setTimeout(() => this.updatePattern(), 300);
};
}
updatePattern() {
if (!filter.value) {
this.pattern = null;
} else {
this.pattern = new RegExp(filter.value, 'i');
}
perf('refilter', () => tree.refilter());
}
filter(el) {
return (this.pattern ? this.pattern.test(el.name) : true) ? TreeVisibility.Visible : TreeVisibility.Recurse;
}
};
const dataSource = new class {
getChildren(element) {
return element.children || [];
}
};
const identityProvider = {
getId(node) {
return node.name;
}
};
const tree = new DataTree('test', container, delegate, [renderer], dataSource, { filter: treeFilter, identityProvider });
tree.setInput({
children: [
{ name: 'A', children: [{ name: 'AA' }, { name: 'AB' }] },
{ name: 'B', children: [{ name: 'BA', children: [{ name: 'BAA' }] }, { name: 'BB' }] },
{ name: 'C' }
]
});
return { tree, treeFilter };
}
switch (location.search) {
case '?problems': {
const { tree, treeFilter } = createIndexTree();
expandall.onclick = () => perf('expand all', () => tree.expandAll());
collapseall.onclick = () => perf('collapse all', () => tree.collapseAll());
renderwidth.onclick = () => perf('renderwidth', () => tree.layoutWidth(Math.random()));
const files = [];
for (let i = 0; i < 100000; i++) {
const errors = [];
for (let j = 1; j <= 3; j++) {
errors.push({ element: `error #${j} ` });
}
files.push({ element: `file #${i}`, children: errors });
}
perf('splice', () => tree.splice([0], 0, files));
break;
}
case '?data': {
const { tree, treeFilter } = createAsyncDataTree();
expandall.onclick = () => perf('expand all', () => tree.expandAll());
collapseall.onclick = () => perf('collapse all', () => tree.collapseAll());
renderwidth.onclick = () => perf('renderwidth', () => tree.layoutWidth(Math.random()));
refresh.onclick = () => perf('refresh', () => tree.updateChildren());
tree.setInput(null);
break;
}
case '?objectdata': {
const { tree, treeFilter } = createDataTree();
expandall.onclick = () => perf('expand all', () => tree.expandAll());
collapseall.onclick = () => perf('collapse all', () => tree.collapseAll());
renderwidth.onclick = () => perf('renderwidth', () => tree.layoutWidth(Math.random()));
refresh.onclick = () => perf('refresh', () => tree.updateChildren());
break;
}
case '?compressed': {
const { tree, treeFilter } = createCompressedObjectTree();
expandall.onclick = () => perf('expand all', () => tree.expandAll());
collapseall.onclick = () => perf('collapse all', () => tree.collapseAll());
const xhr = new XMLHttpRequest();
xhr.open('GET', '/compressed.json');
xhr.send();
xhr.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
tree.setChildren(null, JSON.parse(this.responseText));
}
};
break;
}
case '?height': {
const { tree, treeFilter } = createIndexTree({ supportDynamicHeights: true });
expandall.onclick = () => perf('expand all', () => tree.expandAll());
collapseall.onclick = () => perf('collapse all', () => tree.collapseAll());
renderwidth.onclick = () => perf('renderwidth', () => tree.layoutWidth(Math.random()));
const xhr = new XMLHttpRequest();
xhr.open('GET', '/api/ls?path=');
xhr.send();
xhr.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
perf('splice', () => tree.splice([0], 0, [JSON.parse(this.responseText)]));
treeFilter.updatePattern();
}
};
// container.
break;
}
default: {
const { tree, treeFilter } = createIndexTree();
expandall.onclick = () => perf('expand all', () => tree.expandAll());
collapseall.onclick = () => perf('collapse all', () => tree.collapseAll());
renderwidth.onclick = () => perf('renderwidth', () => tree.layoutWidth(Math.random()));
const xhr = new XMLHttpRequest();
xhr.open('GET', '/api/ls?path=');
xhr.send();
xhr.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
perf('splice', () => tree.splice([0], 0, [JSON.parse(this.responseText)]));
treeFilter.updatePattern();
}
};
}
}
});
</script>
</body>
</html>

View File

@ -1,68 +0,0 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
const fs = require('mz/fs');
const path = require('path');
const Koa = require('koa');
const _ = require('koa-route');
const serve = require('koa-static');
const mount = require('koa-mount');
const app = new Koa();
const root = path.dirname(path.dirname(__dirname));
async function getTree(fsPath, level) {
const element = path.basename(fsPath);
const stat = await fs.stat(fsPath);
if (!stat.isDirectory() || element === '.git' || element === '.build' || level >= 4) {
return { element };
}
const childNames = await fs.readdir(fsPath);
const children = await Promise.all(childNames.map(async childName => await getTree(path.join(fsPath, childName), level + 1)));
return { element, collapsible: true, collapsed: false, children };
}
async function readdir(relativePath) {
const absolutePath = relativePath ? path.join(root, relativePath) : root;
const childNames = await fs.readdir(absolutePath);
const childStats = await Promise.all(childNames.map(async name => await fs.stat(path.join(absolutePath, name))));
const result = [];
for (let i = 0; i < childNames.length; i++) {
const name = childNames[i];
const path = relativePath ? `${relativePath}/${name}` : name;
const stat = childStats[i];
if (stat.isFile()) {
result.push({ type: 'file', name, path });
} else if (!stat.isDirectory() || name === '.git' || name === '.build') {
continue;
} else {
result.push({ type: 'dir', name, path });
}
}
return result;
}
app.use(serve('public'));
app.use(mount('/static', serve('../../out')));
app.use(_.get('/api/ls', async ctx => {
const relativePath = ctx.query.path;
const absolutePath = path.join(root, relativePath);
ctx.body = await getTree(absolutePath, 0);
}));
app.use(_.get('/api/readdir', async ctx => {
const relativePath = ctx.query.path;
ctx.body = await readdir(relativePath);
}));
app.listen(3000);
console.log('http://localhost:3000');

View File

@ -1,24 +0,0 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
const path = require('path');
const fs = require('fs');
function collect(location) {
const element = { name: path.basename(location) };
const stat = fs.statSync(location);
if (!stat.isDirectory()) {
return { element, incompressible: true };
}
const children = fs.readdirSync(location)
.map(child => path.join(location, child))
.map(collect);
return { element, children };
}
console.log(JSON.stringify(collect(process.cwd())));

View File

@ -1,341 +0,0 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1
accepts@^1.2.2:
version "1.3.5"
resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.5.tgz#eb777df6011723a3b14e8a72c0805c8e86746bd2"
integrity sha1-63d99gEXI6OxTopywIBcjoZ0a9I=
dependencies:
mime-types "~2.1.18"
negotiator "0.6.1"
any-promise@^1.0.0, any-promise@^1.1.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f"
integrity sha1-q8av7tzqUugJzcA3au0845Y10X8=
co@^4.6.0:
version "4.6.0"
resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184"
integrity sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=
content-disposition@~0.5.0:
version "0.5.2"
resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.2.tgz#0cf68bb9ddf5f2be7961c3a85178cb85dba78cb4"
integrity sha1-DPaLud318r55YcOoUXjLhdunjLQ=
content-type@^1.0.0:
version "1.0.4"
resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b"
integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==
cookies@~0.7.0:
version "0.7.1"
resolved "https://registry.yarnpkg.com/cookies/-/cookies-0.7.1.tgz#7c8a615f5481c61ab9f16c833731bcb8f663b99b"
integrity sha1-fIphX1SBxhq58WyDNzG8uPZjuZs=
dependencies:
depd "~1.1.1"
keygrip "~1.0.2"
debug@*, debug@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261"
integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==
dependencies:
ms "2.0.0"
debug@^2.6.1:
version "2.6.9"
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==
dependencies:
ms "2.0.0"
deep-equal@~1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5"
integrity sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=
delegates@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a"
integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=
depd@^1.1.0, depd@~1.1.1, depd@~1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9"
integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=
destroy@^1.0.3:
version "1.0.4"
resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80"
integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=
ee-first@1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d"
integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=
error-inject@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/error-inject/-/error-inject-1.0.0.tgz#e2b3d91b54aed672f309d950d154850fa11d4f37"
integrity sha1-4rPZG1Su1nLzCdlQ0VSFD6EdTzc=
escape-html@~1.0.1:
version "1.0.3"
resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988"
integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=
fresh@^0.5.2:
version "0.5.2"
resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7"
integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=
http-assert@^1.1.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/http-assert/-/http-assert-1.3.0.tgz#a31a5cf88c873ecbb5796907d4d6f132e8c01e4a"
integrity sha1-oxpc+IyHPsu1eWkH1NbxMujAHko=
dependencies:
deep-equal "~1.0.1"
http-errors "~1.6.1"
http-errors@^1.2.8, http-errors@^1.6.3, http-errors@~1.6.1, http-errors@~1.6.2:
version "1.6.3"
resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d"
integrity sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=
dependencies:
depd "~1.1.2"
inherits "2.0.3"
setprototypeof "1.1.0"
statuses ">= 1.4.0 < 2"
inherits@2.0.3:
version "2.0.3"
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=
is-generator-function@^1.0.3:
version "1.0.7"
resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.0.7.tgz#d2132e529bb0000a7f80794d4bdf5cd5e5813522"
integrity sha512-YZc5EwyO4f2kWCax7oegfuSr9mFz1ZvieNYBEjmukLxgXfBUbxAWGVF7GZf0zidYtoBl3WvC07YK0wT76a+Rtw==
isarray@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf"
integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=
keygrip@~1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/keygrip/-/keygrip-1.0.2.tgz#ad3297c557069dea8bcfe7a4fa491b75c5ddeb91"
integrity sha1-rTKXxVcGneqLz+ek+kkbdcXd65E=
koa-compose@^3.0.0, koa-compose@^3.2.1:
version "3.2.1"
resolved "https://registry.yarnpkg.com/koa-compose/-/koa-compose-3.2.1.tgz#a85ccb40b7d986d8e5a345b3a1ace8eabcf54de7"
integrity sha1-qFzLQLfZhtjlo0Wzoazo6rz1Tec=
dependencies:
any-promise "^1.1.0"
koa-compose@^4.0.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/koa-compose/-/koa-compose-4.1.0.tgz#507306b9371901db41121c812e923d0d67d3e877"
integrity sha512-8ODW8TrDuMYvXRwra/Kh7/rJo9BtOfPc6qO8eAfC80CnCvSjSl0bkRM24X6/XBBEyj0v1nRUQ1LyOy3dbqOWXw==
koa-convert@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/koa-convert/-/koa-convert-1.2.0.tgz#da40875df49de0539098d1700b50820cebcd21d0"
integrity sha1-2kCHXfSd4FOQmNFwC1CCDOvNIdA=
dependencies:
co "^4.6.0"
koa-compose "^3.0.0"
koa-is-json@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/koa-is-json/-/koa-is-json-1.0.0.tgz#273c07edcdcb8df6a2c1ab7d59ee76491451ec14"
integrity sha1-JzwH7c3Ljfaiwat9We52SRRR7BQ=
koa-mount@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/koa-mount/-/koa-mount-3.0.0.tgz#08cab3b83d31442ed8b7e75c54b1abeb922ec197"
integrity sha1-CMqzuD0xRC7Yt+dcVLGr65IuwZc=
dependencies:
debug "^2.6.1"
koa-compose "^3.2.1"
koa-route@^3.2.0:
version "3.2.0"
resolved "https://registry.yarnpkg.com/koa-route/-/koa-route-3.2.0.tgz#76298b99a6bcfa9e38cab6fe5c79a8733e758bce"
integrity sha1-dimLmaa8+p44yrb+XHmocz51i84=
dependencies:
debug "*"
methods "~1.1.0"
path-to-regexp "^1.2.0"
koa-send@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/koa-send/-/koa-send-5.0.0.tgz#5e8441e07ef55737734d7ced25b842e50646e7eb"
integrity sha512-90ZotV7t0p3uN9sRwW2D484rAaKIsD8tAVtypw/aBU+ryfV+fR2xrcAwhI8Wl6WRkojLUs/cB9SBSCuIb+IanQ==
dependencies:
debug "^3.1.0"
http-errors "^1.6.3"
mz "^2.7.0"
resolve-path "^1.4.0"
koa-static@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/koa-static/-/koa-static-5.0.0.tgz#5e92fc96b537ad5219f425319c95b64772776943"
integrity sha512-UqyYyH5YEXaJrf9S8E23GoJFQZXkBVJ9zYYMPGz919MSX1KuvAcycIuS0ci150HCoPf4XQVhQ84Qf8xRPWxFaQ==
dependencies:
debug "^3.1.0"
koa-send "^5.0.0"
koa@^2.5.1:
version "2.5.1"
resolved "https://registry.yarnpkg.com/koa/-/koa-2.5.1.tgz#79f8b95f8d72d04fe9a58a8da5ebd6d341103f9c"
integrity sha512-cchwbMeG2dv3E2xTAmheDAuvR53tPgJZN/Hf1h7bTzJLSPcFZp8/t5+bNKJ6GaQZoydhZQ+1GNruhKdj3lIrug==
dependencies:
accepts "^1.2.2"
content-disposition "~0.5.0"
content-type "^1.0.0"
cookies "~0.7.0"
debug "*"
delegates "^1.0.0"
depd "^1.1.0"
destroy "^1.0.3"
error-inject "~1.0.0"
escape-html "~1.0.1"
fresh "^0.5.2"
http-assert "^1.1.0"
http-errors "^1.2.8"
is-generator-function "^1.0.3"
koa-compose "^4.0.0"
koa-convert "^1.2.0"
koa-is-json "^1.0.0"
mime-types "^2.0.7"
on-finished "^2.1.0"
only "0.0.2"
parseurl "^1.3.0"
statuses "^1.2.0"
type-is "^1.5.5"
vary "^1.0.0"
media-typer@0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748"
integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=
methods@~1.1.0:
version "1.1.2"
resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee"
integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=
mime-db@~1.33.0:
version "1.33.0"
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.33.0.tgz#a3492050a5cb9b63450541e39d9788d2272783db"
integrity sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==
mime-types@^2.0.7, mime-types@~2.1.18:
version "2.1.18"
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.18.tgz#6f323f60a83d11146f831ff11fd66e2fe5503bb8"
integrity sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==
dependencies:
mime-db "~1.33.0"
ms@2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=
mz@^2.7.0:
version "2.7.0"
resolved "https://registry.yarnpkg.com/mz/-/mz-2.7.0.tgz#95008057a56cafadc2bc63dde7f9ff6955948e32"
integrity sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==
dependencies:
any-promise "^1.0.0"
object-assign "^4.0.1"
thenify-all "^1.0.0"
negotiator@0.6.1:
version "0.6.1"
resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9"
integrity sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=
object-assign@^4.0.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=
on-finished@^2.1.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947"
integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=
dependencies:
ee-first "1.1.1"
only@0.0.2:
version "0.0.2"
resolved "https://registry.yarnpkg.com/only/-/only-0.0.2.tgz#2afde84d03e50b9a8edc444e30610a70295edfb4"
integrity sha1-Kv3oTQPlC5qO3EROMGEKcCle37Q=
parseurl@^1.3.0:
version "1.3.2"
resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.2.tgz#fc289d4ed8993119460c156253262cdc8de65bf3"
integrity sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=
path-is-absolute@1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18=
path-to-regexp@^1.2.0:
version "1.7.0"
resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-1.7.0.tgz#59fde0f435badacba103a84e9d3bc64e96b9937d"
integrity sha1-Wf3g9DW62suhA6hOnTvGTpa5k30=
dependencies:
isarray "0.0.1"
resolve-path@^1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/resolve-path/-/resolve-path-1.4.0.tgz#c4bda9f5efb2fce65247873ab36bb4d834fe16f7"
integrity sha1-xL2p9e+y/OZSR4c6s2u02DT+Fvc=
dependencies:
http-errors "~1.6.2"
path-is-absolute "1.0.1"
setprototypeof@1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656"
integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==
"statuses@>= 1.4.0 < 2", statuses@^1.2.0:
version "1.5.0"
resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c"
integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=
thenify-all@^1.0.0:
version "1.6.0"
resolved "https://registry.yarnpkg.com/thenify-all/-/thenify-all-1.6.0.tgz#1a1918d402d8fc3f98fbf234db0bcc8cc10e9726"
integrity sha1-GhkY1ALY/D+Y+/I02wvMjMEOlyY=
dependencies:
thenify ">= 3.1.0 < 4"
"thenify@>= 3.1.0 < 4":
version "3.3.0"
resolved "https://registry.yarnpkg.com/thenify/-/thenify-3.3.0.tgz#e69e38a1babe969b0108207978b9f62b88604839"
integrity sha1-5p44obq+lpsBCCB5eLn2K4hgSDk=
dependencies:
any-promise "^1.0.0"
type-is@^1.5.5:
version "1.6.16"
resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.16.tgz#f89ce341541c672b25ee7ae3c73dee3b2be50194"
integrity sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q==
dependencies:
media-typer "0.3.0"
mime-types "~2.1.18"
vary@^1.0.0:
version "1.1.2"
resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc"
integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=

View File

@ -131,6 +131,19 @@ const testModules = (async function () {
})
})();
function consoleLogFn(msg) {
const type = msg.type();
const candidate = console[type];
if (candidate) {
return candidate;
}
if (type === 'warning') {
return console.warn;
}
return console.log;
}
async function runTestsInBrowser(testModules, browserType) {
const args = process.platform === 'linux' && browserType === 'chromium' ? ['--no-sandbox'] : undefined; // disable sandbox to run chrome on certain Linux distros
@ -149,7 +162,7 @@ async function runTestsInBrowser(testModules, browserType) {
});
page.on('console', async msg => {
console[msg.type()](msg.text(), await Promise.all(msg.args().map(async arg => await arg.jsonValue())));
consoleLogFn(msg)(msg.text(), await Promise.all(msg.args().map(async arg => await arg.jsonValue())));
});
withReporter(browserType, new EchoRunner(emitter, browserType.toUpperCase()));