mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-16 10:58:30 -05:00
Merge from master
This commit is contained in:
@@ -5,7 +5,7 @@
|
||||
|
||||
import { Code } from '../../vscode/code';
|
||||
|
||||
export enum ActivityBarPosition {
|
||||
export const enum ActivityBarPosition {
|
||||
LEFT = 0,
|
||||
RIGHT = 1
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ export function setup() {
|
||||
await app.workbench.quickopen.openFile('app.js');
|
||||
await app.workbench.debug.configure();
|
||||
|
||||
const launchJsonPath = path.join(app.workspacePath, '.vscode', 'launch.json');
|
||||
const launchJsonPath = path.join(app.workspacePathOrFolder, '.vscode', 'launch.json');
|
||||
const content = fs.readFileSync(launchJsonPath, 'utf8');
|
||||
const config = JSON.parse(stripJsonComments(content));
|
||||
config.configurations[0].protocol = 'inspector';
|
||||
|
||||
@@ -13,19 +13,19 @@ import { IElement } from '../../vscode/driver';
|
||||
const VIEWLET = 'div[id="workbench.view.debug"]';
|
||||
const DEBUG_VIEW = `${VIEWLET} .debug-view-content`;
|
||||
const CONFIGURE = `div[id="workbench.parts.sidebar"] .actions-container .configure`;
|
||||
const STOP = `.debug-actions-widget .debug-action.stop`;
|
||||
const STEP_OVER = `.debug-actions-widget .debug-action.step-over`;
|
||||
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 STOP = `.debug-toolbar .debug-action.stop`;
|
||||
const STEP_OVER = `.debug-toolbar .debug-action.step-over`;
|
||||
const STEP_IN = `.debug-toolbar .debug-action.step-into`;
|
||||
const STEP_OUT = `.debug-toolbar .debug-action.step-out`;
|
||||
const CONTINUE = `.debug-toolbar .debug-action.continue`;
|
||||
const GLYPH_AREA = '.margin-view-overlays>:nth-child';
|
||||
const BREAKPOINT_GLYPH = '.debug-breakpoint';
|
||||
const PAUSE = `.debug-actions-widget .debug-action.pause`;
|
||||
const PAUSE = `.debug-toolbar .debug-action.pause`;
|
||||
const DEBUG_STATUS_BAR = `.statusbar.debugging`;
|
||||
const NOT_DEBUG_STATUS_BAR = `.statusbar:not(debugging)`;
|
||||
const TOOLBAR_HIDDEN = `.debug-actions-widget.monaco-builder-hidden`;
|
||||
const TOOLBAR_HIDDEN = `.debug-toolbar[aria-hidden="true"]`;
|
||||
const STACK_FRAME = `${VIEWLET} .monaco-tree-row .stack-frame`;
|
||||
const SPECIFIC_STACK_FRAME = filename => `${STACK_FRAME} .file[title$="${filename}"]`;
|
||||
const SPECIFIC_STACK_FRAME = filename => `${STACK_FRAME} .file[title*="${filename}"]`;
|
||||
const VARIABLE = `${VIEWLET} .debug-variables .monaco-tree-row .expression`;
|
||||
const CONSOLE_OUTPUT = `.repl .output.expression .value`;
|
||||
const CONSOLE_INPUT_OUTPUT = `.repl .input-output-pair .output.expression .value`;
|
||||
@@ -125,7 +125,7 @@ export class Debug extends Viewlet {
|
||||
}
|
||||
|
||||
async waitForReplCommand(text: string, accept: (result: string) => boolean): Promise<void> {
|
||||
await this.commands.runCommand('Debug: Focus Debug Console');
|
||||
await this.commands.runCommand('Debug: Focus on Debug Console View');
|
||||
await this.code.waitForActiveElement(REPL_FOCUSED);
|
||||
await this.code.waitForSetValue(REPL_FOCUSED, text);
|
||||
|
||||
@@ -22,7 +22,7 @@ export class Editor {
|
||||
|
||||
async findReferences(filename: string, term: string, line: number): Promise<References> {
|
||||
await this.clickOnTerm(filename, term, line);
|
||||
await this.commands.runCommand('Find All References');
|
||||
await this.commands.runCommand('Peek References');
|
||||
const references = new References(this.code);
|
||||
await references.waitUntilOpen();
|
||||
return references;
|
||||
@@ -40,7 +40,7 @@ export class Editor {
|
||||
|
||||
async gotoDefinition(filename: string, term: string, line: number): Promise<void> {
|
||||
await this.clickOnTerm(filename, term, line);
|
||||
await this.commands.runCommand('Go to Definition');
|
||||
await this.commands.runCommand('Go to Implementation');
|
||||
}
|
||||
|
||||
async peekDefinition(filename: string, term: string, line: number): Promise<References> {
|
||||
|
||||
@@ -34,6 +34,6 @@ export class Extensions extends Viewlet {
|
||||
await this.searchForExtension(name);
|
||||
const ariaLabel = `${name}. Press enter for extension details.`;
|
||||
await this.code.waitAndClick(`div.extensions-viewlet[id="workbench.view.extensions"] .monaco-list-row[aria-label="${ariaLabel}"] .extension li[class='action-item'] .extension-action.install`);
|
||||
await this.code.waitForElement(`div.extensions-viewlet[id="workbench.view.extensions"] .monaco-list-row[aria-label="${ariaLabel}"] .extension li[class='action-item'] .extension-action.reload`);
|
||||
await this.code.waitForElement(`.extension-editor .monaco-action-bar .action-item:not(.disabled) .extension-action.uninstall`);
|
||||
}
|
||||
}
|
||||
@@ -14,8 +14,8 @@ export function setup() {
|
||||
before(async function () {
|
||||
const app = this.app as Application;
|
||||
|
||||
cp.execSync('git config user.name testuser', { cwd: app.workspacePath });
|
||||
cp.execSync('git config user.email monacotools@microsoft.com', { cwd: app.workspacePath });
|
||||
cp.execSync('git config user.name testuser', { cwd: app.workspacePathOrFolder });
|
||||
cp.execSync('git config user.email monacotools@microsoft.com', { cwd: app.workspacePathOrFolder });
|
||||
});
|
||||
|
||||
it('reflects working tree changes', async function () {
|
||||
@@ -71,7 +71,7 @@ export function setup() {
|
||||
await app.workbench.scm.commit('second commit');
|
||||
await app.code.waitForTextContent(SYNC_STATUSBAR, ' 0↓ 2↑');
|
||||
|
||||
cp.execSync('git reset --hard origin/master', { cwd: app.workspacePath });
|
||||
cp.execSync('git reset --hard origin/master', { cwd: app.workspacePathOrFolder });
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -3,17 +3,44 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
import { Application } from '../../application';
|
||||
|
||||
function toUri(path: string): string {
|
||||
if (process.platform === 'win32') {
|
||||
return `${path.replace(/\\/g, '/')}`;
|
||||
}
|
||||
|
||||
return `${path}`;
|
||||
}
|
||||
|
||||
async function createWorkspaceFile(workspacePath: string): Promise<string> {
|
||||
const workspaceFilePath = path.join(path.dirname(workspacePath), 'smoketest.code-workspace');
|
||||
const workspace = {
|
||||
folders: [
|
||||
{ path: toUri(path.join(workspacePath, 'public')) },
|
||||
{ path: toUri(path.join(workspacePath, 'routes')) },
|
||||
{ path: toUri(path.join(workspacePath, 'views')) }
|
||||
]
|
||||
};
|
||||
|
||||
fs.writeFileSync(workspaceFilePath, JSON.stringify(workspace, null, '\t'));
|
||||
|
||||
return workspaceFilePath;
|
||||
}
|
||||
|
||||
export function setup() {
|
||||
describe('Multiroot', () => {
|
||||
|
||||
before(async function () {
|
||||
const app = this.app as Application;
|
||||
|
||||
const workspaceFilePath = await createWorkspaceFile(app.workspacePathOrFolder);
|
||||
|
||||
// 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'] });
|
||||
await app.restart({ workspaceOrFolder: workspaceFilePath, extraArgs: ['--disable-restore-windows'] });
|
||||
});
|
||||
|
||||
it('shows results from all folders', async function () {
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
import { Code } from '../../vscode/code';
|
||||
|
||||
const SEARCH_INPUT = '.settings-search-input input';
|
||||
const SEARCH_INPUT = '.keybindings-header .settings-search-input input';
|
||||
|
||||
export class KeybindingsEditor {
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ import { Editors } from '../editor/editors';
|
||||
import { Code } from '../../vscode/code';
|
||||
import { QuickOpen } from '../quickopen/quickopen';
|
||||
|
||||
export enum ActivityBarPosition {
|
||||
export const enum ActivityBarPosition {
|
||||
LEFT = 0,
|
||||
RIGHT = 1
|
||||
}
|
||||
@@ -42,6 +42,6 @@ export class SettingsEditor {
|
||||
}
|
||||
|
||||
private async openSettings(): Promise<void> {
|
||||
await this.quickopen.runCommand('Preferences: Open User Settings');
|
||||
await this.quickopen.runCommand('Preferences: Open Settings (JSON)');
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
import { Code } from '../../vscode/code';
|
||||
|
||||
export enum ProblemSeverity {
|
||||
export const enum ProblemSeverity {
|
||||
WARNING = 0,
|
||||
ERROR = 1
|
||||
}
|
||||
@@ -40,7 +40,7 @@ export class Problems {
|
||||
|
||||
public static getSelectorInProblemsView(problemType: ProblemSeverity): string {
|
||||
let selector = problemType === ProblemSeverity.WARNING ? 'warning' : 'error';
|
||||
return `div[aria-label="Problems grouped by files"] .icon.${selector}`;
|
||||
return `div[id="workbench.panel.markers"] .monaco-tl-contents .icon.${selector}`;
|
||||
}
|
||||
|
||||
public static getSelectorInEditor(problemType: ProblemSeverity): string {
|
||||
|
||||
@@ -25,4 +25,13 @@ export class QuickInput {
|
||||
private async waitForQuickInputClosed(): Promise<void> {
|
||||
await this.code.waitForElement(QuickInput.QUICK_INPUT, r => !!r && r.attributes.style.indexOf('display: none;') !== -1);
|
||||
}
|
||||
|
||||
async selectQuickInputElement(index: number): Promise<void> {
|
||||
await this.waitForQuickInputOpened();
|
||||
for (let from = 0; from < index; from++) {
|
||||
await this.code.dispatchKeybinding('down');
|
||||
}
|
||||
await this.code.dispatchKeybinding('enter');
|
||||
await this.waitForQuickInputClosed();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,8 +8,8 @@ import { Code } from '../../vscode/code';
|
||||
|
||||
export class QuickOpen {
|
||||
|
||||
static QUICK_OPEN = 'div.monaco-quick-open-widget';
|
||||
static QUICK_OPEN_HIDDEN = 'div.monaco-quick-open-widget[aria-hidden="true"]';
|
||||
static QUICK_OPEN = 'div.monaco-quick-open-widget[aria-hidden="false"]';
|
||||
static QUICK_OPEN_INPUT = `${QuickOpen.QUICK_OPEN} .quick-open-input input`;
|
||||
static QUICK_OPEN_FOCUSED_ELEMENT = `${QuickOpen.QUICK_OPEN} .quick-open-tree .monaco-tree-row.focused .monaco-highlighted-label`;
|
||||
static QUICK_OPEN_ENTRY_SELECTOR = 'div[aria-label="Quick Picker"] .monaco-tree-rows.show-twisties .monaco-tree-row .quick-open-entry';
|
||||
|
||||
@@ -10,8 +10,8 @@ export function setup() {
|
||||
describe('Search', () => {
|
||||
after(function () {
|
||||
const app = this.app as Application;
|
||||
cp.execSync('git checkout .', { cwd: app.workspacePath });
|
||||
cp.execSync('git reset --hard origin/master', { cwd: app.workspacePath });
|
||||
cp.execSync('git checkout .', { cwd: app.workspacePathOrFolder });
|
||||
cp.execSync('git reset --hard origin/master', { cwd: app.workspacePathOrFolder });
|
||||
});
|
||||
|
||||
it('searches for body & checks for correct result number', async function () {
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
import { Viewlet } from '../workbench/viewlet';
|
||||
import { Code } from '../../vscode/code';
|
||||
|
||||
const VIEWLET = 'div[id="workbench.view.search"] .search-view';
|
||||
const INPUT = `${VIEWLET} .search-widget .search-container .monaco-inputbox input`;
|
||||
const VIEWLET = 'div[id="workbench.view.search"].search-view';
|
||||
const INPUT = `${VIEWLET} .search-widget .search-container .monaco-inputbox textarea`;
|
||||
const INCLUDE_INPUT = `${VIEWLET} .query-details .file-types.includes .monaco-inputbox input`;
|
||||
const FILE_MATCH = filename => `${VIEWLET} .results .filematch[data-resource$="${filename}"]`;
|
||||
|
||||
@@ -53,7 +53,7 @@ export class Search extends Viewlet {
|
||||
await this.waitForInputFocus(INPUT);
|
||||
|
||||
await this.code.dispatchKeybinding('enter');
|
||||
await this.code.waitForElement(`${VIEWLET} .messages[aria-hidden="false"]`);
|
||||
await this.code.waitForElement(`${VIEWLET} .messages`);
|
||||
}
|
||||
|
||||
async setFilesToIncludeText(text: string): Promise<void> {
|
||||
@@ -92,7 +92,7 @@ export class Search extends Viewlet {
|
||||
}
|
||||
|
||||
async setReplaceText(text: string): Promise<void> {
|
||||
await this.code.waitForSetValue(`${VIEWLET} .search-widget .replace-container .monaco-inputbox input[title="Replace"]`, text);
|
||||
await this.code.waitForSetValue(`${VIEWLET} .search-widget .replace-container .monaco-inputbox textarea[title="Replace"]`, text);
|
||||
}
|
||||
|
||||
async replaceFileMatch(filename: string): Promise<void> {
|
||||
@@ -109,11 +109,11 @@ export class Search extends Viewlet {
|
||||
}
|
||||
|
||||
async waitForResultText(text: string): Promise<void> {
|
||||
await this.code.waitForTextContent(`${VIEWLET} .messages[aria-hidden="false"] .message>p`, text);
|
||||
await this.code.waitForTextContent(`${VIEWLET} .messages .message>p`, text);
|
||||
}
|
||||
|
||||
async waitForNoResultText(): Promise<void> {
|
||||
await this.code.waitForElement(`${VIEWLET} .messages[aria-hidden="false"] .message>p`, el => !el);
|
||||
await this.code.waitForElement(`${VIEWLET} .messages[aria-hidden="true"] .message>p`);
|
||||
}
|
||||
|
||||
private async waitForInputFocus(selector: string): Promise<void> {
|
||||
|
||||
@@ -35,17 +35,17 @@ export function setup() {
|
||||
|
||||
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.quickinput.waitForQuickInputOpened();
|
||||
await app.workbench.quickinput.closeQuickInput();
|
||||
await app.workbench.statusbar.clickOn(StatusBarElement.ENCODING_STATUS);
|
||||
await app.workbench.quickopen.waitForQuickOpenOpened();
|
||||
await app.workbench.quickopen.closeQuickOpen();
|
||||
await app.workbench.quickinput.waitForQuickInputOpened();
|
||||
await app.workbench.quickinput.closeQuickInput();
|
||||
await app.workbench.statusbar.clickOn(StatusBarElement.EOL_STATUS);
|
||||
await app.workbench.quickopen.waitForQuickOpenOpened();
|
||||
await app.workbench.quickopen.closeQuickOpen();
|
||||
await app.workbench.quickinput.waitForQuickInputOpened();
|
||||
await app.workbench.quickinput.closeQuickInput();
|
||||
await app.workbench.statusbar.clickOn(StatusBarElement.LANGUAGE_STATUS);
|
||||
await app.workbench.quickopen.waitForQuickOpenOpened();
|
||||
await app.workbench.quickopen.closeQuickOpen();
|
||||
await app.workbench.quickinput.waitForQuickInputOpened();
|
||||
await app.workbench.quickinput.closeQuickInput();
|
||||
});
|
||||
|
||||
it(`verifies that 'Problems View' appears when clicking on 'Problems' status element`, async function () {
|
||||
@@ -84,8 +84,8 @@ export function setup() {
|
||||
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.quickinput.waitForQuickInputOpened();
|
||||
await app.workbench.quickinput.selectQuickInputElement(1);
|
||||
|
||||
await app.workbench.statusbar.waitForEOL('CRLF');
|
||||
});
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
import { Code } from '../../vscode/code';
|
||||
|
||||
export enum StatusBarElement {
|
||||
export const enum StatusBarElement {
|
||||
BRANCH_STATUS = 0,
|
||||
SYNC_STATUS = 1,
|
||||
PROBLEMS_STATUS = 2,
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Code } from '../../vscode/code';
|
||||
import { QuickOpen } from '../quickopen/quickopen';
|
||||
|
||||
const PANEL_SELECTOR = 'div[id="workbench.panel.terminal"]';
|
||||
const XTERM_SELECTOR = `${PANEL_SELECTOR} .terminal-wrapper`;
|
||||
@@ -11,10 +12,10 @@ const XTERM_TEXTAREA = `${XTERM_SELECTOR} textarea.xterm-helper-textarea`;
|
||||
|
||||
export class Terminal {
|
||||
|
||||
constructor(private code: Code) { }
|
||||
constructor(private code: Code, private quickopen: QuickOpen) { }
|
||||
|
||||
async showTerminal(): Promise<void> {
|
||||
await this.code.dispatchKeybinding('ctrl+`');
|
||||
await this.quickopen.runCommand('View: Toggle Integrated Terminal');
|
||||
await this.code.waitForActiveElement(XTERM_TEXTAREA);
|
||||
await this.code.waitForTerminalBuffer(XTERM_SELECTOR, lines => lines.some(line => line.length > 0));
|
||||
}
|
||||
|
||||
38
test/smoke/src/areas/workbench/launch.test.ts
Normal file
38
test/smoke/src/areas/workbench/launch.test.ts
Normal file
@@ -0,0 +1,38 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as path from 'path';
|
||||
import { Application, ApplicationOptions } from '../../application';
|
||||
|
||||
export function setup() {
|
||||
|
||||
describe('Launch', () => {
|
||||
|
||||
let app: Application;
|
||||
|
||||
after(async function () {
|
||||
if (app) {
|
||||
await app.stop();
|
||||
}
|
||||
});
|
||||
|
||||
afterEach(async function () {
|
||||
if (app) {
|
||||
if (this.currentTest.state === 'failed') {
|
||||
const name = this.currentTest.fullTitle().replace(/[^a-z0-9\-]/ig, '_');
|
||||
await app.captureScreenshot(name);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
it(`verifies that application launches when user data directory has non-ascii characters`, async function () {
|
||||
const defaultOptions = this.defaultOptions as ApplicationOptions;
|
||||
const options: ApplicationOptions = { ...defaultOptions, userDataDir: path.join(defaultOptions.userDataDir, 'abcdø') };
|
||||
app = new Application(options);
|
||||
await app.start();
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
@@ -3,8 +3,6 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import { Code } from '../../vscode/code';
|
||||
|
||||
export abstract class Viewlet {
|
||||
|
||||
@@ -11,7 +11,7 @@ import { Extensions } from '../extensions/extensions';
|
||||
import { Search } from '../search/search';
|
||||
import { Editor } from '../editor/editor';
|
||||
import { SCM } from '../git/scm';
|
||||
import { Debug } from '../debug/debug';
|
||||
import { Debug } from '../debug/debugSmoke';
|
||||
import { StatusBar } from '../statusbar/statusbar';
|
||||
import { Problems } from '../problems/problems';
|
||||
import { SettingsEditor } from '../preferences/settings';
|
||||
@@ -67,11 +67,10 @@ export class Workbench {
|
||||
this.problems = new Problems(code);
|
||||
this.settingsEditor = new SettingsEditor(code, userDataPath, this.editors, this.editor, this.quickopen);
|
||||
this.keybindingsEditor = new KeybindingsEditor(code);
|
||||
this.terminal = new Terminal(code);
|
||||
this.terminal = new Terminal(code, this.quickopen);
|
||||
// {{SQL CARBON EDIT}}
|
||||
this.connectionDialog = new ConnectionDialog(code);
|
||||
this.profiler = new Profiler(code, this.quickopen);
|
||||
// {{END}}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user