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

@@ -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);
}
});
});
}