smoketest: data migration tests 🎆

This commit is contained in:
Joao Moreno 2017-12-08 16:05:55 +01:00
parent 0f6a4175ca
commit 264c09c891
22 changed files with 891 additions and 802 deletions

View file

@ -44,6 +44,7 @@ export interface ParsedArgs {
'enable-proposed-api'?: string | string[];
'open-url'?: string | string[];
'skip-getting-started'?: boolean;
'skip-release-notes'?: boolean;
'sticky-quickopen'?: boolean;
'disable-telemetry'?: boolean;
'export-default-configuration'?: string;
@ -112,6 +113,7 @@ export interface IEnvironmentService {
logLevel: LogLevel;
skipGettingStarted: boolean | undefined;
skipReleaseNotes: boolean | undefined;
skipAddToRecentlyOpened: boolean;

View file

@ -48,6 +48,7 @@ const options: minimist.Opts = {
'show-versions',
'nolazy',
'skip-getting-started',
'skip-release-notes',
'sticky-quickopen',
'disable-telemetry',
'disable-updates',

View file

@ -106,6 +106,8 @@ export class EnvironmentService implements IEnvironmentService {
get skipGettingStarted(): boolean { return this._args['skip-getting-started']; }
get skipReleaseNotes(): boolean { return this._args['skip-release-notes']; }
get skipAddToRecentlyOpened(): boolean { return this._args['skip-add-to-recently-opened']; }
@memoize

View file

@ -202,12 +202,13 @@ export class ProductContribution implements IWorkbenchContribution {
@IStorageService storageService: IStorageService,
@IInstantiationService instantiationService: IInstantiationService,
@IMessageService messageService: IMessageService,
@IWorkbenchEditorService editorService: IWorkbenchEditorService
@IWorkbenchEditorService editorService: IWorkbenchEditorService,
@IEnvironmentService environmentService: IEnvironmentService
) {
const lastVersion = storageService.get(ProductContribution.KEY, StorageScope.GLOBAL, '');
// was there an update? if so, open release notes
if (product.releaseNotesUrl && lastVersion && pkg.version !== lastVersion) {
if (!environmentService.skipReleaseNotes && product.releaseNotesUrl && lastVersion && pkg.version !== lastVersion) {
instantiationService.invokeFunction(loadReleaseNotes, pkg.version).then(
text => editorService.openEditor(instantiationService.createInstance(ReleaseNotesInput, pkg.version, text), { pinned: true }),
() => {

View file

@ -10,7 +10,7 @@ npm run smoketest
npm run smoketest -- --build "path/to/code"
# Data Migration tests
npm run smoketest -- --build "path/to/code-insiders" --stable "path/to/code"
npm run smoketest -- --build "path/to/code-insiders" --stable-build "path/to/code"
```
The script calls mocha, so all mocha arguments should work fine. For example, use `-f Git` to only run the `Git` tests.

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

@ -11,187 +11,189 @@ import * as fs from 'fs';
import * as stripJsonComments from 'strip-json-comments';
import { SpectronApplication, Quality } from '../../spectron/application';
describe('Debug', () => {
let skip = false;
export function setup() {
describe('Debug', () => {
let skip = false;
before(async function () {
const app = this.app as SpectronApplication;
before(async function () {
const app = this.app as SpectronApplication;
if (app.quality === Quality.Dev) {
const extensionsPath = path.join(os.homedir(), '.vscode-oss-dev', 'extensions');
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 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);
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;
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;
}
if (!debug2Exists) {
console.warn(`Skipping debug tests because vscode-node-debug2 extension was not found in ${extensionsPath}`);
skip = true;
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;
}
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();
}
const app = this.app as SpectronApplication;
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);
await app.workbench.quickopen.openFile('index.js');
await app.workbench.debug.setBreakpointOnLine(6);
await app.screenCapturer.capture('breakpoints are set');
});
await app.screenCapturer.capture('debugging is paused');
});
let port: number;
it('start debugging', async function () {
if (skip) {
this.skip();
return;
}
it('focus stack frames and variables', async function () {
if (skip) {
this.skip();
return;
}
const app = this.app as SpectronApplication;
const app = this.app as SpectronApplication;
port = await app.workbench.debug.startDebugging();
await app.screenCapturer.capture('debugging has started');
await app.client.waitFor(() => app.workbench.debug.getLocalVariableCount(), c => c === 4, 'there should be 4 local variables');
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.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);
await app.screenCapturer.capture('debugging is paused');
});
await app.screenCapturer.capture('debugging is paused');
it('focus stack frames and variables', async function () {
if (skip) {
this.skip();
return;
}
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 () {
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);
});
await app.screenCapturer.capture('debugging is paused');
});
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');
});
});
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

@ -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

@ -10,77 +10,79 @@ 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(function () {
this.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();
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 });
});
});
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

@ -6,32 +6,34 @@
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]);
await app.restart([app.workspaceFilePath]);
// for some reason Code opens 2 windows at this point
// so let's select the last one
await app.client.windowByIndex(1);
// for some reason Code opens 2 windows at this point
// so let's select the last one
await app.webclient.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

@ -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

@ -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 MIT License. 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(['--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

@ -6,35 +6,6 @@
import * as fs from 'fs';
import { dirname } from 'path';
/**
* Contains methods that are commonly used across test areas.
*/
export class Util {
constructor() {
// noop
}
public removeFile(filePath: string): void {
try {
fs.unlinkSync(`${filePath}`);
} catch (e) {
if (e.code !== 'ENOENT') {
throw e;
}
}
}
public static removeFile(filePath: string): void {
try {
fs.unlinkSync(`${filePath}`);
} catch (e) {
if (e.code !== 'ENOENT') {
throw e;
}
}
}
}
export function nfcall<R>(fn: Function, ...args): Promise<R> {
return new Promise<R>((c, e) => fn(...args, (err, r) => err ? e(err) : c(r)));
}

View file

@ -12,6 +12,21 @@ import * as tmp from 'tmp';
import * as rimraf from 'rimraf';
import * as mkdirp from 'mkdirp';
import { SpectronApplication, Quality } from './spectron/application';
import { setup as setupDataMigrationTests } from './areas/workbench/data-migration.test';
import { setup as setupDataLossTests } from './areas/workbench/data-loss.test';
import { setup as setupDataExplorerTests } from './areas/explorer/explorer.test';
import { setup as setupDataPreferencesTests } from './areas/preferences/preferences.test';
import { setup as setupDataSearchTests } from './areas/search/search.test';
import { setup as setupDataCSSTests } from './areas/css/css.test';
import { setup as setupDataEditorTests } from './areas/editor/editor.test';
import { setup as setupDataDebugTests } from './areas/debug/debug.test';
import { setup as setupDataGitTests } from './areas/git/git.test';
import { setup as setupDataStatusbarTests } from './areas/statusbar/statusbar.test';
import { setup as setupDataExtensionTests } from './areas/extensions/extensions.test';
import { setup as setupDataMultirootTests } from './areas/multiroot/multiroot.test';
import { setup as setupDataLocalizationTests } from './areas/workbench/localization.test';
// import './areas/terminal/terminal.test';
const tmpDir = tmp.dirSync({ prefix: 't' }) as { name: string; removeCallback: Function; };
const testDataPath = tmpDir.name;
@ -83,12 +98,13 @@ function getBuildElectronPath(root: string): string {
let testCodePath = opts.build;
let stableCodePath = opts['stable-build'];
let electronPath: string;
let stablePath: string;
if (testCodePath) {
electronPath = getBuildElectronPath(testCodePath);
if (stableCodePath) {
process.env.VSCODE_STABLE_PATH = getBuildElectronPath(stableCodePath);
stablePath = getBuildElectronPath(stableCodePath);
}
} else {
testCodePath = getDevElectronPath();
@ -203,14 +219,16 @@ console.warn = function suppressWebdriverWarnings(message) {
warn.apply(console, arguments);
};
before(async function () {
// allow two minutes for setup
this.timeout(2 * 60 * 1000);
await setup();
function createApp(quality: Quality): SpectronApplication | null {
const path = quality === Quality.Insiders ? electronPath : stablePath;
const app = new SpectronApplication({
if (!path) {
return null;
}
return new SpectronApplication({
quality,
electronPath,
electronPath: path,
workspacePath,
userDataDir,
extensionsPath,
@ -218,27 +236,42 @@ before(async function () {
workspaceFilePath,
waitTime: parseInt(opts['wait-time'] || '0') || 20
});
await app.start();
this.app = app;
}
before(async function () {
// allow two minutes for setup
this.timeout(2 * 60 * 1000);
await setup();
});
after(async function () {
await this.app.stop();
await new Promise((c, e) => rimraf(testDataPath, { maxBusyTries: 10 }, err => err ? e(err) : c()));
});
// import './areas/workbench/data-migration.test';
import './areas/workbench/data-loss.test';
import './areas/explorer/explorer.test';
import './areas/preferences/preferences.test';
import './areas/search/search.test';
import './areas/css/css.test';
import './areas/editor/editor.test';
import './areas/debug/debug.test';
import './areas/git/git.test';
// import './areas/terminal/terminal.test';
import './areas/statusbar/statusbar.test';
import './areas/extensions/extensions.test';
import './areas/multiroot/multiroot.test';
import './areas/workbench/localization.test';
describe('Data Migration', () => {
setupDataMigrationTests(userDataDir, createApp);
});
describe('Everything Else', () => {
before(async function () {
const app = createApp(quality);
await app!.start();
this.app = app;
});
after(async function () {
await this.app.stop();
});
setupDataLossTests();
setupDataExplorerTests();
setupDataPreferencesTests();
setupDataSearchTests();
setupDataCSSTests();
setupDataEditorTests();
setupDataDebugTests();
setupDataGitTests();
setupDataStatusbarTests();
setupDataExtensionTests();
setupDataMultirootTests();
setupDataLocalizationTests();
});

View file

@ -108,9 +108,12 @@ export class SpectronApplication {
this._screenCapturer.suiteName = suiteName;
}
async start(): Promise<any> {
async start(waitForWelcome: boolean = true): Promise<any> {
await this._start();
await this.waitForWelcome();
if (waitForWelcome) {
await this.waitForWelcome();
}
}
async restart(codeArgs: string[] = []): Promise<any> {
@ -159,6 +162,9 @@ export class SpectronApplication {
// Prevent 'Getting Started' web page from opening on clean user-data-dir
args.push('--skip-getting-started');
// Prevent 'Getting Started' web page from opening on clean user-data-dir
args.push('--skip-release-notes');
// Prevent Quick Open from closing when focus is stolen, this allows concurrent smoketest suite running
args.push('--sticky-quickopen');
@ -269,10 +275,18 @@ export class SpectronApplication {
private async checkWindowReady(): Promise<any> {
await this.webclient.waitUntilWindowLoaded();
// Spectron opens multiple terminals in Windows platform
// Workaround to focus the right window - https://github.com/electron/spectron/issues/60
// await this.client.windowByIndex(1);
// await this.app.browserWindow.focus();
// Pick the first workbench window here
const count = await this.webclient.getWindowCount();
for (let i = 0; i < count; i++) {
await this.webclient.windowByIndex(i);
if (/bootstrap\/index\.html/.test(await this.webclient.getUrl())) {
break;
}
}
await this.client.waitForElement('.monaco-workbench');
}

View file

@ -25,10 +25,6 @@ export class SpectronClient {
this.retryCount = (waitTime * 1000) / this.retryDuration;
}
windowByIndex(index: number): Promise<any> {
return this.spectron.client.windowByIndex(index);
}
keys(keys: string[]): Promise<void> {
this.spectron.client.keys(keys);
return Promise.resolve();