mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-01-13 17:22:15 -05:00
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:
@@ -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
|
||||
|
||||
@@ -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": {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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');
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -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;
|
||||
@@ -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';
|
||||
|
||||
@@ -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';
|
||||
@@ -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';
|
||||
|
||||
@@ -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';
|
||||
|
||||
4
extensions/integration-tests/test-workspace/.vscode/settings.json
vendored
Normal file
4
extensions/integration-tests/test-workspace/.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"workbench.enablePreviewFeatures": true,
|
||||
"workbench.showConnectDialogOnStartup": false
|
||||
}
|
||||
@@ -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';
|
||||
|
||||
/**
|
||||
|
||||
@@ -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> {
|
||||
|
||||
@@ -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', () => {
|
||||
|
||||
@@ -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';
|
||||
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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';
|
||||
|
||||
|
||||
@@ -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%
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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()
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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}`));
|
||||
|
||||
31
test/automation/src/sql/queryEditor.ts
Normal file
31
test/automation/src/sql/queryEditor.ts
Normal 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);
|
||||
}
|
||||
}
|
||||
@@ -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}}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
});
|
||||
|
||||
@@ -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', () => {
|
||||
22
test/smoke/src/sql/areas/queryEditor/queryEditor.test.ts
Normal file
22
test/smoke/src/sql/areas/queryEditor/queryEditor.test.ts
Normal 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');
|
||||
});
|
||||
});
|
||||
}
|
||||
94
test/smoke/src/sql/main.ts
Normal file
94
test/smoke/src/sql/main.ts
Normal 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();
|
||||
});
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user