diff --git a/build/azure-pipelines/darwin/product-build-darwin.yml b/build/azure-pipelines/darwin/product-build-darwin.yml index b760d90aaf5..a34ae1c4247 100644 --- a/build/azure-pipelines/darwin/product-build-darwin.yml +++ b/build/azure-pipelines/darwin/product-build-darwin.yml @@ -244,6 +244,16 @@ steps: displayName: Run smoke tests (Electron) condition: and(succeeded(), eq(variables['VSCODE_ARCH'], 'x64'), eq(variables['VSCODE_STEP_ON_IT'], 'false')) + - script: | + set -e + APP_ROOT=$(agent.builddirectory)/VSCode-darwin-$(VSCODE_ARCH) + APP_NAME="`ls $APP_ROOT | head -n 1`" + VSCODE_REMOTE_SERVER_PATH="$(agent.builddirectory)/vscode-reh-darwin" \ + yarn smoketest-no-compile --build "$APP_ROOT/$APP_NAME" --remote + timeoutInMinutes: 5 + displayName: Run smoke tests (Remote) + condition: and(succeeded(), eq(variables['VSCODE_ARCH'], 'x64'), eq(variables['VSCODE_STEP_ON_IT'], 'false')) + - script: | set -e VSCODE_REMOTE_SERVER_PATH="$(agent.builddirectory)/vscode-reh-web-darwin" \ diff --git a/extensions/vscode-api-tests/src/singlefolder-tests/extensions.test.ts b/extensions/vscode-api-tests/src/singlefolder-tests/extensions.test.ts new file mode 100644 index 00000000000..889faa0bf1d --- /dev/null +++ b/extensions/vscode-api-tests/src/singlefolder-tests/extensions.test.ts @@ -0,0 +1,25 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import 'mocha'; +import * as assert from 'assert'; +import * as vscode from 'vscode'; + +suite('vscode server cli', () => { + + + test('extension is installed and enabled when installed by server cli', function () { + const extension = process.env.TESTRESOLVER_INSTALL_BUILTIN_EXTENSION; + if (!process.env.BUILD_SOURCEVERSION // Skip it when running out of sources + || !process.env.REMOTE_VSCODE // Skip it when not a remote integration test + || !extension // Skip it when extension is not provided to server + ) { + this.skip(); + } + + assert.ok(vscode.extensions.getExtension(extension!)); + }); + +}); diff --git a/extensions/vscode-test-resolver/src/extension.ts b/extensions/vscode-test-resolver/src/extension.ts index ccac6c52c48..d33fe9cdbbf 100644 --- a/extensions/vscode-test-resolver/src/extension.ts +++ b/extensions/vscode-test-resolver/src/extension.ts @@ -83,12 +83,6 @@ export function activate(context: vscode.ExtensionContext) { const env = getNewEnv(); const remoteDataDir = process.env['TESTRESOLVER_DATA_FOLDER'] || path.join(os.homedir(), serverDataFolderName || `${dataFolderName}-testresolver`); - const remoteExtension = process.env['TESTRESOLVER_REMOTE_EXTENSION']; - if (remoteExtension) { - commandArgs.push('--install-extension', remoteExtension); - commandArgs.push('--start-server'); - } - env['VSCODE_AGENT_FOLDER'] = remoteDataDir; outputChannel.appendLine(`Using data folder at ${remoteDataDir}`); @@ -98,6 +92,11 @@ export function activate(context: vscode.ExtensionContext) { const serverCommandPath = path.join(vscodePath, 'resources', 'server', 'bin-dev', serverCommand); extHostProcess = cp.spawn(serverCommandPath, commandArgs, { env, cwd: vscodePath }); } else { + const extensionToInstall = process.env['TESTRESOLVER_INSTALL_BUILTIN_EXTENSION']; + if (extensionToInstall) { + commandArgs.push('--install-builtin-extension', extensionToInstall); + commandArgs.push('--start-server'); + } const serverCommand = process.platform === 'win32' ? 'server.cmd' : 'server.sh'; let serverLocation = env['VSCODE_REMOTE_SERVER_PATH']; // support environment variable to specify location of server on disk if (!serverLocation) { diff --git a/package.json b/package.json index 0a82a4a914c..f61f2d5fc7c 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-oss-dev", "version": "1.54.0", - "distro": "a1836302c2aaab6ded8ad4a0871f74dbc42359f5", + "distro": "4897627e104317486bf831598791ff29cbb686a6", "author": { "name": "Microsoft Corporation" }, diff --git a/test/automation/src/application.ts b/test/automation/src/application.ts index 9f6480ab42a..0440d68d4e5 100644 --- a/test/automation/src/application.ts +++ b/test/automation/src/application.ts @@ -51,6 +51,10 @@ export class Application { return !!this.options.remote; } + get web(): boolean { + return !!this.options.web; + } + private _workspacePathOrFolder: string; get workspacePathOrFolder(): string { return this._workspacePathOrFolder; diff --git a/test/automation/src/code.ts b/test/automation/src/code.ts index a947b1c100e..0f04f08fa26 100644 --- a/test/automation/src/code.ts +++ b/test/automation/src/code.ts @@ -120,7 +120,7 @@ export async function spawn(options: SpawnOptions): Promise { let child: cp.ChildProcess | undefined; let connectDriver: typeof connectElectronDriver; - copyExtension(options, 'vscode-notebook-tests'); + copyExtension(options.extensionsPath, 'vscode-notebook-tests'); if (options.web) { await launch(options.userDataDir, options.workspacePath, options.codePath, options.extensionsPath); @@ -150,11 +150,19 @@ export async function spawn(options: SpawnOptions): Promise { if (codePath) { // running against a build: copy the test resolver extension - copyExtension(options, 'vscode-test-resolver'); + copyExtension(options.extensionsPath, 'vscode-test-resolver'); } args.push('--enable-proposed-api=vscode.vscode-test-resolver'); const remoteDataDir = `${options.userDataDir}-server`; mkdirp.sync(remoteDataDir); + + if (codePath) { + // running against a build: copy the test resolver extension into remote extensions dir + const remoteExtensionsDir = path.join(remoteDataDir, 'extensions'); + mkdirp.sync(remoteExtensionsDir); + copyExtension(remoteExtensionsDir, 'vscode-notebook-tests'); + } + env['TESTRESOLVER_DATA_FOLDER'] = remoteDataDir; } @@ -186,11 +194,11 @@ export async function spawn(options: SpawnOptions): Promise { return connect(connectDriver, child, outPath, handle, options.logger); } -async function copyExtension(options: SpawnOptions, extId: string): Promise { - const testResolverExtPath = path.join(options.extensionsPath, extId); - if (!fs.existsSync(testResolverExtPath)) { +async function copyExtension(extensionsPath: string, extId: string): Promise { + const dest = path.join(extensionsPath, extId); + if (!fs.existsSync(dest)) { const orig = path.join(repoPath, 'extensions', extId); - await new Promise((c, e) => ncp(orig, testResolverExtPath, err => err ? e(err) : c())); + await new Promise((c, e) => ncp(orig, dest, err => err ? e(err) : c())); } } diff --git a/test/automation/src/extensions.ts b/test/automation/src/extensions.ts index fa1fe2fc0ba..b2bedb8f5c8 100644 --- a/test/automation/src/extensions.ts +++ b/test/automation/src/extensions.ts @@ -32,6 +32,12 @@ export class Extensions extends Viewlet { await this.code.waitAndClick(SEARCH_BOX); await this.code.waitForActiveElement(SEARCH_BOX); await this.code.waitForTypeInEditor(SEARCH_BOX, `@id:${id}`); + await this.code.waitForElement(`div.extensions-viewlet[id="workbench.view.extensions"] .monaco-list-row[data-extension-id="${id}"]`); + } + + async openExtension(id: string): Promise { + await this.searchForExtension(id); + await this.code.waitAndClick(`div.extensions-viewlet[id="workbench.view.extensions"] .monaco-list-row[data-extension-id="${id}"]`); } async installExtension(id: string, waitUntilEnabled: boolean): Promise { diff --git a/test/automation/src/playwrightDriver.ts b/test/automation/src/playwrightDriver.ts index 7d7c34deb25..03840dcb547 100644 --- a/test/automation/src/playwrightDriver.ts +++ b/test/automation/src/playwrightDriver.ts @@ -101,6 +101,7 @@ export async function launch(userDataDir: string, _workspacePath: string, codeSe VSCODE_REMOTE_SERVER_PATH: codeServerPath, ...process.env }; + const args = ['--browser', 'none', '--driver', 'web', '--extensions-dir', extPath]; let serverLocation: string | undefined; if (codeServerPath) { serverLocation = join(codeServerPath, `server.${process.platform === 'win32' ? 'cmd' : 'sh'}`); @@ -111,7 +112,7 @@ export async function launch(userDataDir: string, _workspacePath: string, codeSe } server = spawn( serverLocation, - ['--browser', 'none', '--driver', 'web', '--extensions-dir', extPath], + args, { env } ); server.stderr?.on('data', error => console.log(`Server stderr: ${error}`)); diff --git a/test/smoke/src/areas/extensions/extensions.test.ts b/test/smoke/src/areas/extensions/extensions.test.ts index d5f6004bc3d..72a3460d8fe 100644 --- a/test/smoke/src/areas/extensions/extensions.test.ts +++ b/test/smoke/src/areas/extensions/extensions.test.ts @@ -15,7 +15,9 @@ export function setup() { return; } - await app.workbench.settingsEditor.addUserSetting('webview.experimental.useIframes', 'true'); + if (!app.web) { + await app.workbench.settingsEditor.addUserSetting('webview.experimental.useIframes', 'true'); + } await app.workbench.extensions.openExtensionsViewlet(); @@ -23,15 +25,16 @@ export function setup() { await app.workbench.extensions.waitForExtensionsViewlet(); - if (app.remote) { - await app.reload(); - } await app.workbench.quickaccess.runCommand('Smoke Test Check'); await app.workbench.statusbar.waitForStatusbarText('smoke test', 'VS Code Smoke Test Check'); }); after(async function () { const app = this.app as Application; + if (app.web) { + return; + } + await app.workbench.settingsEditor.clearUserSettings(); }); diff --git a/test/smoke/src/main.ts b/test/smoke/src/main.ts index cf3c02b0efb..13023eb50c8 100644 --- a/test/smoke/src/main.ts +++ b/test/smoke/src/main.ts @@ -315,7 +315,7 @@ describe(`VSCode Smoke Tests (${opts.web ? 'Web' : 'Electron'})`, () => { setupDataLanguagesTests(); setupDataEditorTests(); setupDataStatusbarTests(!!opts.web); - if (!opts.web) { setupDataExtensionTests(); } + setupDataExtensionTests(); if (!opts.web) { setupDataMultirootTests(); } if (!opts.web) { setupDataLocalizationTests(); } if (!opts.web) { setupLaunchTests(); }