Skip to content

Commit 97397a8

Browse files
authored
feat(amazonq): UI Tests Baseline Framework Complete Set Up (#7727)
## Change This is a large PR for all the baseline setup of the framework. It includes the auth, setup, 4 test suites and the abstractions for each, and the cleanup functions. --- - Treat all work as PUBLIC. Private `feature/x` branches will not be squash-merged at release time. - Your code changes must meet the guidelines in [CONTRIBUTING.md](https://github.com/aws/aws-toolkit-vscode/blob/master/CONTRIBUTING.md#guidelines). - License: I confirm that my contribution is made under the terms of the Apache 2.0 license.
1 parent daf0938 commit 97397a8

File tree

13 files changed

+662
-166
lines changed

13 files changed

+662
-166
lines changed

packages/amazonq/test/e2e/amazonq/VET.test.ts

Lines changed: 0 additions & 166 deletions
This file was deleted.
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
/*!
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
import { By, WebviewView } from 'vscode-extension-tester'
6+
import { sleep, waitForElement } from '../utils/generalUtils'
7+
import { WebElement } from 'vscode-extension-tester'
8+
9+
/**
10+
* Clicks the "Pin Context" button in the chat interface
11+
* @param webview The WebviewView instance
12+
* @returns Promise<boolean> True if button was found and clicked, false otherwise
13+
*/
14+
export async function clickPinContextButton(webview: WebviewView): Promise<boolean> {
15+
try {
16+
const topBar = await waitForElement(webview, By.css('.mynah-prompt-input-top-bar'))
17+
const buttons = await topBar.findElements(
18+
By.css('.mynah-button.mynah-button-secondary.fill-state-always.status-clear.mynah-ui-clickable-item')
19+
)
20+
// double check the label to make sure it says "Pin Context"
21+
for (const button of buttons) {
22+
const label = await button.findElement(By.css('.mynah-button-label'))
23+
const labelText = await label.getText()
24+
console.log('THE BUTTON TEXT LABEL IS:', labelText)
25+
if (labelText === '@Pin Context') {
26+
console.log('Found Pin Context button, clicking...')
27+
await button.click()
28+
return true
29+
}
30+
}
31+
console.log('Pin Context button not found')
32+
return false
33+
} catch (e) {
34+
console.error('Error clicking Pin Context button:', e)
35+
return false
36+
}
37+
}
38+
39+
/**
40+
* Lists all the possible Pin Context menu items in the console.
41+
* @param webview The WebviewView instance
42+
* @returns Promise<boolean> Returns the items as a WebElement List and the labels in a string array
43+
*/
44+
export async function getPinContextMenuItems(webview: WebviewView): Promise<{ items: WebElement[]; labels: string[] }> {
45+
try {
46+
const menuList = await waitForElement(webview, By.css('.mynah-detailed-list-items-block'))
47+
await sleep(3000)
48+
const menuListItems = await menuList.findElements(By.css('.mynah-detailed-list-item.mynah-ui-clickable-item'))
49+
const labels: string[] = []
50+
51+
for (const item of menuListItems) {
52+
try {
53+
const textWrapper = await item.findElement(By.css('.mynah-detailed-list-item-text'))
54+
const nameElement = await textWrapper.findElement(By.css('.mynah-detailed-list-item-name'))
55+
const labelText = await nameElement.getText()
56+
labels.push(labelText)
57+
console.log('Menu item found:', labelText)
58+
} catch (e) {
59+
labels.push('')
60+
console.log('Could not get text for menu item')
61+
}
62+
}
63+
64+
return { items: menuListItems, labels }
65+
} catch (e) {
66+
console.error('Error getting Pin Context menu items:', e)
67+
return { items: [], labels: [] }
68+
}
69+
}
70+
71+
/**
72+
* Clicks a specific item in the Pin Context menu by its label text
73+
* @param webview The WebviewView instance
74+
* @param itemName The text label of the menu item to click
75+
* @returns Promise<boolean> True if the item was found and clicked, false otherwise
76+
*
77+
* NOTE: To find all possible text labels, you can call getPinContextMenuItems
78+
*/
79+
export async function clickPinContextMenuItem(webview: WebviewView, itemName: string): Promise<boolean> {
80+
try {
81+
const menuList = await waitForElement(webview, By.css('.mynah-detailed-list-items-block'))
82+
await sleep(3000)
83+
const menuListItems = await menuList.findElements(By.css('.mynah-detailed-list-item.mynah-ui-clickable-item'))
84+
for (const item of menuListItems) {
85+
try {
86+
const textWrapper = await item.findElement(By.css('.mynah-detailed-list-item-text'))
87+
const nameElement = await textWrapper.findElement(By.css('.mynah-detailed-list-item-name'))
88+
const labelText = await nameElement.getText()
89+
90+
if (labelText === itemName) {
91+
console.log(`Clicking Pin Context menu item: ${itemName}`)
92+
await item.click()
93+
return true
94+
}
95+
} catch (e) {
96+
continue
97+
}
98+
}
99+
100+
console.log(`Pin Context menu item not found: ${itemName}`)
101+
return false
102+
} catch (e) {
103+
console.error(`Error clicking Pin Context menu item ${itemName}:`, e)
104+
return false
105+
}
106+
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
/*!
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
import { By, WebElement, WebviewView } from 'vscode-extension-tester'
7+
import { writeToChat } from '../utils/generalUtils'
8+
import { sleep, waitForElements } from '../utils/generalUtils'
9+
10+
/**
11+
* Gets all quick action command menu items
12+
* @param webview The WebviewView instance
13+
* @returns Promise<{items: WebElement[], texts: string[]}> Array of menu items and their text labels
14+
*/
15+
export async function getQuickActionsCommands(webview: WebviewView): Promise<{ items: WebElement[]; texts: string[] }> {
16+
try {
17+
await writeToChat('/', webview, false)
18+
await sleep(2000)
19+
20+
const menuItems = await waitForElements(
21+
webview,
22+
By.css('.mynah-detailed-list-item.mynah-ui-clickable-item.target-command'),
23+
10000
24+
)
25+
26+
const menuTexts = []
27+
for (let i = 0; i < menuItems.length; i++) {
28+
try {
29+
const text = await menuItems[i].getText()
30+
menuTexts.push(text)
31+
console.log(`Command ${i + 1}: ${text}`)
32+
} catch (e) {
33+
menuTexts.push('')
34+
console.log(`Could not get text for command ${i + 1}`)
35+
}
36+
}
37+
38+
console.log(`Found ${menuItems.length} quick action command items`)
39+
return { items: menuItems, texts: menuTexts }
40+
} catch (e) {
41+
console.error('Error getting quick action commands:', e)
42+
return { items: [], texts: [] }
43+
}
44+
}
45+
46+
/**
47+
* Clicks a specific quick action command by name
48+
* @param webview The WebviewView instance
49+
* @param commandName The name of the command to click
50+
* @returns Promise<boolean> True if command was found and clicked, false otherwise
51+
*/
52+
export async function clickQuickActionsCommand(webview: WebviewView, commandName: string): Promise<boolean> {
53+
try {
54+
const { items, texts } = await getQuickActionsCommands(webview)
55+
if (items.length === 0) {
56+
console.log('No quick action commands found to click')
57+
return false
58+
}
59+
const indexToClick = texts.findIndex((text) => text === commandName)
60+
61+
if (indexToClick === -1) {
62+
console.log(`Command "${commandName}" not found`)
63+
return false
64+
}
65+
console.log(`Clicking on command: ${commandName}`)
66+
await items[indexToClick].click()
67+
await sleep(3000)
68+
console.log('Command clicked successfully')
69+
return true
70+
} catch (e) {
71+
console.error('Error clicking quick action command:', e)
72+
return false
73+
}
74+
}

0 commit comments

Comments
 (0)