From 22a124a17bdb9d0479d7e231dafb54baaf581652 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Thu, 31 Aug 2017 15:59:23 +0200 Subject: [PATCH] Improve settings and keybindings smoke tests --- .../src/areas/activitybar/activityBar.ts | 33 ++++++++++++++ test/smoke/src/areas/common.ts | 1 - .../src/areas/preferences/keybindings.test.ts | 44 +++++++++++++++++++ .../src/areas/preferences/keybindings.ts | 40 +++++++++++++++++ .../src/areas/preferences/settings.test.ts | 44 +++++++++++++++++++ test/smoke/src/areas/preferences/settings.ts | 30 +++++++++++++ test/smoke/src/spectron/application.ts | 20 +++++++++ test/smoke/src/spectron/client.ts | 16 +++---- test/smoke/src/test.ts | 36 ++------------- 9 files changed, 223 insertions(+), 41 deletions(-) create mode 100644 test/smoke/src/areas/activitybar/activityBar.ts create mode 100644 test/smoke/src/areas/preferences/keybindings.test.ts create mode 100644 test/smoke/src/areas/preferences/keybindings.ts create mode 100644 test/smoke/src/areas/preferences/settings.test.ts create mode 100644 test/smoke/src/areas/preferences/settings.ts diff --git a/test/smoke/src/areas/activitybar/activityBar.ts b/test/smoke/src/areas/activitybar/activityBar.ts new file mode 100644 index 00000000000..76d416a6913 --- /dev/null +++ b/test/smoke/src/areas/activitybar/activityBar.ts @@ -0,0 +1,33 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { Element } from 'webdriverio'; +import { SpectronApplication } from '../../spectron/application'; + +export enum ActivityBarPosition { + LEFT = 0, + RIGHT = 1 +}; + +export class ActivityBar { + + constructor(private spectron: SpectronApplication) { + // noop + } + + public async getActivityBar(position: ActivityBarPosition): Promise { + let positionClass: string; + + if (position === ActivityBarPosition.LEFT) { + positionClass = 'left'; + } else if (position === ActivityBarPosition.RIGHT) { + positionClass = 'right'; + } else { + throw new Error('No such position for activity bar defined.'); + } + + return this.spectron.client.element(`.part.activitybar.${positionClass}`); + } +} \ No newline at end of file diff --git a/test/smoke/src/areas/common.ts b/test/smoke/src/areas/common.ts index a7776e1e2ef..bf100cc2518 100644 --- a/test/smoke/src/areas/common.ts +++ b/test/smoke/src/areas/common.ts @@ -31,7 +31,6 @@ export class CommonActions { await this.spectron.client.keys(['ArrowRight', 'NULL'], false); await this.spectron.client.keys(`"${setting}": "${value}"`); await this.saveOpenedFile(); - } public async openUserSettings(): Promise { diff --git a/test/smoke/src/areas/preferences/keybindings.test.ts b/test/smoke/src/areas/preferences/keybindings.test.ts new file mode 100644 index 00000000000..54cd5459ba5 --- /dev/null +++ b/test/smoke/src/areas/preferences/keybindings.test.ts @@ -0,0 +1,44 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as assert from 'assert'; + +import { SpectronApplication, LATEST_PATH, WORKSPACE_PATH } from '../../spectron/application'; +import { CommonActions } from '../../areas/common'; +import { ActivityBarPosition, ActivityBar } from '../../areas/activitybar/activityBar'; +import { KeybindingsEditor } from './keybindings'; + +let app: SpectronApplication; +let common: CommonActions; + +export function testKeybindings() { + + describe('Keybindings Customisation', () => { + + beforeEach(async function () { + app = new SpectronApplication(LATEST_PATH, this.currentTest.fullTitle(), (this.currentTest as any).currentRetry(), [WORKSPACE_PATH]); + common = new CommonActions(app); + return await app.start(); + }); + + afterEach(async function () { + await app.stop(); + }); + + it(`changes 'workbench.action.toggleSidebarPosition' command key binding and verifies it`, async function () { + const activitybar = new ActivityBar(app); + let activityBarElement = await activitybar.getActivityBar(ActivityBarPosition.LEFT); + assert.ok(activityBarElement, 'Activity bar should be positioned on the left.'); + + const keybindingsEditor = new KeybindingsEditor(app); + await keybindingsEditor.openKeybindings(); + await keybindingsEditor.updateKeybinding('workbench.action.toggleSidebarPosition', ['Control', 'u', 'NULL'], 'Control+U'); + + await app.client.keys(['Control', 'u', 'NULL']); + activityBarElement = await activitybar.getActivityBar(ActivityBarPosition.RIGHT); + assert.ok(activityBarElement, 'Activity bar was not moved to right after toggling its position.'); + }); + }); +} \ No newline at end of file diff --git a/test/smoke/src/areas/preferences/keybindings.ts b/test/smoke/src/areas/preferences/keybindings.ts new file mode 100644 index 00000000000..5f91222169c --- /dev/null +++ b/test/smoke/src/areas/preferences/keybindings.ts @@ -0,0 +1,40 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { SpectronApplication } from '../../spectron/application'; + +export class KeybindingsEditor { + + constructor(private spectron: SpectronApplication) { + // noop + } + + public async openKeybindings(): Promise { + await this.spectron.command('workbench.action.openGlobalKeybindings'); + return this.spectron.client.element('.settings-search-input .synthetic-focus'); + } + + public async search(text: string, select: boolean = false): Promise { + await this.spectron.type(text); + if (select) { + await this.spectron.client.click('div[aria-label="Keybindings"] .monaco-list-row.keybinding-item'); + return this.spectron.client.element('div[aria-label="Keybindings"] .monaco-list-row.keybinding-item.focused.selected'); + } + } + + public async openDefineKeybindingDialog(): Promise { + await this.spectron.client.click('div[aria-label="Keybindings"] .monaco-list-row.keybinding-item .action-item .icon.add'); + return this.spectron.client.element('.defineKeybindingWidget .monaco-inputbox.synthetic-focus'); + } + + public async updateKeybinding(command: string, keys: string[], ariaLabel: string): Promise { + await this.search(command, true); + await this.openDefineKeybindingDialog(); + await this.spectron.client.keys(keys); + await this.spectron.client.keys(['Enter', 'NULL']); + await this.spectron.client.element(`div[aria-label="Keybindings"] div[aria-label="Keybinding is ${ariaLabel}."]`); + } + +} \ No newline at end of file diff --git a/test/smoke/src/areas/preferences/settings.test.ts b/test/smoke/src/areas/preferences/settings.test.ts new file mode 100644 index 00000000000..aac5d35089f --- /dev/null +++ b/test/smoke/src/areas/preferences/settings.test.ts @@ -0,0 +1,44 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as assert from 'assert'; + +import { SpectronApplication, LATEST_PATH, WORKSPACE_PATH } from '../../spectron/application'; +import { CommonActions } from '../../areas/common'; +import { SettingsEditor } from './settings'; + +let app: SpectronApplication; +let common: CommonActions; + +export function testSettings() { + + describe('Settings Customisation', () => { + + beforeEach(async function () { + app = new SpectronApplication(LATEST_PATH, this.currentTest.fullTitle(), (this.currentTest as any).currentRetry(), [WORKSPACE_PATH]); + common = new CommonActions(app); + return await app.start(); + }); + afterEach(async function () { + await app.stop(); + }); + + it('turns off editor line numbers and verifies the live change', async function () { + await common.openFile('app.js', true); + let lineNumbers = await app.client.elements('.line-numbers'); + assert.ok(!!lineNumbers.value.length, 'Line numbers are not present in the editor before disabling them.'); + + const settingsEditor = new SettingsEditor(app); + await settingsEditor.openUserSettings(); + await settingsEditor.focusEditableSettings(); + await app.client.keys(`"editor.lineNumbers": "off"`); + await common.saveOpenedFile(); + + await common.selectTab('app.js'); + lineNumbers = await app.client.elements('.line-numbers', result => !result || result.length === 0); + assert.ok(!lineNumbers.value.length, 'Line numbers are still present in the editor after disabling them.'); + }); + }); +} \ No newline at end of file diff --git a/test/smoke/src/areas/preferences/settings.ts b/test/smoke/src/areas/preferences/settings.ts new file mode 100644 index 00000000000..46e53f26fe9 --- /dev/null +++ b/test/smoke/src/areas/preferences/settings.ts @@ -0,0 +1,30 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { SpectronApplication } from '../../spectron/application'; + +export enum ActivityBarPosition { + LEFT = 0, + RIGHT = 1 +}; + +export class SettingsEditor { + + constructor(private spectron: SpectronApplication) { + // noop + } + + public async openUserSettings(): Promise { + await this.spectron.command('workbench.action.openGlobalSettings'); + return this.spectron.client.element('.settings-search-input .synthetic-focus'); + } + + public async focusEditableSettings(): Promise { + await this.spectron.client.keys(['ArrowDown', 'NULL'], false); + await this.spectron.client.element(`.editable-preferences-editor-container .monaco-editor.focused`); + await this.spectron.client.keys(['ArrowRight', 'NULL'], false); + } + +} \ No newline at end of file diff --git a/test/smoke/src/spectron/application.ts b/test/smoke/src/spectron/application.ts index 22743ddd424..a55de5cf943 100644 --- a/test/smoke/src/spectron/application.ts +++ b/test/smoke/src/spectron/application.ts @@ -52,6 +52,7 @@ export class SpectronApplication { this.spectron = new Application({ path: electronPath, + // args: ['/Users/sandy081/work/vscode', ...args], args: args, chromeDriverArgs: chromeDriverArgs, startTimeout: 10000, @@ -168,4 +169,23 @@ export class SpectronApplication { return key.length === 1 ? key : key.charAt(0).toUpperCase() + key.slice(1); }; } + + public type(text: string): Promise { + return new Promise((res) => { + let textSplit = text.split(' '); + + const type = async (i: number) => { + if (!textSplit[i] || textSplit[i].length <= 0) { + return res(); + } + + const toType = textSplit[i + 1] ? `${textSplit[i]} ` : textSplit[i]; + await this.client.keys(toType, false); + await this.client.keys(['NULL']); + await type(i + 1); + }; + + return type(0); + }); + } } diff --git a/test/smoke/src/spectron/client.ts b/test/smoke/src/spectron/client.ts index b348631b851..60f08cbedb3 100644 --- a/test/smoke/src/spectron/client.ts +++ b/test/smoke/src/spectron/client.ts @@ -35,17 +35,17 @@ export class SpectronClient { public async getHTML(selector: string, capture: boolean = true, accept: (result: string) => boolean = (result: string) => !!result): Promise { await this.screenshot(); - return this.wait(this.spectron.client.getHTML, selector, accept); + return this.wait(this.spectron.client.getHTML, selector, accept, `getHTML with selector ${selector}`); } public async click(selector: string): Promise { await this.screenshot(); - return this.wait(this.spectron.client.click, selector); + return this.wait(this.spectron.client.click, selector, void 0, `click with selector ${selector}`); } public async doubleClick(selector: string, capture: boolean = true): Promise { await this.screenshot(capture); - return this.wait(this.spectron.client.doubleClick, selector); + return this.wait(this.spectron.client.doubleClick, selector, void 0, `doubleClick with selector ${selector}`); } public async leftClick(selector: string, xoffset: number, yoffset: number, capture: boolean = true): Promise { @@ -70,17 +70,17 @@ export class SpectronClient { public async elements(selector: string, accept: (result: Element[]) => boolean = result => result.length > 0): Promise { await this.screenshot(true); - return this.wait>(this.spectron.client.elements, selector, result => accept(result.value)); + return this.wait>(this.spectron.client.elements, selector, result => accept(result.value), `elements with selector ${selector}`); } public async element(selector: string, accept: (result: Element | undefined) => boolean = result => !!result): Promise { await this.screenshot(); - return this.wait>(this.spectron.client.element, selector, result => accept(result ? result.value : void 0)); + return this.wait>(this.spectron.client.element, selector, result => accept(result ? result.value : void 0), `element with selector ${selector}`); } public async elementActive(selector: string, accept: (result: Element | undefined) => boolean = result => !!result): Promise { await this.screenshot(); - return this.wait>(this.spectron.client.elementActive, selector, result => accept(result ? result.value : void 0)); + return this.wait>(this.spectron.client.elementActive, selector, result => accept(result ? result.value : void 0), `elementActive with selector ${selector}`); } public async dragAndDrop(sourceElem: string, destinationElem: string, capture: boolean = true): Promise { @@ -124,12 +124,12 @@ export class SpectronClient { return this.spectron.client.getTitle(); } - private async wait(func: (...args: any[]) => any, args: any, accept: (result: T) => boolean = result => !!result): Promise { + private async wait(func: (...args: any[]) => any, args: any, accept: (result: T) => boolean = result => !!result, functionDetails: string): Promise { let trial = 1; while (true) { if (trial > this.trials) { - throw new Error(`Timed out after ${this.trials * this.trialWait} seconds.`); + return new Promise((res, rej) => rej(`${functionDetails}: Timed out after ${this.trials * this.trialWait} seconds.`)); } let result; diff --git a/test/smoke/src/test.ts b/test/smoke/src/test.ts index c4b167f04c6..2138b7b67c5 100644 --- a/test/smoke/src/test.ts +++ b/test/smoke/src/test.ts @@ -3,38 +3,10 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { testDataMigration } from './tests/data-migration'; -import { testDataLoss } from './tests/data-loss'; -import { testExplorer } from './tests/explorer'; -import { testConfigViews } from './tests/configuration-views'; -import { testSearch } from './tests/search'; -import { testCSS } from './tests/css'; -import { testJavaScript } from './tests/javascript'; -import { testJavaScriptDebug } from './tests/javascript-debug'; -import { testGit } from './tests/git'; -import { testIntegratedTerminal } from './tests/integrated-terminal'; -import { testStatusbar } from './tests/statusbar'; -import { testTasks } from './tests/tasks'; -import { testExtensions } from './tests/extensions'; -import { testLocalization } from './tests/localization'; -import { testMultiRoot } from './tests/multiroot'; +import { testSettings } from './areas/preferences/settings.test'; +import { testKeybindings } from './areas/preferences/keybindings.test'; describe('Smoke:', () => { - testDataMigration(); - testDataLoss(); - testExplorer(); - testConfigViews(); - testSearch(); - testCSS(); - testJavaScript(); - testJavaScriptDebug(); - testGit(); - testIntegratedTerminal(); - testStatusbar(); - testTasks(); - testExtensions(); - testLocalization(); - if (process.env.VSCODE_EDITION === 'insiders') { - testMultiRoot(); // only enabled in insiders - } + testSettings(); + testKeybindings(); }); \ No newline at end of file -- GitLab