Merge VS Code 1.21 source code (#1067)

* Initial VS Code 1.21 file copy with patches

* A few more merges

* Post npm install

* Fix batch of build breaks

* Fix more build breaks

* Fix more build errors

* Fix more build breaks

* Runtime fixes 1

* Get connection dialog working with some todos

* Fix a few packaging issues

* Copy several node_modules to package build to fix loader issues

* Fix breaks from master

* A few more fixes

* Make tests pass

* First pass of license header updates

* Second pass of license header updates

* Fix restore dialog issues

* Remove add additional themes menu items

* fix select box issues where the list doesn't show up

* formatting

* Fix editor dispose issue

* Copy over node modules to correct location on all platforms
This commit is contained in:
Karl Burtram
2018-04-04 15:27:51 -07:00
committed by GitHub
parent 5fba3e31b4
commit dafb780987
9412 changed files with 141255 additions and 98813 deletions

View File

@@ -7,50 +7,52 @@ import * as assert from 'assert';
import { SpectronApplication } from '../../spectron/application';
import { ProblemSeverity, Problems } from '../problems/problems';
describe('CSS', () => {
before(function () {
this.app.suiteName = 'CSS';
export function setup() {
describe('CSS', () => {
before(function () {
this.app.suiteName = 'CSS';
});
it('verifies quick outline', async function () {
const app = this.app as SpectronApplication;
await app.workbench.quickopen.openFile('style.css');
await app.workbench.editor.openOutline();
await app.workbench.quickopen.waitForQuickOpenElements(names => names.length === 2);
});
it('verifies warnings for the empty rule', async function () {
const app = this.app as SpectronApplication;
await app.workbench.quickopen.openFile('style.css');
await app.workbench.editor.waitForTypeInEditor('style.css', '.foo{}');
let warning = await app.client.waitForElement(Problems.getSelectorInEditor(ProblemSeverity.WARNING));
await app.screenCapturer.capture('CSS Warning in editor');
assert.ok(warning, `Warning squiggle is not shown in 'style.css'.`);
await app.workbench.problems.showProblemsView();
warning = await app.client.waitForElement(Problems.getSelectorInProblemsView(ProblemSeverity.WARNING));
await app.screenCapturer.capture('CSS Warning in problems view');
assert.ok(warning, 'Warning does not appear in Problems view.');
await app.workbench.problems.hideProblemsView();
});
it('verifies that warning becomes an error once setting changed', async function () {
const app = this.app as SpectronApplication;
await app.workbench.settingsEditor.addUserSetting('css.lint.emptyRules', '"error"');
await app.workbench.quickopen.openFile('style.css');
await app.workbench.editor.waitForTypeInEditor('style.css', '.foo{}');
let error = await app.client.waitForElement(Problems.getSelectorInEditor(ProblemSeverity.ERROR));
await app.screenCapturer.capture('CSS Error in editor');
assert.ok(error, `Warning squiggle is not shown in 'style.css'.`);
const problems = new Problems(app);
await problems.showProblemsView();
error = await app.client.waitForElement(Problems.getSelectorInProblemsView(ProblemSeverity.ERROR));
await app.screenCapturer.capture('CSS Error in probles view');
assert.ok(error, 'Warning does not appear in Problems view.');
await problems.hideProblemsView();
});
});
it('verifies quick outline', async function () {
const app = this.app as SpectronApplication;
await app.workbench.quickopen.openFile('style.css');
await app.workbench.editor.openOutline();
await app.workbench.quickopen.waitForQuickOpenElements(names => names.length === 2);
});
it('verifies warnings for the empty rule', async function () {
const app = this.app as SpectronApplication;
await app.workbench.quickopen.openFile('style.css');
await app.workbench.editor.waitForTypeInEditor('style.css', '.foo{}');
let warning = await app.client.waitForElement(Problems.getSelectorInEditor(ProblemSeverity.WARNING));
await app.screenCapturer.capture('CSS Warning in editor');
assert.ok(warning, `Warning squiggle is not shown in 'style.css'.`);
await app.workbench.problems.showProblemsView();
warning = await app.client.waitForElement(Problems.getSelectorInProblemsView(ProblemSeverity.WARNING));
await app.screenCapturer.capture('CSS Warning in problems view');
assert.ok(warning, 'Warning does not appear in Problems view.');
await app.workbench.problems.hideProblemsView();
});
it('verifies that warning becomes an error once setting changed', async function () {
const app = this.app as SpectronApplication;
await app.workbench.settingsEditor.addUserSetting('css.lint.emptyRules', '"error"');
await app.workbench.quickopen.openFile('style.css');
await app.workbench.editor.waitForTypeInEditor('style.css', '.foo{}');
let error = await app.client.waitForElement(Problems.getSelectorInEditor(ProblemSeverity.ERROR));
await app.screenCapturer.capture('CSS Error in editor');
assert.ok(error, `Warning squiggle is not shown in 'style.css'.`);
const problems = new Problems(app);
await problems.showProblemsView();
error = await app.client.waitForElement(Problems.getSelectorInProblemsView(ProblemSeverity.ERROR));
await app.screenCapturer.capture('CSS Error in probles view');
assert.ok(error, 'Warning does not appear in Problems view.');
await problems.hideProblemsView();
});
});
}

View File

@@ -5,193 +5,125 @@
import * as assert from 'assert';
import * as http from 'http';
import * as os from 'os';
import * as path from 'path';
import * as fs from 'fs';
import * as stripJsonComments from 'strip-json-comments';
import { SpectronApplication, Quality } from '../../spectron/application';
import { SpectronApplication } from '../../spectron/application';
describe('Debug', () => {
let skip = false;
before(async function () {
const app = this.app as SpectronApplication;
if (app.quality === Quality.Dev) {
const extensionsPath = path.join(os.homedir(), '.vscode-oss-dev', 'extensions');
const debugPath = path.join(extensionsPath, 'vscode-node-debug');
const debugExists = fs.existsSync(debugPath);
const debug2Path = path.join(extensionsPath, 'vscode-node-debug2');
const debug2Exists = fs.existsSync(debug2Path);
if (!debugExists) {
console.warn(`Skipping debug tests because vscode-node-debug extension was not found in ${extensionsPath}`);
skip = true;
return;
}
if (!debug2Exists) {
console.warn(`Skipping debug tests because vscode-node-debug2 extension was not found in ${extensionsPath}`);
skip = true;
return;
}
await new Promise((c, e) => fs.symlink(debugPath, path.join(app.extensionsPath, 'vscode-node-debug'), err => err ? e(err) : c()));
await new Promise((c, e) => fs.symlink(debug2Path, path.join(app.extensionsPath, 'vscode-node-debug2'), err => err ? e(err) : c()));
await app.reload();
}
this.app.suiteName = 'Debug';
});
it('configure launch json', async function () {
if (skip) {
this.skip();
return;
}
const app = this.app as SpectronApplication;
await app.workbench.debug.openDebugViewlet();
await app.workbench.quickopen.openFile('app.js');
await app.workbench.debug.configure();
const launchJsonPath = path.join(app.workspacePath, '.vscode', 'launch.json');
const content = fs.readFileSync(launchJsonPath, 'utf8');
const config = JSON.parse(stripJsonComments(content));
config.configurations[0].protocol = 'inspector';
fs.writeFileSync(launchJsonPath, JSON.stringify(config, undefined, 4), 'utf8');
await app.workbench.editor.waitForEditorContents('launch.json', contents => /"protocol": "inspector"/.test(contents));
await app.screenCapturer.capture('launch.json file');
assert.equal(config.configurations[0].request, 'launch');
assert.equal(config.configurations[0].type, 'node');
if (process.platform === 'win32') {
assert.equal(config.configurations[0].program, '${workspaceFolder}\\bin\\www');
} else {
assert.equal(config.configurations[0].program, '${workspaceFolder}/bin/www');
}
});
it('breakpoints', async function () {
if (skip) {
this.skip();
return;
}
const app = this.app as SpectronApplication;
await app.workbench.quickopen.openFile('index.js');
await app.workbench.debug.setBreakpointOnLine(6);
await app.screenCapturer.capture('breakpoints are set');
});
let port: number;
it('start debugging', async function () {
if (skip) {
this.skip();
return;
}
const app = this.app as SpectronApplication;
port = await app.workbench.debug.startDebugging();
await app.screenCapturer.capture('debugging has started');
await new Promise((c, e) => {
const request = http.get(`http://localhost:${port}`);
request.on('error', e);
app.workbench.debug.waitForStackFrame(sf => sf.name === 'index.js' && sf.lineNumber === 6, 'looking for index.js and line 6').then(c, e);
export function setup() {
describe('Debug', () => {
before(async function () {
const app = this.app as SpectronApplication;
app.suiteName = 'Debug';
});
await app.screenCapturer.capture('debugging is paused');
});
it('configure launch json', async function () {
const app = this.app as SpectronApplication;
it('focus stack frames and variables', async function () {
if (skip) {
this.skip();
return;
}
await app.workbench.debug.openDebugViewlet();
await app.workbench.quickopen.openFile('app.js');
await app.workbench.debug.configure();
const app = this.app as SpectronApplication;
const launchJsonPath = path.join(app.workspacePath, '.vscode', 'launch.json');
const content = fs.readFileSync(launchJsonPath, 'utf8');
const config = JSON.parse(stripJsonComments(content));
config.configurations[0].protocol = 'inspector';
fs.writeFileSync(launchJsonPath, JSON.stringify(config, undefined, 4), 'utf8');
await app.client.waitFor(() => app.workbench.debug.getLocalVariableCount(), c => c === 4, 'there should be 4 local variables');
await app.workbench.editor.waitForEditorContents('launch.json', contents => /"protocol": "inspector"/.test(contents));
await app.screenCapturer.capture('launch.json file');
await app.workbench.debug.focusStackFrame('layer.js', 'looking for layer.js');
await app.client.waitFor(() => app.workbench.debug.getLocalVariableCount(), c => c === 5, 'there should be 5 local variables');
await app.workbench.debug.focusStackFrame('route.js', 'looking for route.js');
await app.client.waitFor(() => app.workbench.debug.getLocalVariableCount(), c => c === 3, 'there should be 3 local variables');
await app.workbench.debug.focusStackFrame('index.js', 'looking for index.js');
await app.client.waitFor(() => app.workbench.debug.getLocalVariableCount(), c => c === 4, 'there should be 4 local variables');
});
it('stepOver, stepIn, stepOut', async function () {
if (skip) {
this.skip();
return;
}
const app = this.app as SpectronApplication;
await app.workbench.debug.stepIn();
await app.screenCapturer.capture('debugging has stepped in');
const first = await app.workbench.debug.waitForStackFrame(sf => sf.name === 'response.js', 'looking for response.js');
await app.workbench.debug.stepOver();
await app.screenCapturer.capture('debugging has stepped over');
await app.workbench.debug.waitForStackFrame(sf => sf.name === 'response.js' && sf.lineNumber === first.lineNumber + 1, `looking for response.js and line ${first.lineNumber + 1}`);
await app.workbench.debug.stepOut();
await app.screenCapturer.capture('debugging has stepped out');
await app.workbench.debug.waitForStackFrame(sf => sf.name === 'index.js' && sf.lineNumber === 7, `looking for index.js and line 7`);
});
it('continue', async function () {
if (skip) {
this.skip();
return;
}
const app = this.app as SpectronApplication;
await app.workbench.debug.continue();
await app.screenCapturer.capture('debugging has continued');
await new Promise((c, e) => {
const request = http.get(`http://localhost:${port}`);
request.on('error', e);
app.workbench.debug.waitForStackFrame(sf => sf.name === 'index.js' && sf.lineNumber === 6, `looking for index.js and line 6`).then(c, e);
assert.equal(config.configurations[0].request, 'launch');
assert.equal(config.configurations[0].type, 'node');
if (process.platform === 'win32') {
assert.equal(config.configurations[0].program, '${workspaceFolder}\\bin\\www');
} else {
assert.equal(config.configurations[0].program, '${workspaceFolder}/bin/www');
}
});
await app.screenCapturer.capture('debugging is paused');
it('breakpoints', async function () {
const app = this.app as SpectronApplication;
await app.workbench.quickopen.openFile('index.js');
await app.workbench.debug.setBreakpointOnLine(6);
await app.screenCapturer.capture('breakpoints are set');
});
let port: number;
it('start debugging', async function () {
const app = this.app as SpectronApplication;
port = await app.workbench.debug.startDebugging();
await app.screenCapturer.capture('debugging has started');
await new Promise((c, e) => {
const request = http.get(`http://localhost:${port}`);
request.on('error', e);
app.workbench.debug.waitForStackFrame(sf => sf.name === 'index.js' && sf.lineNumber === 6, 'looking for index.js and line 6').then(c, e);
});
await app.screenCapturer.capture('debugging is paused');
});
it('focus stack frames and variables', async function () {
const app = this.app as SpectronApplication;
await app.client.waitFor(() => app.workbench.debug.getLocalVariableCount(), c => c === 4, 'there should be 4 local variables');
await app.workbench.debug.focusStackFrame('layer.js', 'looking for layer.js');
await app.client.waitFor(() => app.workbench.debug.getLocalVariableCount(), c => c === 5, 'there should be 5 local variables');
await app.workbench.debug.focusStackFrame('route.js', 'looking for route.js');
await app.client.waitFor(() => app.workbench.debug.getLocalVariableCount(), c => c === 3, 'there should be 3 local variables');
await app.workbench.debug.focusStackFrame('index.js', 'looking for index.js');
await app.client.waitFor(() => app.workbench.debug.getLocalVariableCount(), c => c === 4, 'there should be 4 local variables');
});
it('stepOver, stepIn, stepOut', async function () {
const app = this.app as SpectronApplication;
await app.workbench.debug.stepIn();
await app.screenCapturer.capture('debugging has stepped in');
const first = await app.workbench.debug.waitForStackFrame(sf => sf.name === 'response.js', 'looking for response.js');
await app.workbench.debug.stepOver();
await app.screenCapturer.capture('debugging has stepped over');
await app.workbench.debug.waitForStackFrame(sf => sf.name === 'response.js' && sf.lineNumber === first.lineNumber + 1, `looking for response.js and line ${first.lineNumber + 1}`);
await app.workbench.debug.stepOut();
await app.screenCapturer.capture('debugging has stepped out');
await app.workbench.debug.waitForStackFrame(sf => sf.name === 'index.js' && sf.lineNumber === 7, `looking for index.js and line 7`);
});
it('continue', async function () {
const app = this.app as SpectronApplication;
await app.workbench.debug.continue();
await app.screenCapturer.capture('debugging has continued');
await new Promise((c, e) => {
const request = http.get(`http://localhost:${port}`);
request.on('error', e);
app.workbench.debug.waitForStackFrame(sf => sf.name === 'index.js' && sf.lineNumber === 6, `looking for index.js and line 6`).then(c, e);
});
await app.screenCapturer.capture('debugging is paused');
});
it('debug console', async function () {
const app = this.app as SpectronApplication;
await app.workbench.debug.waitForReplCommand('2 + 2', r => r === '4');
});
it('stop debugging', async function () {
const app = this.app as SpectronApplication;
await app.workbench.debug.stopDebugging();
await app.screenCapturer.capture('debugging has stopped');
});
});
it('debug console', async function () {
if (skip) {
this.skip();
return;
}
const app = this.app as SpectronApplication;
await app.workbench.debug.waitForReplCommand('2 + 2', r => r === '4');
});
it('stop debugging', async function () {
if (skip) {
this.skip();
return;
}
const app = this.app as SpectronApplication;
await app.workbench.debug.stopDebugging();
await app.screenCapturer.capture('debugging has stopped');
});
});
}

View File

@@ -16,7 +16,7 @@ const STEP_IN = `.debug-actions-widget .debug-action.step-into`;
const STEP_OUT = `.debug-actions-widget .debug-action.step-out`;
const CONTINUE = `.debug-actions-widget .debug-action.continue`;
const GLYPH_AREA = '.margin-view-overlays>:nth-child';
const BREAKPOINT_GLYPH = '.debug-breakpoint-glyph';
const BREAKPOINT_GLYPH = '.debug-breakpoint';
const PAUSE = `.debug-actions-widget .debug-action.pause`;
const DEBUG_STATUS_BAR = `.statusbar.debugging`;
const NOT_DEBUG_STATUS_BAR = `.statusbar:not(debugging)`;

View File

@@ -5,69 +5,71 @@
import { SpectronApplication } from '../../spectron/application';
describe('Editor', () => {
before(function () {
this.app.suiteName = 'Editor';
export function setup() {
describe('Editor', () => {
before(function () {
this.app.suiteName = 'Editor';
});
it('shows correct quick outline', async function () {
const app = this.app as SpectronApplication;
await app.workbench.quickopen.openFile('www');
await app.workbench.editor.openOutline();
await app.workbench.quickopen.waitForQuickOpenElements(names => names.length >= 6);
});
it(`finds 'All References' to 'app'`, async function () {
const app = this.app as SpectronApplication;
await app.workbench.quickopen.openFile('www');
const references = await app.workbench.editor.findReferences('app', 7);
await references.waitForReferencesCountInTitle(3);
await references.waitForReferencesCount(3);
await references.close();
});
it(`renames local 'app' variable`, async function () {
const app = this.app as SpectronApplication;
await app.workbench.quickopen.openFile('www');
await app.workbench.editor.rename('www', 7, 'app', 'newApp');
await app.workbench.editor.waitForEditorContents('www', contents => contents.indexOf('newApp') > -1);
await app.screenCapturer.capture('Rename result');
});
// it('folds/unfolds the code correctly', async function () {
// await app.workbench.quickopen.openFile('www');
// // Fold
// await app.workbench.editor.foldAtLine(3);
// await app.workbench.editor.waitUntilShown(3);
// await app.workbench.editor.waitUntilHidden(4);
// await app.workbench.editor.waitUntilHidden(5);
// // Unfold
// await app.workbench.editor.unfoldAtLine(3);
// await app.workbench.editor.waitUntilShown(3);
// await app.workbench.editor.waitUntilShown(4);
// await app.workbench.editor.waitUntilShown(5);
// });
it(`verifies that 'Go To Definition' works`, async function () {
const app = this.app as SpectronApplication;
await app.workbench.quickopen.openFile('app.js');
await app.workbench.editor.gotoDefinition('express', 11);
await app.workbench.waitForActiveTab('index.d.ts');
});
it(`verifies that 'Peek Definition' works`, async function () {
const app = this.app as SpectronApplication;
await app.workbench.quickopen.openFile('app.js');
const peek = await app.workbench.editor.peekDefinition('express', 11);
await peek.waitForFile('index.d.ts');
});
});
it('shows correct quick outline', async function () {
const app = this.app as SpectronApplication;
await app.workbench.quickopen.openFile('www');
await app.workbench.editor.openOutline();
await app.workbench.quickopen.waitForQuickOpenElements(names => names.length >= 6);
});
it(`finds 'All References' to 'app'`, async function () {
const app = this.app as SpectronApplication;
await app.workbench.quickopen.openFile('www');
const references = await app.workbench.editor.findReferences('app', 7);
await references.waitForReferencesCountInTitle(3);
await references.waitForReferencesCount(3);
await references.close();
});
it(`renames local 'app' variable`, async function () {
const app = this.app as SpectronApplication;
await app.workbench.quickopen.openFile('www');
await app.workbench.editor.rename('www', 7, 'app', 'newApp');
await app.workbench.editor.waitForEditorContents('www', contents => contents.indexOf('newApp') > -1);
await app.screenCapturer.capture('Rename result');
});
// it('folds/unfolds the code correctly', async function () {
// await app.workbench.quickopen.openFile('www');
// // Fold
// await app.workbench.editor.foldAtLine(3);
// await app.workbench.editor.waitUntilShown(3);
// await app.workbench.editor.waitUntilHidden(4);
// await app.workbench.editor.waitUntilHidden(5);
// // Unfold
// await app.workbench.editor.unfoldAtLine(3);
// await app.workbench.editor.waitUntilShown(3);
// await app.workbench.editor.waitUntilShown(4);
// await app.workbench.editor.waitUntilShown(5);
// });
it(`verifies that 'Go To Definition' works`, async function () {
const app = this.app as SpectronApplication;
await app.workbench.quickopen.openFile('app.js');
await app.workbench.editor.gotoDefinition('express', 11);
await app.workbench.waitForActiveTab('index.d.ts');
});
it(`verifies that 'Peek Definition' works`, async function () {
const app = this.app as SpectronApplication;
await app.workbench.quickopen.openFile('app.js');
const peek = await app.workbench.editor.peekDefinition('express', 11);
await peek.waitForFile('index.d.ts');
});
});
}

View File

@@ -5,38 +5,40 @@
import { SpectronApplication } from '../../spectron/application';
describe('Explorer', () => {
before(function () {
this.app.suiteName = 'Explorer';
export function setup() {
describe('Explorer', () => {
before(function () {
this.app.suiteName = 'Explorer';
});
it('quick open search produces correct result', async function () {
const app = this.app as SpectronApplication;
const expectedNames = [
'.eslintrc.json',
'tasks.json',
'app.js',
'index.js',
'users.js',
'package.json',
'jsconfig.json'
];
await app.workbench.quickopen.openQuickOpen('.js');
await app.workbench.quickopen.waitForQuickOpenElements(names => expectedNames.every(n => names.some(m => n === m)));
await app.client.keys(['Escape', 'NULL']);
});
it('quick open respects fuzzy matching', async function () {
const app = this.app as SpectronApplication;
const expectedNames = [
'tasks.json',
'app.js',
'package.json'
];
await app.workbench.quickopen.openQuickOpen('a.s');
await app.workbench.quickopen.waitForQuickOpenElements(names => expectedNames.every(n => names.some(m => n === m)));
await app.client.keys(['Escape', 'NULL']);
});
});
it('quick open search produces correct result', async function () {
const app = this.app as SpectronApplication;
const expectedNames = [
'.eslintrc.json',
'tasks.json',
'app.js',
'index.js',
'users.js',
'package.json',
'jsconfig.json'
];
await app.workbench.quickopen.openQuickOpen('.js');
await app.workbench.quickopen.waitForQuickOpenElements(names => expectedNames.every(n => names.some(m => n === m)));
await app.client.keys(['Escape', 'NULL']);
});
it('quick open respects fuzzy matching', async function () {
const app = this.app as SpectronApplication;
const expectedNames = [
'tasks.json',
'app.js',
'package.json'
];
await app.workbench.quickopen.openQuickOpen('a.s');
await app.workbench.quickopen.waitForQuickOpenElements(names => expectedNames.every(n => names.some(m => n === m)));
await app.client.keys(['Escape', 'NULL']);
});
});
}

View File

@@ -6,31 +6,33 @@
import * as assert from 'assert';
import { SpectronApplication, Quality } from '../../spectron/application';
describe('Extensions', () => {
before(function () {
this.app.suiteName = 'Extensions';
export function setup() {
describe('Extensions', () => {
before(function () {
this.app.suiteName = 'Extensions';
});
it(`install and activate vscode-smoketest-check extension`, async function () {
const app = this.app as SpectronApplication;
if (app.quality === Quality.Dev) {
this.skip();
return;
}
const extensionName = 'vscode-smoketest-check';
await app.workbench.extensions.openExtensionsViewlet();
const installed = await app.workbench.extensions.installExtension(extensionName);
assert.ok(installed);
await app.reload();
await app.workbench.extensions.waitForExtensionsViewlet();
await app.workbench.quickopen.runCommand('Smoke Test Check');
const statusbarText = await app.workbench.statusbar.getStatusbarTextByTitle('smoke test');
await app.screenCapturer.capture('Statusbar');
assert.equal(statusbarText, 'VS Code Smoke Test Check');
});
});
it(`install and activate vscode-smoketest-check extension`, async function () {
const app = this.app as SpectronApplication;
if (app.quality === Quality.Dev) {
this.skip();
return;
}
const extensionName = 'vscode-smoketest-check';
await app.workbench.extensions.openExtensionsViewlet();
const installed = await app.workbench.extensions.installExtension(extensionName);
assert.ok(installed);
await app.reload();
await app.workbench.extensions.waitForExtensionsViewlet();
await app.workbench.quickopen.runCommand('Smoke Test Check');
const statusbarText = await app.workbench.statusbar.getStatusbarTextByTitle('smoke test');
await app.screenCapturer.capture('Statusbar');
assert.equal(statusbarText, 'VS Code Smoke Test Check');
});
});
}

View File

@@ -3,84 +3,79 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as assert from 'assert';
import * as cp from 'child_process';
import { SpectronApplication } from '../../spectron/application';
const DIFF_EDITOR_LINE_INSERT = '.monaco-diff-editor .editor.modified .line-insert';
const SYNC_STATUSBAR = 'div[id="workbench.parts.statusbar"] .statusbar-entry a[title$="Synchronize Changes"]';
describe('Git', () => {
before(function () {
this.app.suiteName = 'Git';
export function setup() {
describe('Git', () => {
before(async function () {
const app = this.app as SpectronApplication;
app.suiteName = 'Git';
});
it('reflects working tree changes', async function () {
const app = this.app as SpectronApplication;
await app.workbench.scm.openSCMViewlet();
await app.workbench.quickopen.openFile('app.js');
await app.workbench.editor.waitForTypeInEditor('app.js', '.foo{}');
await app.workbench.saveOpenedFile();
await app.workbench.quickopen.openFile('index.jade');
await app.workbench.editor.waitForTypeInEditor('index.jade', 'hello world');
await app.workbench.saveOpenedFile();
await app.workbench.scm.refreshSCMViewlet();
await app.workbench.scm.waitForChange('app.js', 'Modified');
await app.workbench.scm.waitForChange('index.jade', 'Modified');
await app.screenCapturer.capture('changes');
});
it('opens diff editor', async function () {
const app = this.app as SpectronApplication;
await app.workbench.scm.openSCMViewlet();
await app.workbench.scm.openChange('app.js');
await app.client.waitForElement(DIFF_EDITOR_LINE_INSERT);
});
it('stages correctly', async function () {
const app = this.app as SpectronApplication;
await app.workbench.scm.openSCMViewlet();
await app.workbench.scm.waitForChange('app.js', 'Modified');
await app.workbench.scm.stage('app.js');
await app.workbench.scm.waitForChange('app.js', 'Index Modified');
await app.workbench.scm.unstage('app.js');
await app.workbench.scm.waitForChange('app.js', 'Modified');
});
it(`stages, commits changes and verifies outgoing change`, async function () {
const app = this.app as SpectronApplication;
await app.workbench.scm.openSCMViewlet();
await app.workbench.scm.waitForChange('app.js', 'Modified');
await app.workbench.scm.stage('app.js');
await app.workbench.scm.waitForChange('app.js', 'Index Modified');
await app.workbench.scm.commit('first commit');
await app.client.waitForText(SYNC_STATUSBAR, ' 0↓ 1↑');
await app.workbench.quickopen.runCommand('Git: Stage All Changes');
await app.workbench.scm.waitForChange('index.jade', 'Index Modified');
await app.workbench.scm.commit('second commit');
await app.client.waitForText(SYNC_STATUSBAR, ' 0↓ 2↑');
cp.execSync('git reset --hard origin/master', { cwd: app.workspacePath });
});
});
it('reflects working tree changes', async function () {
const app = this.app as SpectronApplication;
await app.workbench.scm.openSCMViewlet();
await app.workbench.quickopen.openFile('app.js');
await app.workbench.editor.waitForTypeInEditor('app.js', '.foo{}');
await app.workbench.saveOpenedFile();
await app.workbench.quickopen.openFile('index.jade');
await app.workbench.editor.waitForTypeInEditor('index.jade', 'hello world');
await app.workbench.saveOpenedFile();
await app.workbench.scm.refreshSCMViewlet();
const appJs = await app.workbench.scm.waitForChange(c => c.name === 'app.js');
const indexJade = await app.workbench.scm.waitForChange(c => c.name === 'index.jade');
await app.screenCapturer.capture('changes');
assert.equal(appJs.name, 'app.js');
assert.equal(appJs.type, 'Modified');
assert.equal(indexJade.name, 'index.jade');
assert.equal(indexJade.type, 'Modified');
});
it('opens diff editor', async function () {
const app = this.app as SpectronApplication;
await app.workbench.scm.openSCMViewlet();
const appJs = await app.workbench.scm.waitForChange(c => c.name === 'app.js');
await app.workbench.scm.openChange(appJs);
await app.client.waitForElement(DIFF_EDITOR_LINE_INSERT);
});
it('stages correctly', async function () {
const app = this.app as SpectronApplication;
await app.workbench.scm.openSCMViewlet();
const appJs = await app.workbench.scm.waitForChange(c => c.name === 'app.js' && c.type === 'Modified');
await app.workbench.scm.stage(appJs);
const indexAppJs = await app.workbench.scm.waitForChange(c => c.name === 'app.js' && c.type === 'Index Modified');
await app.workbench.scm.unstage(indexAppJs);
await app.workbench.scm.waitForChange(c => c.name === 'app.js' && c.type === 'Modified');
});
it(`stages, commits changes and verifies outgoing change`, async function () {
const app = this.app as SpectronApplication;
await app.workbench.scm.openSCMViewlet();
const appJs = await app.workbench.scm.waitForChange(c => c.name === 'app.js' && c.type === 'Modified');
await app.workbench.scm.stage(appJs);
await app.workbench.scm.waitForChange(c => c.name === 'app.js' && c.type === 'Index Modified');
await app.workbench.scm.commit('first commit');
await app.client.waitForText(SYNC_STATUSBAR, ' 0↓ 1↑');
await app.workbench.quickopen.runCommand('Git: Stage All Changes');
await app.workbench.scm.waitForChange(c => c.name === 'index.jade' && c.type === 'Index Modified');
await app.workbench.scm.commit('second commit');
await app.client.waitForText(SYNC_STATUSBAR, ' 0↓ 2↑');
cp.execSync('git reset --hard origin/master', { cwd: app.workspacePath });
});
});
}

View File

@@ -3,7 +3,6 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as assert from 'assert';
import { SpectronApplication } from '../../spectron/application';
import { Viewlet } from '../workbench/viewlet';
@@ -13,14 +12,14 @@ const SCM_RESOURCE = `${VIEWLET} .monaco-list-row > .resource`;
const SCM_RESOURCE_GROUP = `${VIEWLET} .monaco-list-row > .resource-group`;
const REFRESH_COMMAND = `div[id="workbench.parts.sidebar"] .actions-container a.action-label[title="Refresh"]`;
const COMMIT_COMMAND = `div[id="workbench.parts.sidebar"] .actions-container a.action-label[title="Commit"]`;
const SCM_RESOURCE_CLICK = name => `${SCM_RESOURCE} .monaco-icon-label[title*="${name}"]`;
const SCM_RESOURCE_GROUP_COMMAND_CLICK = name => `${SCM_RESOURCE_GROUP} .actions .action-label[title="${name}"]`;
const SCM_RESOURCE_CLICK = (name: string) => `${SCM_RESOURCE} .monaco-icon-label[title*="${name}"] .label-name`;
const SCM_RESOURCE_ACTION_CLICK = (name: string, actionName: string) => `${SCM_RESOURCE} .monaco-icon-label[title*="${name}"] .actions .action-label[title="${actionName}"]`;
const SCM_RESOURCE_GROUP_COMMAND_CLICK = (name: string) => `${SCM_RESOURCE_GROUP} .actions .action-label[title="${name}"]`;
export interface Change {
id: string;
interface Change {
name: string;
type: string;
actions: { id: string, title: string; }[];
actions: string[];
}
export class SCM extends Viewlet {
@@ -34,64 +33,67 @@ export class SCM extends Viewlet {
await this.spectron.client.waitForElement(SCM_INPUT);
}
async waitForChange(func: (change: Change) => boolean): Promise<Change> {
return await this.spectron.client.waitFor(async () => {
const changes = await this.getChanges();
return changes.filter(func)[0];
}, void 0, 'Getting changes');
waitForChange(name: string, type?: string): Promise<void> {
return this.spectron.client.waitFor(async () => {
const changes = await this.queryChanges(name, type);
return changes.length;
}, l => l > 0, 'Getting SCM changes') as Promise<any> as Promise<void>;
}
async refreshSCMViewlet(): Promise<any> {
await this.spectron.client.click(REFRESH_COMMAND);
}
async getChanges(): Promise<Change[]> {
const result = await this.spectron.webclient.selectorExecute(SCM_RESOURCE,
div => (Array.isArray(div) ? div : [div]).map(element => {
const name = element.querySelector('.label-name') as HTMLElement;
const icon = element.querySelector('.decoration-icon') as HTMLElement;
const actionElementList = element.querySelectorAll('.actions .action-label');
const actionElements: any[] = [];
private async queryChanges(name: string, type?: string): Promise<Change[]> {
const result = await this.spectron.webclient.selectorExecute(SCM_RESOURCE, (div, name, type) => {
return (Array.isArray(div) ? div : [div])
.map(element => {
const name = element.querySelector('.label-name') as HTMLElement;
const type = element.getAttribute('data-tooltip') || '';
const actionElementList = element.querySelectorAll('.actions .action-label');
const actions: string[] = [];
for (let i = 0; i < actionElementList.length; i++) {
const element = actionElementList.item(i) as HTMLElement;
actionElements.push({ element, title: element.title });
}
for (let i = 0; i < actionElementList.length; i++) {
const element = actionElementList.item(i) as HTMLElement;
actions.push(element.title);
}
return {
name: name.textContent,
type: (icon.title || ''),
element,
actionElements
};
})
);
return {
name: name.textContent,
type,
actions
};
})
.filter(change => {
if (change.name !== name) {
return false;
}
return result.map(({ name, type, element, actionElements }) => {
// const actions = actionElements.reduce((r, { element, title }) => r[title] = element.ELEMENT, {});
const actions = actionElements.map(({ element, title }) => ({ id: element.ELEMENT, title }));
return { name, type, id: element.ELEMENT, actions };
});
if (type && (change.type !== type)) {
return false;
}
return true;
});
}, name, type);
return result;
}
async openChange(change: Change): Promise<void> {
await this.spectron.client.waitAndClick(SCM_RESOURCE_CLICK(change.name));
async openChange(name: string): Promise<void> {
await this.spectron.client.waitAndClick(SCM_RESOURCE_CLICK(name));
}
async stage(change: Change): Promise<void> {
const action = change.actions.filter(a => a.title === 'Stage Changes')[0];
assert(action);
await this.spectron.client.spectron.client.elementIdClick(action.id);
async stage(name: string): Promise<void> {
await this.spectron.client.waitAndClick(SCM_RESOURCE_ACTION_CLICK(name, 'Stage Changes'));
}
async stageAll(): Promise<void> {
await this.spectron.client.waitAndClick(SCM_RESOURCE_GROUP_COMMAND_CLICK('Stage All Changes'));
}
async unstage(change: Change): Promise<void> {
const action = change.actions.filter(a => a.title === 'Unstage Changes')[0];
assert(action);
await this.spectron.client.spectron.client.elementIdClick(action.id);
async unstage(name: string): Promise<void> {
await this.spectron.client.waitAndClick(SCM_RESOURCE_ACTION_CLICK(name, 'Unstage Changes'));
}
async commit(message: string): Promise<void> {

View File

@@ -6,32 +6,32 @@
import * as assert from 'assert';
import { SpectronApplication } from '../../spectron/application';
describe('Multiroot', () => {
export function setup() {
describe('Multiroot', () => {
before(async function () {
this.app.suiteName = 'Multiroot';
before(async function () {
this.app.suiteName = 'Multiroot';
const app = this.app as SpectronApplication;
const app = this.app as SpectronApplication;
await app.restart([app.workspaceFilePath]);
// restart with preventing additional windows from restoring
// to ensure the window after restart is the multi-root workspace
await app.restart({ workspaceOrFolder: app.workspaceFilePath, extraArgs: ['--disable-restore-windows'] });
});
// for some reason Code opens 2 windows at this point
// so let's select the last one
await app.client.windowByIndex(1);
it('shows results from all folders', async function () {
const app = this.app as SpectronApplication;
await app.workbench.quickopen.openQuickOpen('*.*');
await app.workbench.quickopen.waitForQuickOpenElements(names => names.length === 6);
await app.workbench.quickopen.closeQuickOpen();
});
it('shows workspace name in title', async function () {
const app = this.app as SpectronApplication;
const title = await app.client.getTitle();
await app.screenCapturer.capture('window title');
assert.ok(title.indexOf('smoketest (Workspace)') >= 0);
});
});
it('shows results from all folders', async function () {
const app = this.app as SpectronApplication;
await app.workbench.quickopen.openQuickOpen('*.*');
await app.workbench.quickopen.waitForQuickOpenElements(names => names.length >= 6);
await app.workbench.quickopen.closeQuickOpen();
});
it('shows workspace name in title', async function () {
const app = this.app as SpectronApplication;
const title = await app.client.getTitle();
await app.screenCapturer.capture('window title');
assert.ok(title.indexOf('smoketest (Workspace)') >= 0);
});
});
}

View File

@@ -8,39 +8,41 @@ import * as assert from 'assert';
import { SpectronApplication } from '../../spectron/application';
import { ActivityBarPosition } from '../activitybar/activityBar';
describe('Preferences', () => {
before(function () {
this.app.suiteName = 'Preferences';
export function setup() {
describe('Preferences', () => {
before(function () {
this.app.suiteName = 'Preferences';
});
it('turns off editor line numbers and verifies the live change', async function () {
const app = this.app as SpectronApplication;
await app.workbench.explorer.openFile('app.js');
let lineNumbers = await app.client.waitForElements('.line-numbers');
await app.screenCapturer.capture('app.js has line numbers');
assert.ok(!!lineNumbers.length, 'Line numbers are not present in the editor before disabling them.');
await app.workbench.settingsEditor.addUserSetting('editor.lineNumbers', '"off"');
await app.workbench.selectTab('app.js');
lineNumbers = await app.client.waitForElements('.line-numbers', result => !result || result.length === 0);
await app.screenCapturer.capture('line numbers hidden');
assert.ok(!lineNumbers.length, 'Line numbers are still present in the editor after disabling them.');
});
it(`changes 'workbench.action.toggleSidebarPosition' command key binding and verifies it`, async function () {
const app = this.app as SpectronApplication;
assert.ok(await app.workbench.activitybar.getActivityBar(ActivityBarPosition.LEFT), 'Activity bar should be positioned on the left.');
await app.workbench.keybindingsEditor.updateKeybinding('workbench.action.toggleSidebarPosition', ['Control', 'u'], 'Control+U');
await app.client.keys(['Control', 'u', 'NULL']);
assert.ok(await app.workbench.activitybar.getActivityBar(ActivityBarPosition.RIGHT), 'Activity bar was not moved to right after toggling its position.');
});
after(async function () {
const app = this.app as SpectronApplication;
await app.workbench.settingsEditor.clearUserSettings();
});
});
it('turns off editor line numbers and verifies the live change', async function () {
const app = this.app as SpectronApplication;
await app.workbench.explorer.openFile('app.js');
let lineNumbers = await app.client.waitForElements('.line-numbers');
await app.screenCapturer.capture('app.js has line numbers');
assert.ok(!!lineNumbers.length, 'Line numbers are not present in the editor before disabling them.');
await app.workbench.settingsEditor.addUserSetting('editor.lineNumbers', '"off"');
await app.workbench.selectTab('app.js');
lineNumbers = await app.client.waitForElements('.line-numbers', result => !result || result.length === 0);
await app.screenCapturer.capture('line numbers hidden');
assert.ok(!lineNumbers.length, 'Line numbers are still present in the editor after disabling them.');
});
it(`changes 'workbench.action.toggleSidebarPosition' command key binding and verifies it`, async function () {
const app = this.app as SpectronApplication;
assert.ok(await app.workbench.activitybar.getActivityBar(ActivityBarPosition.LEFT), 'Activity bar should be positioned on the left.');
await app.workbench.keybindingsEditor.updateKeybinding('workbench.action.toggleSidebarPosition', ['Control', 'u'], 'Control+U');
await app.client.keys(['Control', 'u', 'NULL']);
assert.ok(await app.workbench.activitybar.getActivityBar(ActivityBarPosition.RIGHT), 'Activity bar was not moved to right after toggling its position.');
});
after(async function () {
const app = this.app as SpectronApplication;
await app.workbench.settingsEditor.clearUserSettings();
});
});
}

View File

@@ -50,9 +50,6 @@ export class QuickOpen {
async waitForQuickOpenOpened(): Promise<void> {
await this.spectron.client.waitForActiveElement(QuickOpen.QUICK_OPEN_INPUT);
// we gotta wait 50 milliseconds due to https://github.com/Microsoft/vscode/blob/master/src/vs/platform/list/browser/listService.ts#L59
await new Promise(c => setTimeout(c, 50));
}
private async waitForQuickOpenClosed(): Promise<void> {

View File

@@ -5,52 +5,54 @@
import { SpectronApplication } from '../../spectron/application';
describe('Search', () => {
before(function () {
this.app.suiteName = 'Search';
export function setup() {
describe('Search', () => {
before(function () {
this.app.suiteName = 'Search';
});
it('searches for body & checks for correct result number', async function () {
const app = this.app as SpectronApplication;
await app.workbench.search.openSearchViewlet();
await app.workbench.search.searchFor('body');
await app.workbench.search.waitForResultText('14 results in 5 files');
});
it('searches only for *.js files & checks for correct result number', async function () {
const app = this.app as SpectronApplication;
await app.workbench.search.searchFor('body');
await app.workbench.search.showQueryDetails();
await app.workbench.search.setFilesToIncludeText('*.js');
await app.workbench.search.submitSearch();
await app.workbench.search.waitForResultText('4 results in 1 file');
await app.workbench.search.setFilesToIncludeText('');
await app.workbench.search.hideQueryDetails();
});
it('dismisses result & checks for correct result number', async function () {
const app = this.app as SpectronApplication;
await app.workbench.search.searchFor('body');
await app.workbench.search.removeFileMatch(1);
await app.workbench.search.waitForResultText('10 results in 4 files');
});
it('replaces first search result with a replace term', async function () {
const app = this.app as SpectronApplication;
await app.workbench.search.searchFor('body');
await app.workbench.search.expandReplace();
await app.workbench.search.setReplaceText('ydob');
await app.workbench.search.replaceFileMatch(1);
await app.workbench.saveOpenedFile();
await app.workbench.search.waitForResultText('10 results in 4 files');
await app.workbench.search.searchFor('ydob');
await app.workbench.search.setReplaceText('body');
await app.workbench.search.replaceFileMatch(1);
await app.workbench.saveOpenedFile();
});
});
it('searches for body & checks for correct result number', async function () {
const app = this.app as SpectronApplication;
await app.workbench.search.openSearchViewlet();
await app.workbench.search.searchFor('body');
await app.workbench.search.waitForResultText('14 results in 5 files');
});
it('searches only for *.js files & checks for correct result number', async function () {
const app = this.app as SpectronApplication;
await app.workbench.search.searchFor('body');
await app.workbench.search.showQueryDetails();
await app.workbench.search.setFilesToIncludeText('*.js');
await app.workbench.search.submitSearch();
await app.workbench.search.waitForResultText('4 results in 1 file');
await app.workbench.search.setFilesToIncludeText('');
await app.workbench.search.hideQueryDetails();
});
it('dismisses result & checks for correct result number', async function () {
const app = this.app as SpectronApplication;
await app.workbench.search.searchFor('body');
await app.workbench.search.removeFileMatch(1);
await app.workbench.search.waitForResultText('10 results in 4 files');
});
it('replaces first search result with a replace term', async function () {
const app = this.app as SpectronApplication;
await app.workbench.search.searchFor('body');
await app.workbench.search.expandReplace();
await app.workbench.search.setReplaceText('ydob');
await app.workbench.search.replaceFileMatch(1);
await app.workbench.saveOpenedFile();
await app.workbench.search.waitForResultText('10 results in 4 files');
await app.workbench.search.searchFor('ydob');
await app.workbench.search.setReplaceText('body');
await app.workbench.search.replaceFileMatch(1);
await app.workbench.saveOpenedFile();
});
});
}

View File

@@ -6,7 +6,7 @@
import { SpectronApplication } from '../../spectron/application';
import { Viewlet } from '../workbench/viewlet';
const VIEWLET = 'div[id="workbench.view.search"] .search-viewlet';
const VIEWLET = 'div[id="workbench.view.search"] .search-view';
const INPUT = `${VIEWLET} .search-widget .search-container .monaco-inputbox input`;
const INCLUDE_INPUT = `${VIEWLET} .query-details .monaco-inputbox input[aria-label="Search Include Patterns"]`;
@@ -84,4 +84,4 @@ export class Search extends Viewlet {
async waitForResultText(text: string): Promise<void> {
await this.spectron.client.waitForText(`${VIEWLET} .messages[aria-hidden="false"] .message>p`, text);
}
}
}

View File

@@ -8,90 +8,92 @@ import * as assert from 'assert';
import { SpectronApplication, Quality } from '../../spectron/application';
import { StatusBarElement } from './statusbar';
describe('Statusbar', () => {
before(function () {
this.app.suiteName = 'Statusbar';
export function setup() {
describe('Statusbar', () => {
before(function () {
this.app.suiteName = 'Statusbar';
});
it('verifies presence of all default status bar elements', async function () {
const app = this.app as SpectronApplication;
await app.workbench.statusbar.waitForStatusbarElement(StatusBarElement.BRANCH_STATUS);
if (app.quality !== Quality.Dev) {
await app.workbench.statusbar.waitForStatusbarElement(StatusBarElement.FEEDBACK_ICON);
}
await app.workbench.statusbar.waitForStatusbarElement(StatusBarElement.SYNC_STATUS);
await app.workbench.statusbar.waitForStatusbarElement(StatusBarElement.PROBLEMS_STATUS);
await app.workbench.quickopen.openFile('app.js');
await app.workbench.statusbar.waitForStatusbarElement(StatusBarElement.ENCODING_STATUS);
await app.workbench.statusbar.waitForStatusbarElement(StatusBarElement.EOL_STATUS);
await app.workbench.statusbar.waitForStatusbarElement(StatusBarElement.INDENTATION_STATUS);
await app.workbench.statusbar.waitForStatusbarElement(StatusBarElement.LANGUAGE_STATUS);
await app.workbench.statusbar.waitForStatusbarElement(StatusBarElement.SELECTION_STATUS);
});
it(`verifies that 'quick open' opens when clicking on status bar elements`, async function () {
const app = this.app as SpectronApplication;
await app.workbench.statusbar.clickOn(StatusBarElement.BRANCH_STATUS);
await app.workbench.quickopen.waitForQuickOpenOpened();
await app.workbench.quickopen.closeQuickOpen();
await app.workbench.quickopen.openFile('app.js');
await app.workbench.statusbar.clickOn(StatusBarElement.INDENTATION_STATUS);
await app.workbench.quickopen.waitForQuickOpenOpened();
await app.workbench.quickopen.closeQuickOpen();
await app.workbench.statusbar.clickOn(StatusBarElement.ENCODING_STATUS);
await app.workbench.quickopen.waitForQuickOpenOpened();
await app.workbench.quickopen.closeQuickOpen();
await app.workbench.statusbar.clickOn(StatusBarElement.EOL_STATUS);
await app.workbench.quickopen.waitForQuickOpenOpened();
await app.workbench.quickopen.closeQuickOpen();
await app.workbench.statusbar.clickOn(StatusBarElement.LANGUAGE_STATUS);
await app.workbench.quickopen.waitForQuickOpenOpened();
await app.workbench.quickopen.closeQuickOpen();
});
it(`verifies that 'Problems View' appears when clicking on 'Problems' status element`, async function () {
const app = this.app as SpectronApplication;
await app.workbench.statusbar.clickOn(StatusBarElement.PROBLEMS_STATUS);
await app.workbench.problems.waitForProblemsView();
});
it(`verifies that 'Tweet us feedback' pop-up appears when clicking on 'Feedback' icon`, async function () {
const app = this.app as SpectronApplication;
if (app.quality === Quality.Dev) {
return this.skip();
}
await app.workbench.statusbar.clickOn(StatusBarElement.FEEDBACK_ICON);
assert.ok(!!await app.client.waitForElement('.feedback-form'));
});
it(`checks if 'Go to Line' works if called from the status bar`, async function () {
const app = this.app as SpectronApplication;
await app.workbench.quickopen.openFile('app.js');
await app.workbench.statusbar.clickOn(StatusBarElement.SELECTION_STATUS);
await app.workbench.quickopen.waitForQuickOpenOpened();
await app.workbench.quickopen.submit(':15');
await app.workbench.editor.waitForHighlightingLine(15);
});
it(`verifies if changing EOL is reflected in the status bar`, async function () {
const app = this.app as SpectronApplication;
await app.workbench.quickopen.openFile('app.js');
await app.workbench.statusbar.clickOn(StatusBarElement.EOL_STATUS);
await app.workbench.quickopen.waitForQuickOpenOpened();
await app.workbench.quickopen.selectQuickOpenElement(1);
await app.workbench.statusbar.waitForEOL('CRLF');
});
});
it('verifies presence of all default status bar elements', async function () {
const app = this.app as SpectronApplication;
await app.workbench.statusbar.waitForStatusbarElement(StatusBarElement.BRANCH_STATUS);
if (app.quality !== Quality.Dev) {
await app.workbench.statusbar.waitForStatusbarElement(StatusBarElement.FEEDBACK_ICON);
}
await app.workbench.statusbar.waitForStatusbarElement(StatusBarElement.SYNC_STATUS);
await app.workbench.statusbar.waitForStatusbarElement(StatusBarElement.PROBLEMS_STATUS);
await app.workbench.quickopen.openFile('app.js');
await app.workbench.statusbar.waitForStatusbarElement(StatusBarElement.ENCODING_STATUS);
await app.workbench.statusbar.waitForStatusbarElement(StatusBarElement.EOL_STATUS);
await app.workbench.statusbar.waitForStatusbarElement(StatusBarElement.INDENTATION_STATUS);
await app.workbench.statusbar.waitForStatusbarElement(StatusBarElement.LANGUAGE_STATUS);
await app.workbench.statusbar.waitForStatusbarElement(StatusBarElement.SELECTION_STATUS);
});
it(`verifies that 'quick open' opens when clicking on status bar elements`, async function () {
const app = this.app as SpectronApplication;
await app.workbench.statusbar.clickOn(StatusBarElement.BRANCH_STATUS);
await app.workbench.quickopen.waitForQuickOpenOpened();
await app.workbench.quickopen.closeQuickOpen();
await app.workbench.quickopen.openFile('app.js');
await app.workbench.statusbar.clickOn(StatusBarElement.INDENTATION_STATUS);
await app.workbench.quickopen.waitForQuickOpenOpened();
await app.workbench.quickopen.closeQuickOpen();
await app.workbench.statusbar.clickOn(StatusBarElement.ENCODING_STATUS);
await app.workbench.quickopen.waitForQuickOpenOpened();
await app.workbench.quickopen.closeQuickOpen();
await app.workbench.statusbar.clickOn(StatusBarElement.EOL_STATUS);
await app.workbench.quickopen.waitForQuickOpenOpened();
await app.workbench.quickopen.closeQuickOpen();
await app.workbench.statusbar.clickOn(StatusBarElement.LANGUAGE_STATUS);
await app.workbench.quickopen.waitForQuickOpenOpened();
await app.workbench.quickopen.closeQuickOpen();
});
it(`verifies that 'Problems View' appears when clicking on 'Problems' status element`, async function () {
const app = this.app as SpectronApplication;
await app.workbench.statusbar.clickOn(StatusBarElement.PROBLEMS_STATUS);
await app.workbench.problems.waitForProblemsView();
});
it(`verifies that 'Tweet us feedback' pop-up appears when clicking on 'Feedback' icon`, async function () {
const app = this.app as SpectronApplication;
if (app.quality === Quality.Dev) {
return this.skip();
}
await app.workbench.statusbar.clickOn(StatusBarElement.FEEDBACK_ICON);
assert.ok(!!await app.client.waitForElement('.feedback-form'));
});
it(`checks if 'Go to Line' works if called from the status bar`, async function () {
const app = this.app as SpectronApplication;
await app.workbench.quickopen.openFile('app.js');
await app.workbench.statusbar.clickOn(StatusBarElement.SELECTION_STATUS);
await app.workbench.quickopen.waitForQuickOpenOpened();
await app.workbench.quickopen.submit(':15');
await app.workbench.editor.waitForHighlightingLine(15);
});
it(`verifies if changing EOL is reflected in the status bar`, async function () {
const app = this.app as SpectronApplication;
await app.workbench.quickopen.openFile('app.js');
await app.workbench.statusbar.clickOn(StatusBarElement.EOL_STATUS);
await app.workbench.quickopen.waitForQuickOpenOpened();
await app.workbench.quickopen.selectQuickOpenElement(1);
await app.workbench.statusbar.waitForEOL('CRLF');
});
});
}

View File

@@ -5,36 +5,38 @@
import { SpectronApplication } from '../../spectron/application';
describe('Dataloss', () => {
before(function () {
this.app.suiteName = 'Dataloss';
export function setup() {
describe('Dataloss', () => {
before(function () {
this.app.suiteName = 'Dataloss';
});
it(`verifies that 'hot exit' works for dirty files`, async function () {
const app = this.app as SpectronApplication;
await app.workbench.newUntitledFile();
const untitled = 'Untitled-1';
const textToTypeInUntitled = 'Hello, Unitled Code';
await app.workbench.editor.waitForTypeInEditor(untitled, textToTypeInUntitled);
await app.screenCapturer.capture('Untitled file before reload');
const readmeMd = 'readme.md';
const textToType = 'Hello, Code';
await app.workbench.explorer.openFile(readmeMd);
await app.workbench.editor.waitForTypeInEditor(readmeMd, textToType);
await app.screenCapturer.capture(`${readmeMd} before reload`);
await app.reload();
await app.screenCapturer.capture('After reload');
await app.workbench.waitForActiveTab(readmeMd, true);
await app.screenCapturer.capture(`${readmeMd} after reload`);
await app.workbench.editor.waitForEditorContents(readmeMd, c => c.indexOf(textToType) > -1);
await app.workbench.waitForTab(untitled, true);
await app.workbench.selectTab(untitled, true);
await app.screenCapturer.capture('Untitled file after reload');
await app.workbench.editor.waitForEditorContents(untitled, c => c.indexOf(textToTypeInUntitled) > -1);
});
});
it(`verifies that 'hot exit' works for dirty files`, async function () {
const app = this.app as SpectronApplication;
await app.workbench.newUntitledFile();
const untitled = 'Untitled-1';
const textToTypeInUntitled = 'Hello, Unitled Code';
await app.workbench.editor.waitForTypeInEditor(untitled, textToTypeInUntitled);
await app.screenCapturer.capture('Untitled file before reload');
const readmeMd = 'readme.md';
const textToType = 'Hello, Code';
await app.workbench.explorer.openFile(readmeMd);
await app.workbench.editor.waitForTypeInEditor(readmeMd, textToType);
await app.screenCapturer.capture(`${readmeMd} before reload`);
await app.reload();
await app.screenCapturer.capture('After reload');
await app.workbench.waitForActiveTab(readmeMd, true);
await app.screenCapturer.capture(`${readmeMd} after reload`);
await app.workbench.editor.waitForEditorContents(readmeMd, c => c.indexOf(textToType) > -1);
await app.workbench.waitForTab(untitled, true);
await app.workbench.selectTab(untitled, true);
await app.screenCapturer.capture('Untitled file after reload');
await app.workbench.editor.waitForEditorContents(untitled, c => c.indexOf(textToTypeInUntitled) > -1);
});
});
}

View File

@@ -3,85 +3,130 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
// import * as assert from 'assert';
import * as assert from 'assert';
// import { SpectronApplication, STABLE_PATH, LATEST_PATH } from '../../spectron/application';
// import { Util } from '../../helpers/utilities';
import { SpectronApplication, Quality } from '../../spectron/application';
import * as rimraf from 'rimraf';
// describe('Data Migration', () => {
export interface ICreateAppFn {
(quality: Quality): SpectronApplication | null;
}
// if (!STABLE_PATH) {
// return;
// }
export function setup(userDataDir: string, createApp: ICreateAppFn) {
// let app: SpectronApplication;
// afterEach(() => app.stop());
describe('Data Migration', () => {
afterEach(async function () {
await new Promise((c, e) => rimraf(userDataDir, { maxBusyTries: 10 }, err => err ? e(err) : c()));
});
// it('checks if the Untitled file is restored migrating from stable to latest', async function () {
// const textToType = 'Very dirty file';
it('checks if the Untitled file is restored migrating from stable to latest', async function () {
const stableApp = createApp(Quality.Stable);
// // Setting up stable version
// let app = new SpectronApplication(STABLE_PATH);
// await app.start('Data Migration');
if (!stableApp) {
this.skip();
return;
}
// await app.workbench.newUntitledFile();
// await app.workbench.editor.waitForTypeInEditor('Untitled-1', textToType);
await stableApp.start();
stableApp.suiteName = 'Data Migration';
// await app.stop();
// await new Promise(c => setTimeout(c, 500)); // wait until all resources are released (e.g. locked local storage)
// // Checking latest version for the restored state
const textToType = 'Very dirty file';
// app = new SpectronApplication(LATEST_PATH);
// await app.start('Data Migration');
await stableApp.workbench.newUntitledFile();
await stableApp.workbench.editor.waitForTypeInEditor('Untitled-1', textToType);
// assert.ok(await app.workbench.waitForActiveTab('Untitled-1', true), `Untitled-1 tab is not present after migration.`);
await stableApp.stop();
await new Promise(c => setTimeout(c, 500)); // wait until all resources are released (e.g. locked local storage)
// await app.workbench.editor.waitForEditorContents('Untitled-1', c => c.indexOf(textToType) > -1);
// await app.screenCapturer.capture('Untitled file text');
// });
// Checking latest version for the restored state
const app = createApp(Quality.Insiders);
// it('checks if the newly created dirty file is restored migrating from stable to latest', async function () {
// const fileName = 'test_data/plainFile',
// firstTextPart = 'This is going to be an unsaved file', secondTextPart = '_that is dirty.';
if (!app) {
return assert(false);
}
// // Setting up stable version
// let app = new SpectronApplication(STABLE_PATH, fileName);
// await Util.removeFile(`${fileName}`);
// await app.start('Data Migration');
await app.start(false);
app.suiteName = 'Data Migration';
// await app.workbench.editor.waitForTypeInEditor('plainFile', firstTextPart);
// await app.workbench.saveOpenedFile();
// await app.workbench.editor.waitForTypeInEditor('plainFile', secondTextPart);
assert.ok(await app.workbench.waitForActiveTab('Untitled-1', true), `Untitled-1 tab is not present after migration.`);
// await app.stop();
// await new Promise(c => setTimeout(c, 1000)); // wait until all resources are released (e.g. locked local storage)
await app.workbench.editor.waitForEditorContents('Untitled-1', c => c.indexOf(textToType) > -1);
await app.screenCapturer.capture('Untitled file text');
// // Checking latest version for the restored state
// app = new SpectronApplication(LATEST_PATH);
// await app.start('Data Migration');
await app.stop();
});
// const filename = fileName.split('/')[1];
// assert.ok(await app.workbench.waitForActiveTab(filename), `Untitled-1 tab is not present after migration.`);
// await app.workbench.editor.waitForEditorContents(filename, c => c.indexOf(firstTextPart + secondTextPart) > -1);
it('checks if the newly created dirty file is restored migrating from stable to latest', async function () {
const stableApp = createApp(Quality.Stable);
// await Util.removeFile(`${fileName}`);
// });
if (!stableApp) {
this.skip();
return;
}
// it('cheks if opened tabs are restored migrating from stable to latest', async function () {
// const fileName1 = 'app.js', fileName2 = 'jsconfig.json', fileName3 = 'readme.md';
// let app = new SpectronApplication(STABLE_PATH);
// await app.start('Data Migration');
await stableApp.start();
stableApp.suiteName = 'Data Migration';
// await app.workbench.quickopen.openFile(fileName1);
// await app.workbench.quickopen.openFile(fileName2);
// await app.workbench.quickopen.openFile(fileName3);
// await app.stop();
const fileName = 'app.js';
const textPart = 'This is going to be an unsaved file';
// app = new SpectronApplication(LATEST_PATH);
// await app.start('Data Migration');
await stableApp.workbench.quickopen.openFile(fileName);
// assert.ok(await app.workbench.waitForTab(fileName1), `${fileName1} tab was not restored after migration.`);
// assert.ok(await app.workbench.waitForTab(fileName2), `${fileName2} tab was not restored after migration.`);
// assert.ok(await app.workbench.waitForTab(fileName3), `${fileName3} tab was not restored after migration.`);
// });
// });
await stableApp.workbench.editor.waitForTypeInEditor(fileName, textPart);
await stableApp.stop();
await new Promise(c => setTimeout(c, 500)); // wait until all resources are released (e.g. locked local storage)
// Checking latest version for the restored state
const app = createApp(Quality.Insiders);
if (!app) {
return assert(false);
}
await app.start(false);
app.suiteName = 'Data Migration';
assert.ok(await app.workbench.waitForActiveTab(fileName), `dirty file tab is not present after migration.`);
await app.workbench.editor.waitForEditorContents(fileName, c => c.indexOf(textPart) > -1);
await app.stop();
});
it('checks if opened tabs are restored migrating from stable to latest', async function () {
const stableApp = createApp(Quality.Stable);
if (!stableApp) {
this.skip();
return;
}
await stableApp.start();
stableApp.suiteName = 'Data Migration';
const fileName1 = 'app.js', fileName2 = 'jsconfig.json', fileName3 = 'readme.md';
await stableApp.workbench.quickopen.openFile(fileName1);
await stableApp.workbench.quickopen.runCommand('View: Keep Editor');
await stableApp.workbench.quickopen.openFile(fileName2);
await stableApp.workbench.quickopen.runCommand('View: Keep Editor');
await stableApp.workbench.quickopen.openFile(fileName3);
await stableApp.stop();
const app = createApp(Quality.Insiders);
if (!app) {
return assert(false);
}
await app.start(false);
app.suiteName = 'Data Migration';
assert.ok(await app.workbench.waitForTab(fileName1), `${fileName1} tab was not restored after migration.`);
assert.ok(await app.workbench.waitForTab(fileName2), `${fileName2} tab was not restored after migration.`);
assert.ok(await app.workbench.waitForTab(fileName3), `${fileName3} tab was not restored after migration.`);
await app.stop();
});
});
}

View File

@@ -7,48 +7,50 @@ import * as assert from 'assert';
import { SpectronApplication, Quality } from '../../spectron/application';
describe('Localization', () => {
before(async function () {
const app = this.app as SpectronApplication;
this.app.suiteName = 'Localization';
export function setup() {
describe('Localization', () => {
before(async function () {
const app = this.app as SpectronApplication;
this.app.suiteName = 'Localization';
if (app.quality === Quality.Dev) {
return;
}
if (app.quality === Quality.Dev) {
return;
}
await app.restart(['--locale=DE']);
await app.restart({ extraArgs: ['--locale=DE'] });
});
it(`starts with 'DE' locale and verifies title and viewlets text is in German`, async function () {
const app = this.app as SpectronApplication;
if (app.quality === Quality.Dev) {
this.skip();
return;
}
let text = await app.workbench.explorer.getOpenEditorsViewTitle();
await app.screenCapturer.capture('Open editors title');
assert(/geöffnete editoren/i.test(text));
await app.workbench.search.openSearchViewlet();
text = await app.workbench.search.getTitle();
await app.screenCapturer.capture('Search title');
assert(/suchen/i.test(text));
await app.workbench.scm.openSCMViewlet();
text = await app.workbench.scm.getTitle();
await app.screenCapturer.capture('Scm title');
assert(/quellcodeverwaltung/i.test(text));
await app.workbench.debug.openDebugViewlet();
text = await app.workbench.debug.getTitle();
await app.screenCapturer.capture('Debug title');
assert(/debuggen/i.test(text));
await app.workbench.extensions.openExtensionsViewlet();
text = await app.workbench.extensions.getTitle();
await app.screenCapturer.capture('Extensions title');
assert(/erweiterungen/i.test(text));
});
});
it(`starts with 'DE' locale and verifies title and viewlets text is in German`, async function () {
const app = this.app as SpectronApplication;
if (app.quality === Quality.Dev) {
this.skip();
return;
}
let text = await app.workbench.explorer.getOpenEditorsViewTitle();
await app.screenCapturer.capture('Open editors title');
assert(/geöffnete editoren/i.test(text));
await app.workbench.search.openSearchViewlet();
text = await app.workbench.search.getTitle();
await app.screenCapturer.capture('Search title');
assert(/suchen/i.test(text));
await app.workbench.scm.openSCMViewlet();
text = await app.workbench.scm.getTitle();
await app.screenCapturer.capture('Scm title');
assert(/quellcodeverwaltung/i.test(text));
await app.workbench.debug.openDebugViewlet();
text = await app.workbench.debug.getTitle();
await app.screenCapturer.capture('Debug title');
assert(/debuggen/i.test(text));
await app.workbench.extensions.openExtensionsViewlet();
text = await app.workbench.extensions.getTitle();
await app.screenCapturer.capture('Extensions title');
assert(/erweiterungen/i.test(text));
});
});
}

View File

@@ -51,14 +51,8 @@ export class Workbench {
}
public async saveOpenedFile(): Promise<any> {
try {
await this.spectron.client.waitForElement('.tabs-container div.tab.active.dirty');
} catch (e) {
// ignore if there is no dirty file
return Promise.resolve();
}
await this.spectron.runCommand('workbench.action.files.save');
return this.spectron.client.waitForElement('.tabs-container div.tab.active.dirty', element => !element);
await this.spectron.client.waitForElement('.tabs-container div.tab.active.dirty');
await this.spectron.workbench.quickopen.runCommand('File: Save');
}
public async selectTab(tabName: string, untitled: boolean = false): Promise<void> {