UNPKG

@salesforce/salesforcedx-vscode-test-tools

Version:
242 lines (219 loc) 8.4 kB
/* * 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 */ import { Duration, log, pause } from '../core/miscellaneous'; import { retryOperation } from '../retryUtils'; import { getBrowser, getWorkbench } from './workbench'; import { By, InputBox, Key, QuickOpenBox, Workbench } from 'vscode-extension-tester'; /** * Opens the command prompt and enters a command * @param workbench - The VSCode workbench instance * @param command - The command to enter in the prompt * @returns The InputBox or QuickOpenBox representing the command prompt */ export async function openCommandPromptWithCommand( workbench: Workbench, command: string ): Promise<InputBox | QuickOpenBox> { const prompt = await (await workbench.openCommandPrompt()).wait(); await (await prompt.wait()).setText(`>${command}`); return prompt; } /** * Runs a command from the command prompt * @param workbench - The VSCode workbench instance * @param command - The command to run * @param durationInSeconds - Optional duration to wait after running the command * @returns The InputBox or QuickOpenBox representing the command prompt */ export async function runCommandFromCommandPrompt( workbench: Workbench, command: string, durationInSeconds: Duration = Duration.seconds(0) ): Promise<InputBox | QuickOpenBox> { const prompt = await (await openCommandPromptWithCommand(workbench, command)).wait(); await selectQuickPickItem(prompt, command); if (durationInSeconds.milliseconds > 0) { await pause(durationInSeconds); } return prompt; } /** * Selects a quick pick option with the specified text * @param prompt - The command prompt * @param text - The text of the quick pick option to select */ export async function selectQuickPickWithText(prompt: InputBox | QuickOpenBox, text: string) { // Set the text in the command prompt. Only selectQuickPick() needs to be called, but setting // the text in the command prompt is a nice visual feedback to anyone watching the tests run. await prompt.setText(text); await pause(Duration.seconds(1)); await prompt.selectQuickPick(text); await pause(Duration.seconds(1)); // After the text has been entered and selectQuickPick() is called, you might see the last few characters // in the input box be deleted. This is b/c selectQuickPick() calls resetPosition(), which for some reason // deletes the last two characters. This doesn't seem to affect the outcome though. } /** * Selects a quick pick item with the exact text * @param prompt - The command prompt * @param text - The exact text of the quick pick item to select * @throws Error if the prompt is undefined or if the quick pick item is not found */ export async function selectQuickPickItem(prompt: InputBox | QuickOpenBox | undefined, text: string): Promise<void> { if (!prompt) { throw new Error('Prompt cannot be undefined'); } const quickPick = await prompt.findQuickPick(text); if (!quickPick || (await quickPick.getLabel()) !== text) { throw new Error(`Quick pick item ${text} was not found`); } await quickPick.select(); await pause(Duration.seconds(1)); } /** * Finds a quick pick item in the command prompt * @param inputBox - The command prompt * @param quickPickItemTitle - The text to search for in quick pick items * @param useExactMatch - If true, looks for exact match; if false, checks if item contains the text * @param selectTheQuickPickItem - If true, selects the item when found * @returns True if the item was found, false otherwise */ export async function findQuickPickItem( inputBox: InputBox | QuickOpenBox | undefined, quickPickItemTitle: string, useExactMatch: boolean, selectTheQuickPickItem: boolean ): Promise<boolean> { if (!inputBox) { return false; } // Type the text into the filter. Do this in case the pick list is long and // the target item is not visible (and one needs to scroll down to see it). await inputBox.setText(quickPickItemTitle); await pause(Duration.seconds(1)); let itemWasFound = false; const quickPicks = await inputBox.getQuickPicks(); for (const quickPick of quickPicks) { const label = await quickPick.getLabel(); if (useExactMatch && label === quickPickItemTitle) { itemWasFound = true; } else if (!useExactMatch && label.includes(quickPickItemTitle)) { itemWasFound = true; } if (itemWasFound) { if (selectTheQuickPickItem) { await quickPick.select(); await pause(Duration.seconds(1)); } return true; } } return false; } /** * Waits for a quick pick item to appear in the command prompt * @param prompt - The command prompt * @param pickListItem - The text of the quick pick item to wait for * @param options - Optional configuration including timeout and error message */ export async function waitForQuickPick( prompt: InputBox | QuickOpenBox | undefined, pickListItem: string, options: { msg?: string; timeout?: Duration } = { timeout: Duration.milliseconds(10_000) } ) { await getBrowser().wait( async () => { try { await findQuickPickItem(prompt, pickListItem, false, true); return true; // eslint-disable-next-line @typescript-eslint/no-unused-vars } catch (_) { return false; } }, options.timeout?.milliseconds, options.msg ?? `Expected to find option ${pickListItem} before ${options.timeout} milliseconds`, 500 // Check every 500 ms ); } /** * Runs exact command from command palette * @param command - The command to execute * @param wait - Duration to wait after executing the command; default is 1 second * @returns The command prompt interface * @throws Error if the command is not found or execution fails */ export async function executeQuickPick( command: string, wait: Duration = Duration.seconds(1) ): Promise<InputBox | QuickOpenBox> { log(`executeQuickPick command: ${command}`); return await retryOperation(async () => { const workbench = getWorkbench(); const inputBox = await workbench.openCommandPrompt(); await pause(Duration.seconds(2)); await inputBox.wait(); await inputBox.setText(`>${command}`); await inputBox.selectQuickPick(command); await pause(wait); log(`executeQuickPick command: ${command} - done`); return inputBox; }, 3, `executeQuickPick command: ${command} - failed` ); } /** * Clicks the OK button in a file path dialog * Also handles the Overwrite confirmation if a folder already exists * @throws Error if the OK button is not found */ export async function clickFilePathOkButton(): Promise<void> { const browser = getBrowser(); const okButton = await browser.findElement( By.css('*:not([style*="display: none"]).quick-input-action .monaco-button') ); if (!okButton) { throw new Error('Ok button not found'); } await pause(Duration.milliseconds(500)); await okButton.sendKeys(Key.ENTER); await pause(Duration.seconds(1)); const buttons = await browser.findElements(By.css('a.monaco-button.monaco-text-button')); for (const item of buttons) { const text = await item.getText(); if (text.includes('Overwrite')) { log('clickFilePathOkButton() - folder already exists'); await browser.wait( async () => (await item.isDisplayed()) && (await item.isEnabled()), Duration.seconds(5).milliseconds, `Overwrite button not clickable within 5 seconds` ); await item.click(); break; } } await pause(Duration.seconds(2)); } /** * Checks if a VSCode command is available. * @param commandName - Name of the VSCode command to check * @returns boolean - true if the command is available, false otherwise */ export const isCommandAvailable = async (commandName: string): Promise<boolean> => { log('Checking if command is available: ' + commandName); const workbench = getWorkbench(); const prompt = await workbench.openCommandPrompt(); await prompt.setText(`>${commandName}`); const availableCommands = await prompt.getQuickPicks(); for (const item of availableCommands) { if ((await item.getLabel()) === commandName) { return true; } } return false; };