UNPKG

@salesforce/salesforcedx-vscode-test-tools

Version:
186 lines 8.89 kB
"use strict"; /* * Copyright (c) 2025, salesforce.com, inc. * All rights reserved. * Licensed under the BSD 3-Clause license. * For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause */ Object.defineProperty(exports, "__esModule", { value: true }); exports.checkForUncaughtErrors = exports.getExtensionsToVerifyActive = void 0; exports.showRunningExtensions = showRunningExtensions; exports.reloadAndEnableExtensions = reloadAndEnableExtensions; exports.verifyExtensionsAreRunning = verifyExtensionsAreRunning; exports.findExtensionsInRunningExtensionsList = findExtensionsInRunningExtensionsList; const miscellaneous_1 = require("../core/miscellaneous"); const commandPrompt_1 = require("../ui-interaction/commandPrompt"); const vscode_extension_tester_1 = require("vscode-extension-tester"); const chai_1 = require("chai"); const ui_interaction_1 = require("../ui-interaction"); const VERIFY_EXTENSIONS_TIMEOUT = miscellaneous_1.Duration.seconds(60); /** * Shows the list of running extensions in VS Code * @returns The editor showing running extensions, or undefined if not found */ async function showRunningExtensions() { (0, miscellaneous_1.log)(''); (0, miscellaneous_1.log)(`Starting showRunningExtensions()...`); await (0, commandPrompt_1.executeQuickPick)('Developer: Show Running Extensions'); let re = undefined; await (0, ui_interaction_1.getBrowser)().wait(async () => { const wb = (0, ui_interaction_1.getWorkbench)(); const ev = wb.getEditorView(); re = await ev.openEditor('Running Extensions'); return re.isDisplayed(); }, 5000, // Timeout after 5 seconds 'Expected "Running Extensions" tab to be visible after 5 seconds', 500); (0, miscellaneous_1.log)(`... Finished showRunningExtensions()`); (0, miscellaneous_1.log)(''); return re; } /** * Reloads the VS Code window and enables all extensions */ async function reloadAndEnableExtensions() { await (0, ui_interaction_1.reloadWindow)(); await (0, ui_interaction_1.enableAllExtensions)(); } /** * Gets a list of extensions that need to be verified as active * @param extensions - Array of extensions to filter * @param predicate - Optional filter function to apply to the extensions * @returns Array of extensions that should be verified as active */ const getExtensionsToVerifyActive = (extensions, predicate = ext => !!ext) => { return extensions .filter(ext => { return ext.shouldVerifyActivation; }) .filter(predicate); }; exports.getExtensionsToVerifyActive = getExtensionsToVerifyActive; /** * Verifies that specified extensions are running in VS Code * @param extensions - Array of extensions to verify * @param timeout - Optional timeout (defaults to VERIFY_EXTENSIONS_TIMEOUT) * @returns True if all extensions are activated successfully */ async function verifyExtensionsAreRunning(extensions, timeout = VERIFY_EXTENSIONS_TIMEOUT) { (0, miscellaneous_1.log)(''); (0, miscellaneous_1.log)(`Starting verifyExtensionsAreRunning()...`); if (extensions.length === 0) { (0, miscellaneous_1.log)('verifyExtensionsAreRunning - No extensions to verify, continuing test run w/o extension verification'); return true; } const extensionIDsToVerify = extensions.map(extension => extension.extensionId); await (0, miscellaneous_1.pause)(miscellaneous_1.Duration.seconds(15)); await (0, ui_interaction_1.zoom)('Out', 4, miscellaneous_1.Duration.seconds(1)); let extensionsStatus = []; let allActivated = false; const timeoutPromise = new Promise((_, reject) => setTimeout(() => reject(new Error('findExtensionsInRunningExtensionsList timeout')), timeout.milliseconds)); try { await Promise.race([ (async () => { do { extensionsStatus = await findExtensionsInRunningExtensionsList(extensionIDsToVerify); extensions.map(e => { const found = extensionsStatus.find(es => es.extensionId === e.extensionId); if (found) { // Log the current state of the activation check for each extension (0, miscellaneous_1.log)(`Extension ${found.extensionId}: ${found.activationTime ?? 'No activation time'}`); } else { (0, miscellaneous_1.log)(`Extension ${e.extensionId}: ${e.name} is not activated yet`); } }); allActivated = extensionIDsToVerify.every(extensionId => extensionsStatus.find(extensionStatus => extensionStatus.extensionId === extensionId) ?.isActivationComplete); } while (!allActivated); })(), timeoutPromise ]); } catch (error) { (0, miscellaneous_1.log)(`Error while waiting for extensions to activate: ${error}`); } await (0, ui_interaction_1.zoomReset)(); (0, miscellaneous_1.log)('... Finished verifyExtensionsAreRunning()'); (0, miscellaneous_1.log)(''); return allActivated; } /** * Finds and returns information about running extensions * @param extensionIds - Array of extension IDs to look for * @returns Array of extension activation information * @throws If the running extensions editor cannot be found */ async function findExtensionsInRunningExtensionsList(extensionIds) { (0, miscellaneous_1.log)(''); (0, miscellaneous_1.log)('Starting findExtensionsInRunningExtensionsList()...'); // This function assumes the Extensions list was opened. // Close the panel and clear notifications so we can see as many of the running extensions as we can. try { const center = await (0, ui_interaction_1.getWorkbench)().openNotificationsCenter(); await center.clearAllNotifications(); await center.close(); } catch (error) { if (error instanceof Error) { (0, miscellaneous_1.log)(`Failed clearing all notifications ${error.message}`); } } const runningExtensionsEditor = await showRunningExtensions(); if (!runningExtensionsEditor) { throw new Error('Could not find the running extensions editor'); } // Get all extensions const allExtensions = await runningExtensionsEditor.findElements(vscode_extension_tester_1.By.css('div.monaco-list-row > div.extension')); const runningExtensions = []; for (const extension of allExtensions) { const parent = await extension.findElement(vscode_extension_tester_1.By.xpath('..')); const extensionId = await parent.getAttribute('aria-label'); const version = await extension.findElement(vscode_extension_tester_1.By.css('.version')).getText(); const activationTime = await extension.findElement(vscode_extension_tester_1.By.css('.activation-time')).getText(); const isActivationComplete = /\:\s*?[0-9]{1,}ms/.test(activationTime); let hasBug; try { await parent.findElement(vscode_extension_tester_1.By.css('span.codicon-bug error')); } catch (error) { if (error instanceof Error) { hasBug = error.message.startsWith('no such element') ? false : true; } else { hasBug = true; } } runningExtensions.push({ extensionId, activationTime, version, isPresent: true, hasBug, isActivationComplete }); } (0, miscellaneous_1.log)('... Finished findExtensionsInRunningExtensionsList()'); (0, miscellaneous_1.log)(''); // limit runningExtensions to those whose property extensionId is in the list of extensionIds return runningExtensions.filter(extension => extensionIds.includes(extension.extensionId)); } /** * Checks for uncaught errors in extensions and fails the test if any are found * @param extensions - Array of extensions to check for errors */ const checkForUncaughtErrors = async (extensions) => { await showRunningExtensions(); // Zoom out so all the extensions are visible await (0, ui_interaction_1.zoom)('Out', 4, miscellaneous_1.Duration.seconds(1)); const uncaughtErrors = (await findExtensionsInRunningExtensionsList((0, exports.getExtensionsToVerifyActive)(extensions).map(ext => ext.extensionId))).filter(ext => ext.hasBug); await (0, ui_interaction_1.zoomReset)(); uncaughtErrors.forEach(ext => { (0, miscellaneous_1.log)(`Extension ${ext.extensionId}:${ext.version ?? 'unknown'} has a bug`); }); (0, chai_1.expect)(uncaughtErrors.length).equal(0); }; exports.checkForUncaughtErrors = checkForUncaughtErrors; //# sourceMappingURL=extensionUtils.js.map