-
Notifications
You must be signed in to change notification settings - Fork 688
feat(amazonq): Add Pin Context Tests and Update to pinContextHelper #7829
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 5 commits
3bf85a6
d9b13a0
f48bfdf
b190cde
4252646
96f9d31
5412977
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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<boolean> True if button was found and clicked, false otherwise | ||
* @throws Error if button is not found | ||
*/ | ||
export async function clickPinContextButton(webview: WebviewView): Promise<boolean> { | ||
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<void> { | ||
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<boole | |
* @returns Promise<boolean> 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. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ty |
||
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) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Out of curiosity, how noisy are the logs when running the full test suite? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The logs aren't too noisy, I actually think they're helpful to see the process of the test in my opinion |
||
} | ||
|
||
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<boolean> 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<boolean> { | ||
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<void> { | ||
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<boolean> 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<void> { | ||
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}`) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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') | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. my understanding is that this returns a boolean false if it fails, but this won't cause the test to fail. |
||
}) | ||
}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Was this for debugging? Do we want to this run on text execution.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh do you mean the console.log statements?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah maybe we can build a toggle for logging with a logging abstraction as a follow up