diff --git a/packages/amazonq/test/e2e_new/amazonq/helpers/pinContextHelper.ts b/packages/amazonq/test/e2e_new/amazonq/helpers/pinContextHelper.ts index aa58ea2d75d..652b9ae1f8c 100644 --- a/packages/amazonq/test/e2e_new/amazonq/helpers/pinContextHelper.ts +++ b/packages/amazonq/test/e2e_new/amazonq/helpers/pinContextHelper.ts @@ -9,31 +9,25 @@ import { WebElement } from 'vscode-extension-tester' /** * Clicks the "Pin Context" button in the chat interface * @param webview The WebviewView instance - * @returns Promise True if button was found and clicked, false otherwise + * @throws Error if button is not found */ -export async function clickPinContextButton(webview: WebviewView): Promise { - try { - const topBar = await waitForElement(webview, By.css('.mynah-prompt-input-top-bar')) - const buttons = await topBar.findElements( - By.css('.mynah-button.mynah-button-secondary.fill-state-always.status-clear.mynah-ui-clickable-item') - ) - // double check the label to make sure it says "Pin Context" - for (const button of buttons) { - const label = await button.findElement(By.css('.mynah-button-label')) - const labelText = await label.getText() - console.log('THE BUTTON TEXT LABEL IS:', labelText) - if (labelText === '@Pin Context') { - console.log('Found Pin Context button, clicking...') - await button.click() - return true - } +export async function clickPinContextButton(webview: WebviewView): Promise { + const topBar = await waitForElement(webview, By.css('.mynah-prompt-input-top-bar')) + const buttons = await topBar.findElements( + By.css('.mynah-button.mynah-button-secondary.fill-state-always.status-clear.mynah-ui-clickable-item') + ) + // double check the label to make sure it says "Pin Context" + for (const button of buttons) { + const label = await button.findElement(By.css('.mynah-button-label')) + const labelText = await label.getText() + console.log('THE BUTTON TEXT LABEL IS:', labelText) + if (labelText === '@Pin Context') { + console.log('Found Pin Context button, clicking...') + await button.click() + return } - console.log('Pin Context button not found') - return false - } catch (e) { - console.error('Error clicking Pin Context button:', e) - return false } + throw new Error('Pin Context button not found') } /** @@ -42,65 +36,105 @@ export async function clickPinContextButton(webview: WebviewView): Promise Returns the items as a WebElement List and the labels in a string array */ export async function getPinContextMenuItems(webview: WebviewView): Promise<{ items: WebElement[]; labels: string[] }> { - try { - const menuList = await waitForElement(webview, By.css('.mynah-detailed-list-items-block')) - await sleep(3000) - const menuListItems = await menuList.findElements(By.css('.mynah-detailed-list-item.mynah-ui-clickable-item')) - const labels: string[] = [] + const menuList = await waitForElement(webview, By.css('.mynah-detailed-list-items-block')) + // TODO: Fix the need for a sleep function to be required at all. + await sleep(100) + const menuListItems = await menuList.findElements(By.css('.mynah-detailed-list-item.mynah-ui-clickable-item')) - for (const item of menuListItems) { - try { - const textWrapper = await item.findElement(By.css('.mynah-detailed-list-item-text')) - const nameElement = await textWrapper.findElement(By.css('.mynah-detailed-list-item-name')) - const labelText = await nameElement.getText() - labels.push(labelText) - console.log('Menu item found:', labelText) - } catch (e) { - labels.push('') - console.log('Could not get text for menu item') - } - } + if (menuListItems.length === 0) { + throw new Error('No pin context menu items found') + } - return { items: menuListItems, labels } - } catch (e) { - console.error('Error getting Pin Context menu items:', e) - return { items: [], labels: [] } + const labels: string[] = [] + for (const item of menuListItems) { + const textWrapper = await item.findElement(By.css('.mynah-detailed-list-item-text')) + const nameElement = await textWrapper.findElement(By.css('.mynah-detailed-list-item-name')) + const labelText = await nameElement.getText() + labels.push(labelText) + console.log('Menu item found:', labelText) } + + return { items: menuListItems, labels } } /** * Clicks a specific item in the Pin Context menu by its label text * @param webview The WebviewView instance * @param itemName The text label of the menu item to click - * @returns Promise True if the item was found and clicked, false otherwise + * @throws Error if the menu item is not found or DOM structure is invalid * * NOTE: To find all possible text labels, you can call getPinContextMenuItems */ -export async function clickPinContextMenuItem(webview: WebviewView, itemName: string): Promise { - try { - const menuList = await waitForElement(webview, By.css('.mynah-detailed-list-items-block')) - await sleep(3000) - const menuListItems = await menuList.findElements(By.css('.mynah-detailed-list-item.mynah-ui-clickable-item')) - for (const item of menuListItems) { - try { - const textWrapper = await item.findElement(By.css('.mynah-detailed-list-item-text')) - const nameElement = await textWrapper.findElement(By.css('.mynah-detailed-list-item-name')) - const labelText = await nameElement.getText() +export async function clickPinContextMenuItem(webview: WebviewView, itemName: string): Promise { + const menuList = await waitForElement(webview, By.css('.mynah-detailed-list-items-block')) + await sleep(100) + const menuListItems = await menuList.findElements(By.css('.mynah-detailed-list-item.mynah-ui-clickable-item')) + for (const item of menuListItems) { + const textWrapper = await item.findElement(By.css('.mynah-detailed-list-item-text')) + const nameElement = await textWrapper.findElement(By.css('.mynah-detailed-list-item-name')) + const labelText = await nameElement.getText() - if (labelText === itemName) { - console.log(`Clicking Pin Context menu item: ${itemName}`) - await item.click() - return true - } - } catch (e) { - continue - } + if (labelText === itemName) { + console.log(`Clicking Pin Context menu item: ${itemName}`) + await item.click() + return } + } + + throw new Error(`Pin Context menu item not found: ${itemName}`) +} +/** + * Lists all the possible Sub-menu items in the console. + * @param webview The WebviewView instance + * @returns Promise Returns the items as a WebElement List and the labels in a string array + */ +export async function getSubMenuItems(webview: WebviewView): Promise<{ items: WebElement[]; labels: string[] }> { + const menuList = await waitForElement(webview, By.css('.mynah-detailed-list-items-block')) + await sleep(100) + const menuListItems = await menuList.findElements(By.css('.mynah-detailed-list-item.mynah-ui-clickable-item')) - console.log(`Pin Context menu item not found: ${itemName}`) - return false - } catch (e) { - console.error(`Error clicking Pin Context menu item ${itemName}:`, e) - return false + if (menuListItems.length === 0) { + throw new Error('No sub-menu items found') + } + + const labels: string[] = [] + for (const item of menuListItems) { + const textWrapper = await item.findElement( + By.css('.mynah-detailed-list-item-text.mynah-detailed-list-item-text-direction-row') + ) + const nameElement = await textWrapper.findElement(By.css('.mynah-detailed-list-item-name')) + const labelText = await nameElement.getText() + labels.push(labelText) + console.log('Menu item found:', labelText) } + + return { items: menuListItems, labels } +} +/** + * Clicks a specific item in the Sub-Menu by its label text + * @param webview The WebviewView instance + * @param itemName The text label of the menu item to click + * @throws Error if the menu item is not found or DOM structure is invalid + * + * NOTE: To find all possible text labels, you can call getPinContextMenuItems + */ +export async function clickSubMenuItem(webview: WebviewView, itemName: string): Promise { + const menuList = await waitForElement(webview, By.css('.mynah-detailed-list-items-block')) + await sleep(100) + const menuListItems = await menuList.findElements(By.css('.mynah-detailed-list-item.mynah-ui-clickable-item')) + for (const item of menuListItems) { + const textWrapper = await item.findElement( + By.css('.mynah-detailed-list-item-text.mynah-detailed-list-item-text-direction-row') + ) + const nameElement = await textWrapper.findElement(By.css('.mynah-detailed-list-item-name')) + const labelText = await nameElement.getText() + + if (labelText === itemName) { + console.log(`Clicking Pin Context menu item: ${itemName}`) + await item.click() + return + } + } + + throw new Error(`Pin Context menu item not found: ${itemName}`) } diff --git a/packages/amazonq/test/e2e_new/amazonq/tests/pinContext.test.ts b/packages/amazonq/test/e2e_new/amazonq/tests/pinContext.test.ts index 4e6c9c5a477..a2998077935 100644 --- a/packages/amazonq/test/e2e_new/amazonq/tests/pinContext.test.ts +++ b/packages/amazonq/test/e2e_new/amazonq/tests/pinContext.test.ts @@ -3,11 +3,11 @@ * SPDX-License-Identifier: Apache-2.0 */ import '../utils/setup' -import { WebviewView } from 'vscode-extension-tester' +import { WebviewView, By } from 'vscode-extension-tester' import { closeAllTabs, dismissOverlayIfPresent } from '../utils/cleanupUtils' import { testContext } from '../utils/testContext' -import { clickPinContextButton, getPinContextMenuItems, clickPinContextMenuItem } from '../helpers/pinContextHelper' -import { clearChat } from '../utils/generalUtils' +import { clickPinContextButton, clickPinContextMenuItem, clickSubMenuItem } from '../helpers/pinContextHelper' +import { waitForElement } from '../utils/generalUtils' describe('Amazon Q Pin Context Functionality', function () { // this timeout is the general timeout for the entire test suite @@ -18,18 +18,33 @@ describe('Amazon Q Pin Context Functionality', function () { webviewView = testContext.webviewView }) - after(async function () { - await closeAllTabs(webviewView) - }) - afterEach(async () => { await dismissOverlayIfPresent(webviewView) - await clearChat(webviewView) + await closeAllTabs(webviewView) }) - - it('Pin Context Test', async () => { + it('Allows User to Add File Context', async () => { + await clickPinContextButton(webviewView) + await clickPinContextMenuItem(webviewView, 'Files') + await clickPinContextMenuItem(webviewView, 'Active file') + }) + it('Allows User to Pin Workspace Context', async () => { await clickPinContextButton(webviewView) - await getPinContextMenuItems(webviewView) await clickPinContextMenuItem(webviewView, '@workspace') }) + it('Allows User to Add Prompt Context', async () => { + await clickPinContextButton(webviewView) + await clickPinContextMenuItem(webviewView, 'Prompts') + const addPrompt = await waitForElement(webviewView, By.css('.mynah-ui-icon.mynah-ui-icon-list-add')) + await addPrompt.click() + const chatInput = await waitForElement(webviewView, By.css('[data-testid="chat-item-form-item-text-input"]')) + await chatInput.sendKeys('test') + const createPrompt = await waitForElement( + webviewView, + By.css('.mynah-button.fill-state-always.status-primary.mynah-ui-clickable-item') + ) + await createPrompt.click() + await clickPinContextButton(webviewView) + await clickPinContextMenuItem(webviewView, 'Prompts') + await clickSubMenuItem(webviewView, 'test') + }) })