mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-16 10:58:30 -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:
@@ -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