Smoke tests (#9814)

* move

* add inital test; need basic sqllite connection

* before sqlite

* sqlite

* add smoke tests

* working tests

* fix app names

* fix quick open

* fix smoke tests

* add win32 smoke tests

* fix smoke test

* fix win32 smoke

* no continue

* continue on error

* add vscode smokes

* remove vscode tests

* continue on error

* allow sqlite to use relative paths

* add linux smoke tests

* fix build files

* use dispatch instead of select

* fix linux build again

* fix darwin

* get select working

* try and use screen shots

* screen shots

* remove smoke tests linux

* try vscodes sqlite

* fix compile

* fix webpack

* fix deps

* try this again

* try force a rebuild

* try npm rebuild

* add sqlite to be rebuilt

* distro

* try vscode sqlite again

* revert changes to driver and simplify edits

* fix compile

* fix imports

* move sqlite out

* remove unneeded change

* add extensions path

* fix web tests

* no continue on error
This commit is contained in:
Anthony Dresser
2020-04-03 00:01:32 -07:00
committed by GitHub
parent 589de854d5
commit 6e6649d006
33 changed files with 234 additions and 244 deletions

View File

@@ -113,6 +113,21 @@ steps:
displayName: Run unit tests
condition: and(succeeded(), eq(variables['RUN_TESTS'], 'true'))
- script: |
set -e
APP_ROOT=$(agent.builddirectory)/azuredatastudio-darwin
APP_NAME="`ls $APP_ROOT | head -n 1`"
yarn smoketest --build "$APP_ROOT/$APP_NAME" --screenshots "$(build.artifactstagingdirectory)/smokeshots"
displayName: Run smoke tests (Electron)
condition: and(succeeded(), eq(variables['VSCODE_STEP_ON_IT'], 'false'))
- script: |
set -e
VSCODE_REMOTE_SERVER_PATH="$(agent.builddirectory)/azuredatastudio-reh-web-darwin" \
yarn smoketest --web --headless --screenshots "$(build.artifactstagingdirectory)/smokeshots"
displayName: Run smoke tests (Browser)
condition: and(succeeded(), eq(variables['VSCODE_STEP_ON_IT'], 'false'))
- script: |
set -e
pushd ../azuredatastudio-darwin

View File

@@ -9,7 +9,8 @@
"azdata": "*"
},
"activationEvents": [
"*"
"onFileSystem:memfs",
"onDebug"
],
"main": "./out/main",
"extensionDependencies": [
@@ -17,7 +18,8 @@
"Microsoft.import",
"Microsoft.profiler",
"Microsoft.mssql",
"Microsoft.notebook"
"Microsoft.notebook",
"Microsoft.azuredatastudio-postgresql"
],
"contributes": {
"configuration": {

View File

@@ -4,122 +4,11 @@
*--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode';
import * as azdata from 'azdata';
import { normalize, join } from 'path';
import * as fs from 'fs';
const TEST_SETUP_COMPLETED_TEXT: string = 'Test Setup Completed';
const EXTENSION_LOADED_TEXT: string = 'Test Extension Loaded';
const ALL_EXTENSION_LOADED_TEXT: string = 'All Extensions Loaded';
let statusBarItemTimer: NodeJS.Timer;
export function activate(context: vscode.ExtensionContext) {
let statusBarItem = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left);
vscode.commands.registerCommand('test.setupIntegrationTest', async () => {
let extensionInstallersFolder = normalize(join(__dirname, '../extensionInstallers'));
console.info(`extensionInstallersFolder=${extensionInstallersFolder}`);
// eslint-disable-next-line no-sync
let installers = fs.readdirSync(extensionInstallersFolder);
for (let i = 0; i < installers.length; i++) {
if (installers[i].endsWith('.vsix')) {
let installerFullPath = join(extensionInstallersFolder, installers[i]);
console.info(`installing extension at ${installerFullPath}`);
await azdata.extensions.install(installerFullPath);
console.info(`extension has been installed successfully. vsix: ${installers[i]}`);
}
}
await setConfiguration('workbench.enablePreviewFeatures', true);
await setConfiguration('workbench.showConnectDialogOnStartup', false);
await setConfiguration('test.testSetupCompleted', true);
showStatusBarItem(statusBarItem, TEST_SETUP_COMPLETED_TEXT);
});
vscode.commands.registerCommand('test.waitForExtensionsToLoad', async () => {
const expectedExtensions = ['Microsoft.agent', 'Microsoft.import', 'Microsoft.mssql', 'Microsoft.profiler', 'Microsoft.azuredatastudio-postgresql'];
const commonFeatures: azdata.DataProviderType[] = [
azdata.DataProviderType.AdminServicesProvider,
azdata.DataProviderType.BackupProvider,
azdata.DataProviderType.CapabilitiesProvider,
azdata.DataProviderType.ConnectionProvider,
azdata.DataProviderType.FileBrowserProvider,
azdata.DataProviderType.MetadataProvider,
azdata.DataProviderType.ObjectExplorerProvider,
azdata.DataProviderType.ProfilerProvider,
azdata.DataProviderType.QueryProvider,
azdata.DataProviderType.RestoreProvider,
azdata.DataProviderType.ScriptingProvider,
azdata.DataProviderType.TaskServicesProvider];
const features_mssql: azdata.DataProviderType[] = [
azdata.DataProviderType.AgentServicesProvider,
azdata.DataProviderType.IconProvider
];
features_mssql.push(...commonFeatures);
const providerFeatureMapping: { providerId: string, features: azdata.DataProviderType[] }[] = [
{
providerId: 'MSSQL',
features: features_mssql
}, {
providerId: 'PGSQL',
features: commonFeatures
}];
do {
let extensions = vscode.extensions.all.filter(ext => { return expectedExtensions.indexOf(ext.id) !== -1; });
const extensionsNotInReadyState: string[] = [];
extensions.forEach(extension => {
if (!extension.isActive) {
extensionsNotInReadyState.push(extension.id);
}
});
const providerTypesNotInReadyState: string[] = [];
if (extensionsNotInReadyState.length === 0) {
providerFeatureMapping.forEach(entry => {
entry.features.forEach(feature => {
const provider = azdata.dataprotocol.getProvider(entry.providerId, feature);
if (!provider) {
providerTypesNotInReadyState.push(`${entry.providerId}:${feature}`);
}
});
});
}
if (extensionsNotInReadyState.length === 0 && providerTypesNotInReadyState.length === 0) {
console.info('All extensions are ready');
showStatusBarItem(statusBarItem, ALL_EXTENSION_LOADED_TEXT);
break;
} else if (extensionsNotInReadyState.length !== 0) {
console.warn(`the following extensions are not ready: ${extensionsNotInReadyState.join(',')}`);
} else {
console.warn(`the following providers are not ready: ${providerTypesNotInReadyState.join(',')}`);
}
await new Promise(resolve => { setTimeout(resolve, 2000); });
}
while (true);
});
showStatusBarItem(statusBarItem, EXTENSION_LOADED_TEXT);
}
function showStatusBarItem(statusBarItem: vscode.StatusBarItem, text: string) {
statusBarItem.text = text;
statusBarItem.tooltip = text;
statusBarItem.show();
clearTimeout(statusBarItemTimer);
statusBarItemTimer = setTimeout(function () {
statusBarItem.hide();
}, 5000);
}
// this method is called when your extension is deactivated
export function deactivate(): void {
}
async function setConfiguration(name: string, value: any) {
await vscode.workspace.getConfiguration().update(name, value, true);
}

View File

@@ -1,35 +0,0 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import 'mocha';
import * as vscode from 'vscode';
import { isTestSetupCompleted } from './testContext';
import * as assert from 'assert';
import { getConfigValue, EnvironmentVariable_BDC_SERVER, EnvironmentVariable_BDC_USERNAME, EnvironmentVariable_BDC_PASSWORD, EnvironmentVariable_AZURE_PASSWORD, EnvironmentVariable_AZURE_SERVER, EnvironmentVariable_AZURE_USERNAME, EnvironmentVariable_STANDALONE_PASSWORD, EnvironmentVariable_STANDALONE_SERVER, EnvironmentVariable_STANDALONE_USERNAME, EnvironmentVariable_PYTHON_PATH } from './testConfig';
assert(getConfigValue(EnvironmentVariable_BDC_SERVER) !== undefined &&
getConfigValue(EnvironmentVariable_BDC_USERNAME) !== undefined &&
getConfigValue(EnvironmentVariable_BDC_PASSWORD) !== undefined &&
getConfigValue(EnvironmentVariable_AZURE_PASSWORD) !== undefined &&
getConfigValue(EnvironmentVariable_AZURE_SERVER) !== undefined &&
getConfigValue(EnvironmentVariable_AZURE_USERNAME) !== undefined &&
getConfigValue(EnvironmentVariable_STANDALONE_PASSWORD) !== undefined &&
getConfigValue(EnvironmentVariable_STANDALONE_SERVER) !== undefined &&
getConfigValue(EnvironmentVariable_STANDALONE_USERNAME) !== undefined &&
getConfigValue(EnvironmentVariable_PYTHON_PATH) !== undefined, 'Required environment variables are not set, if you see this error in the build pipeline, make sure the environment variables are set properly in the build definition, otherwise for local dev environment make sure you follow the instructions in the readme file.');
if (!isTestSetupCompleted()) {
suite('integration test setup', () => {
test('test setup', async function () {
this.timeout(5 * 60 * 1000);
// Prepare the environment and make it ready for testing
await vscode.commands.executeCommand('test.setupIntegrationTest');
// Wait for the extensions to load
await vscode.commands.executeCommand('test.waitForExtensionsToLoad');
// Reload the window, this is required for some changes made by the 'test.setupIntegrationTest' to work
await vscode.commands.executeCommand('workbench.action.reloadWindow');
});
});
}

View File

@@ -6,12 +6,12 @@
import 'mocha';
import * as vscode from 'vscode';
import * as azdata from 'azdata';
import * as mssql from '../../mssql';
import * as utils from './utils';
import * as uuid from './uuid';
import { isTestSetupCompleted } from './testContext';
import * as mssql from '../../../mssql';
import * as utils from '../utils';
import * as uuid from '../uuid';
import { isTestSetupCompleted } from '../testContext';
import assert = require('assert');
import { getStandaloneServer, TestServerProfile } from './testConfig';
import { getStandaloneServer, TestServerProfile } from '../testConfig';
let cmsService: mssql.ICmsService;
let server: TestServerProfile;

View File

@@ -5,14 +5,14 @@
import 'mocha';
import * as azdata from 'azdata';
import * as utils from './utils';
import * as utils from '../utils';
import * as path from 'path';
import * as fs from 'fs';
import * as os from 'os';
import * as mssql from '../../mssql';
import * as mssql from '../../../mssql';
import * as vscode from 'vscode';
import { isTestSetupCompleted } from './testContext';
import { getStandaloneServer } from './testConfig';
import { isTestSetupCompleted } from '../testContext';
import { getStandaloneServer } from '../testConfig';
import * as assert from 'assert';
import { promisify } from 'util';

View File

@@ -7,10 +7,10 @@ import 'mocha';
import * as assert from 'assert';
import * as azdata from 'azdata';
import * as vscode from 'vscode';
import { isTestSetupCompleted } from './testContext';
import { sqlNotebookContent, writeNotebookToFile, sqlKernelMetadata, getFileName, pySparkNotebookContent, pySparkKernelMetadata, pythonKernelMetadata, sqlNotebookMultipleCellsContent, notebookContentForCellLanguageTest, sqlKernelSpec, pythonKernelSpec, pySparkKernelSpec, CellTypes } from './notebook.util';
import { getConfigValue, EnvironmentVariable_PYTHON_PATH, TestServerProfile, getStandaloneServer } from './testConfig';
import { connectToServer, sleep, testServerProfileToIConnectionProfile } from './utils';
import { isTestSetupCompleted } from '../testContext';
import { sqlNotebookContent, writeNotebookToFile, sqlKernelMetadata, getFileName, pySparkNotebookContent, pySparkKernelMetadata, pythonKernelMetadata, sqlNotebookMultipleCellsContent, notebookContentForCellLanguageTest, sqlKernelSpec, pythonKernelSpec, pySparkKernelSpec, CellTypes } from '../notebook.util';
import { getConfigValue, EnvironmentVariable_PYTHON_PATH, TestServerProfile, getStandaloneServer } from '../testConfig';
import { connectToServer, sleep, testServerProfileToIConnectionProfile } from '../utils';
import * as fs from 'fs';
import { stressify } from 'adstest';
import { isNullOrUndefined, promisify } from 'util';

View File

@@ -5,9 +5,9 @@
import 'mocha';
import * as azdata from 'azdata';
import { isTestSetupCompleted } from './testContext';
import { getBdcServer, TestServerProfile, getAzureServer, getStandaloneServer } from './testConfig';
import { connectToServer, createDB, deleteDB, DefaultConnectTimeoutInMs, asyncTimeout } from './utils';
import { isTestSetupCompleted } from '../testContext';
import { getBdcServer, TestServerProfile, getAzureServer, getStandaloneServer } from '../testConfig';
import { connectToServer, createDB, deleteDB, DefaultConnectTimeoutInMs, asyncTimeout } from '../utils';
import * as assert from 'assert';
import { stressify } from 'adstest';

View File

@@ -6,14 +6,14 @@
import 'mocha';
import * as azdata from 'azdata';
import * as vscode from 'vscode';
import * as utils from './utils';
import * as mssql from '../../mssql';
import * as utils from '../utils';
import * as mssql from '../../../mssql';
import * as os from 'os';
import * as fs from 'fs';
const path = require('path');
import { isTestSetupCompleted } from './testContext';
import { isTestSetupCompleted } from '../testContext';
import * as assert from 'assert';
import { getStandaloneServer } from './testConfig';
import { getStandaloneServer } from '../testConfig';
import { stressify } from 'adstest';
import { promisify } from 'util';

View File

@@ -0,0 +1,4 @@
{
"workbench.enablePreviewFeatures": true,
"workbench.showConnectDialogOnStartup": false
}

View File

@@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import * as azdata from 'azdata';
import * as mssql from '../../../mssql/src/mssql';
import * as mssql from '../../../mssql';
import { ApiWrapper } from '../common/apiWrapper';
/**

View File

@@ -8,7 +8,7 @@ import 'mocha';
import * as TypeMoq from 'typemoq';
import { createContext } from './utils';
import { LanguageController } from '../../../views/externalLanguages/languageController';
import * as mssql from '../../../../../mssql/src/mssql';
import * as mssql from '../../../../../mssql';
describe('External Languages Controller', () => {
it('Should open dialog for manage languages successfully ', async function (): Promise<void> {

View File

@@ -6,7 +6,7 @@
import * as should from 'should';
import 'mocha';
import { createContext } from './utils';
import * as mssql from '../../../../../mssql/src/mssql';
import * as mssql from '../../../../../mssql';
import { LanguageService } from '../../../externalLanguage/languageService';
describe('External Languages Dialog Model', () => {

View File

@@ -8,7 +8,7 @@ import * as vscode from 'vscode';
import * as TypeMoq from 'typemoq';
import { ApiWrapper } from '../../../common/apiWrapper';
import { LanguageViewBase } from '../../../views/externalLanguages/languageViewBase';
import * as mssql from '../../../../../mssql/src/mssql';
import * as mssql from '../../../../../mssql';
import { LanguageService } from '../../../externalLanguage/languageService';
import { createViewContext } from '../utils';

View File

@@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import * as azdata from 'azdata';
import * as mssql from '../../../../mssql/src/mssql';
import * as mssql from '../../../../mssql';
import { LanguageViewBase } from './languageViewBase';
import * as constants from '../../common/constants';
import { ApiWrapper } from '../../common/apiWrapper';

View File

@@ -3,7 +3,7 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as mssql from '../../../../mssql/src/mssql';
import * as mssql from '../../../../mssql';
import { ApiWrapper } from '../../common/apiWrapper';
import { LanguageService } from '../../externalLanguage/languageService';
import { LanguagesDialog } from './languagesDialog';

View File

@@ -7,7 +7,7 @@ import * as azdata from 'azdata';
import * as vscode from 'vscode';
import * as constants from '../../common/constants';
import { ApiWrapper } from '../../common/apiWrapper';
import * as mssql from '../../../../mssql/src/mssql';
import * as mssql from '../../../../mssql';
import * as path from 'path';
export interface LanguageUpdateModel {

View File

@@ -5,7 +5,7 @@
import * as azdata from 'azdata';
import * as constants from '../../common/constants';
import * as mssql from '../../../../mssql/src/mssql';
import * as mssql from '../../../../mssql';
import { LanguageViewBase } from './languageViewBase';
import { ApiWrapper } from '../../common/apiWrapper';

View File

@@ -47,7 +47,7 @@ if "%SKIP_PYTHON_INSTALL_TEST%" == "1" (
)
call %INTEGRATION_TEST_ELECTRON_PATH% --user-data-dir=%VSCODEUSERDATADIR% --extensions-dir=%VSCODEEXTENSIONSDIR% --remote-debugging-port=9222 ^
--extensionDevelopmentPath=%~dp0\..\extensions\integration-tests --extensionTestsPath=%~dp0\..\extensions\integration-tests\out --disable-telemetry --disable-crash-reporter --disable-updates -nogpu
--extensionDevelopmentPath=%~dp0\..\extensions\integration-tests --extensionTestsPath=%~dp0\..\extensions\integration-tests\out\tests --disable-telemetry --disable-crash-reporter --disable-updates -nogpu
rmdir /s /q %VSCODEUSERDATADIR%
rmdir /s /q %VSCODEEXTENSIONSDIR%

View File

@@ -60,7 +60,7 @@ fi
--extensionDevelopmentPath=$ROOT/extensions/profiler \
--extensionDevelopmentPath=$ROOT/extensions/resource-deployment \
--extensionDevelopmentPath=$ROOT/extensions/schema-compare \
--extensionTestsPath=$ROOT/extensions/integration-tests/out \
--extensionTestsPath=$ROOT/extensions/integration-tests/out/tests \
--user-data-dir=$VSCODEUSERDATADIR --extensions-dir=$VSCODEEXTDIR \
--disable-telemetry --disable-crash-reporter --disable-updates --skip-getting-started --disable-inspect

View File

@@ -50,6 +50,7 @@ import { find } from 'vs/base/common/arrays';
import { values } from 'vs/base/common/collections';
import { assign } from 'vs/base/common/objects';
import { IAdsTelemetryService } from 'sql/platform/telemetry/common/telemetry';
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
export class ConnectionManagementService extends Disposable implements IConnectionManagementService {
@@ -90,7 +91,8 @@ export class ConnectionManagementService extends Disposable implements IConnecti
@IAccountManagementService private _accountManagementService: IAccountManagementService,
@ILogService private _logService: ILogService,
@IStorageService private _storageService: IStorageService,
@IEnvironmentService private _environmentService: IEnvironmentService
@IEnvironmentService private _environmentService: IEnvironmentService,
@IExtensionService private readonly extensionService: IExtensionService
) {
super();
@@ -819,6 +821,8 @@ export class ConnectionManagementService extends Disposable implements IConnecti
options: connection.options
});
await this.extensionService.activateByEvent(`onConnect:${connection.providerName}`);
return this._providers.get(connection.providerName).onReady.then((provider) => {
provider.connect(uri, connectionInfo);
this._onConnectRequestSent.fire();

View File

@@ -35,6 +35,7 @@ import { NullLogService } from 'vs/platform/log/common/log';
import { assign } from 'vs/base/common/objects';
import { NullAdsTelemetryService } from 'sql/platform/telemetry/common/adsTelemetryService';
import { TestStorageService } from 'vs/workbench/test/common/workbenchTestServices';
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
suite('SQL ConnectionManagementService tests', () => {
@@ -164,7 +165,8 @@ suite('SQL ConnectionManagementService tests', () => {
accountManagementService.object,
new NullLogService(), // ILogService
undefined, // IStorageService
TestEnvironmentService
TestEnvironmentService,
getBasicExtensionService()
);
return connectionManagementService;
}
@@ -922,7 +924,7 @@ suite('SQL ConnectionManagementService tests', () => {
connectionStoreMock.setup(x => x.getConnectionProfileGroups(TypeMoq.It.isAny(), undefined)).returns(() => {
return [group1];
});
const connectionManagementService = new ConnectionManagementService(connectionStoreMock.object, connectionStatusManagerMock.object, undefined, undefined, undefined, undefined, undefined, new TestCapabilitiesService(), undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined);
const connectionManagementService = new ConnectionManagementService(connectionStoreMock.object, connectionStatusManagerMock.object, undefined, undefined, undefined, undefined, undefined, new TestCapabilitiesService(), undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, getBasicExtensionService());
// dupe connections have been seeded the numbers below already reflected the de-duped results
@@ -968,3 +970,9 @@ function createConnectionProfile(id: string): ConnectionProfile {
function createConnectionGroup(id: string): ConnectionProfileGroup {
return new ConnectionProfileGroup(id, undefined, id, undefined, undefined);
}
function getBasicExtensionService(): IExtensionService {
return <any>{
activateByEvent: () => Promise.resolve()
};
}

View File

@@ -53,10 +53,10 @@ export abstract class BaseWindowDriver implements IWindowDriver {
return Promise.reject(new Error(`Element not found: ${selector}`));
}
const inputElement = element as HTMLInputElement;
const inputElement = element as HTMLInputElement | HTMLSelectElement; // {{SQL CARBON EDIT}} handle select element
inputElement.value = text;
const event = new Event('input', { bubbles: true, cancelable: true });
const event = new Event(inputElement.tagName === 'INPUT' ? 'input' : 'change', { bubbles: true, cancelable: true }); // {{SQL CARBON EDIT}} handle select element
inputElement.dispatchEvent(event);
}

View File

@@ -121,7 +121,7 @@ export async function spawn(options: SpawnOptions): Promise<Code> {
let connectDriver: typeof connectElectronDriver;
if (options.web) {
await launch(options.userDataDir, options.workspacePath, options.codePath);
await launch(options.userDataDir, options.workspacePath, options.extensionsPath, options.codePath);
connectDriver = connectPlaywrightDriver.bind(connectPlaywrightDriver, options.browser);
return connect(connectDriver, child, '', handle, options.logger);
}

View File

@@ -92,7 +92,7 @@ let server: ChildProcess | undefined;
let endpoint: string | undefined;
let workspacePath: string | undefined;
export async function launch(userDataDir: string, _workspacePath: string, codeServerPath = process.env.VSCODE_REMOTE_SERVER_PATH): Promise<void> {
export async function launch(userDataDir: string, _workspacePath: string, extensionsDir: string, codeServerPath = process.env.VSCODE_REMOTE_SERVER_PATH): Promise<void> {
workspacePath = _workspacePath;
const agentFolder = userDataDir;
@@ -110,7 +110,7 @@ export async function launch(userDataDir: string, _workspacePath: string, codeSe
}
server = spawn(
serverLocation,
['--browser', 'none', '--driver', 'web'],
['--browser', 'none', '--driver', 'web', '--extensions-dir', `${extensionsDir}`],
{ env }
);
server.stderr?.on('data', error => console.log(`Server stderr: ${error}`));

View File

@@ -0,0 +1,31 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Code } from '../code';
export class QueryEditor {
public readonly commandBar: CommandBar;
constructor(code: Code) {
this.commandBar = new CommandBar(code);
}
}
export class CommandBar {
private static readonly COMMAND_BAR_BUTTON = '.query-editor .carbon-taskbar ul>:nth-child(${INDEX})';
constructor(private code: Code) { }
public async clickButton(index: number): Promise<void> {
await this.code.waitAndClick(CommandBar.COMMAND_BAR_BUTTON.replace('${INDEX}', '' + index));
}
public async waitForButton(index: number, label: string): Promise<void> {
await this.code.waitForTextContent(CommandBar.COMMAND_BAR_BUTTON.replace('${INDEX}', '' + index), label);
}
}

View File

@@ -24,6 +24,7 @@ import { Terminal } from './terminal';
import { ConnectionDialog } from './sql/connectionDialog';
import { Profiler } from './sql/profiler';
import { QueryEditors } from './sql/queryEditors';
import { QueryEditor } from './sql/queryEditor';
// {{END}}
export interface Commands {
@@ -52,6 +53,7 @@ export class Workbench {
readonly connectionDialog: ConnectionDialog;
readonly profiler: Profiler;
readonly queryEditors: QueryEditors;
readonly queryEditor: QueryEditor;
// {{END}}
constructor(code: Code, userDataPath: string) {
@@ -74,6 +76,7 @@ export class Workbench {
this.connectionDialog = new ConnectionDialog(code);
this.profiler = new Profiler(code, this.quickaccess);
this.queryEditors = new QueryEditors(code);
this.queryEditor = new QueryEditor(code);
// {{END}}
}
}

View File

@@ -21,13 +21,8 @@ import {
FileLogger,
} from '../../automation';
//{{SQL CARBON EDIT}}
import { setup as runProfilerTests } from './sql/profiler/profiler.test';
import { setup as runQueryEditorTests } from './sql/queryEditor/queryEditor.test';
//Original
/*
import { setup as setupDataMigrationTests } from './areas/workbench/data-migration.test';
import { main as sqlMain, setup as sqlSetup } from './sql/main'; //{{SQL CARBON EDIT}}
/*import { setup as setupDataMigrationTests } from './areas/workbench/data-migration.test';
import { setup as setupDataLossTests } from './areas/workbench/data-loss.test';
import { setup as setupDataPreferencesTests } from './areas/preferences/preferences.test';
import { setup as setupDataSearchTests } from './areas/search/search.test';
@@ -38,7 +33,7 @@ import { setup as setupDataExtensionTests } from './areas/extensions/extensions.
import { setup as setupTerminalTests } from './areas/terminal/terminal.test';
import { setup as setupDataMultirootTests } from './areas/multiroot/multiroot.test';
import { setup as setupDataLocalizationTests } from './areas/workbench/localization.test';
import { setup as setupLaunchTests } from './areas/workbench/launch.test';*///{{END}}
import { setup as setupLaunchTests } from './areas/workbench/launch.test';*/
if (!/^v10/.test(process.version) && !/^v12/.test(process.version)) {
console.error('Error: Smoketest must be run using Node 10/12. Currently running', process.version);
@@ -70,8 +65,8 @@ const opts = minimist(args, {
}
});
const testRepoUrl = 'https://github.com/Microsoft/vscode-smoketest-express';
const workspacePath = path.join(testDataPath, 'vscode-smoketest-express');
const testRepoUrl = 'https://github.com/anthonydresser/azuredatastudio-smoke-test-repo.git';
const workspacePath = path.join(testDataPath, 'azuredatastudio-smoke-test-repo');
const extensionsPath = path.join(testDataPath, 'extensions-dir');
mkdirp.sync(extensionsPath);
@@ -210,8 +205,8 @@ async function setupRepository(): Promise<void> {
cp.spawnSync('git', ['clean', '-xdf'], { cwd: workspacePath });
}
console.log('*** Running yarn...');
cp.execSync('yarn', { cwd: workspacePath, stdio: 'inherit' });
// console.log('*** Running yarn...');
// cp.execSync('yarn', { cwd: workspacePath, stdio: 'inherit' });
}
}
@@ -258,6 +253,7 @@ before(async function () {
this.timeout(2 * 60 * 1000); // allow two minutes for setup
await setup();
this.defaultOptions = createOptions();
await sqlSetup(this.defaultOptions);
});
after(async function () {
@@ -272,25 +268,11 @@ after(async function () {
await new Promise((c, e) => rimraf(testDataPath, { maxBusyTries: 10 }, err => err ? e(err) : c()));
});
describe(`VSCode Smoke Tests (${opts.web ? 'Web' : 'Electron'})`, () => {
describe(`Smoke Tests (${opts.web ? 'Web' : 'Electron'})`, () => {
before(async function () {
const app = new Application(this.defaultOptions);
await app!.start(opts.web ? false : undefined);
this.app = app;
//{{SQL CARBON EDIT}}
const testExtLoadedText = 'Test Extension Loaded';
const testSetupCompletedText = 'Test Setup Completed';
const allExtensionsLoadedText = 'All Extensions Loaded';
const setupTestCommand = 'Test: Setup Integration Test';
const waitForExtensionsCommand = 'Test: Wait For Extensions To Load';
await app.workbench.statusbar.waitForStatusbarText(testExtLoadedText, testExtLoadedText);
await app.workbench.quickaccess.runCommand(setupTestCommand);
await app.workbench.statusbar.waitForStatusbarText(testSetupCompletedText, testSetupCompletedText);
await app!.reload();
await app.workbench.statusbar.waitForStatusbarText(testExtLoadedText, testExtLoadedText);
await app.workbench.quickaccess.runCommand(waitForExtensionsCommand);
await app.workbench.statusbar.waitForStatusbarText(allExtensionsLoadedText, allExtensionsLoadedText);
//{{END}}
});
after(async function () {
@@ -318,6 +300,7 @@ describe(`VSCode Smoke Tests (${opts.web ? 'Web' : 'Electron'})`, () => {
});
}
sqlMain();
/*if (!opts.web) { setupDataMigrationTests(opts['stable-build'], testDataPath); }
if (!opts.web) { setupDataLossTests(); }
if (!opts.web) { setupDataPreferencesTests(); }
@@ -330,6 +313,4 @@ describe(`VSCode Smoke Tests (${opts.web ? 'Web' : 'Electron'})`, () => {
if (!opts.web) { setupDataMultirootTests(); }
if (!opts.web) { setupDataLocalizationTests(); }
if (!opts.web) { setupLaunchTests(); }*/
runProfilerTests(); // {{SQL CARBON EDIT}} add our tests
runQueryEditorTests(); // {{SQL CARBON EDIT}} add our tests
});

View File

@@ -3,7 +3,7 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Application, getStandaloneServer } from '../../../../automation';
import { Application, getStandaloneServer } from '../../../../../automation';
export function setup() {
describe('profiler test suite', () => {

View File

@@ -0,0 +1,22 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Application } from '../../../../../automation';
export function setup() {
describe('Query Editor', () => {
it('can open and connect file', async function () {
const app = this.app as Application;
await app.workbench.quickaccess.openFile('test.sql');
await app.workbench.queryEditor.commandBar.clickButton(3);
await app.workbench.connectionDialog.waitForConnectionDialog();
await app.code.waitForSetValue('.modal .modal-body select[aria-label="Connection type"]', 'Sqlite');
await app.code.waitForSetValue('.modal .modal-body input[aria-label="File"]', 'chinook.db');
await app.code.waitAndClick('.modal .modal-footer a[aria-label="Connect"]');
await app.workbench.queryEditor.commandBar.waitForButton(3, 'Disconnect');
});
});
}

View File

@@ -0,0 +1,94 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { setup as setupQueryEditorTest } from './areas/queryEditor/queryEditor.test';
import { ApplicationOptions } from '../../../automation';
import * as yazl from 'yauzl';
import * as fs from 'fs';
import * as path from 'path';
import { request } from 'https';
import * as mkdirp from 'mkdirp';
export function main(): void {
setupQueryEditorTest();
}
/* eslint-disable no-sync */
const PLATFORM = '${PLATFORM}';
const RUNTIME = '${RUNTIME}';
const VERSION = '${VERSION}';
const sqliteUrl = `https://github.com/anthonydresser/azuredatastudio-sqlite/releases/download/1.0.5/azuredatastudio-sqlite-${PLATFORM}-${RUNTIME}-${VERSION}.zip`;
export async function setup(app: ApplicationOptions): Promise<void> {
const requestUrl = sqliteUrl.replace(PLATFORM, process.platform).replace(RUNTIME, getRuntime(app.web || app.remote || false)).replace(VERSION, getVersion(app.web || app.remote || false));
const zip = await fetch(requestUrl);
return new Promise<void>((resolve, reject) => {
yazl.fromBuffer(zip, (e, zipFile) => {
if (e || !zipFile) {
reject(e);
return;
}
zipFile.on('entry', (entry: yazl.Entry) => {
if (/\/$/.test(entry.fileName)) {
return;
}
zipFile.openReadStream(entry, (err, readStream) => {
if (err || !readStream) {
reject(err);
return;
}
const destination = path.join(app.extensionsPath, 'azuredatastudio-sqlite', entry.fileName);
if (fs.existsSync(path.dirname(destination))) {
readStream.pipe(fs.createWriteStream(destination));
return;
}
mkdirp(path.dirname(destination), err => {
if (err) {
reject(err);
return;
}
readStream.pipe(fs.createWriteStream(destination));
});
});
}).once('end', () => resolve());
});
});
}
const root = path.dirname(path.dirname(path.dirname(path.dirname(__dirname))));
function getRuntime(remote: boolean) {
// eslint-disable-next-line no-sync
const yarnrc = fs.readFileSync(remote ? path.join(root, 'remote', '.yarnrc') : path.join(root, '.yarnrc'), 'utf8');
const runtime = /^runtime "(.*)"$/m.exec(yarnrc)![1];
return runtime;
}
function getVersion(remote: boolean) {
// eslint-disable-next-line no-sync
const yarnrc = fs.readFileSync(remote ? path.join(root, 'remote', '.yarnrc') : path.join(root, '.yarnrc'), 'utf8');
const target = /^target "(.*)"$/m.exec(yarnrc)![1];
return target;
}
function fetch(url: string): Promise<Buffer> {
return new Promise<Buffer>((resolve, reject) => {
const buffers: Buffer[] = [];
const req = request(url, res => {
if (res.headers.location) {
resolve(fetch(res.headers.location));
} else {
res.on('data', chunk => buffers.push(chunk));
res.on('end', () => resolve(Buffer.concat(buffers)));
res.on('error', e => reject(e));
}
});
req.end();
});
}

View File

@@ -1,28 +0,0 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Application } from '../../../../automation';
import { promises as fs } from 'fs';
import * as os from 'os';
import * as path from 'path';
export function setup() {
describe('Query Editor Test Suite', () => {
it('Can open and edit existing file', async function () {
const testFilePath = path.join(os.tmpdir(), 'QueryEditorSmokeTest.sql');
await fs.writeFile(testFilePath, '');
try {
const app = this.app as Application;
await app.workbench.quickaccess.openFile(testFilePath);
const fileBaseName = path.basename(testFilePath);
await app.workbench.editor.waitForTypeInEditor(fileBaseName, 'SELECT * FROM sys.tables');
}
finally {
await fs.unlink(testFilePath);
}
});
});
}