Skip to content

Commit 641f583

Browse files
committed
implementation done
1 parent 9edf5ce commit 641f583

File tree

3 files changed

+131
-64
lines changed

3 files changed

+131
-64
lines changed

packages/amazonq/test/e2e_new/amazonq/helpers/rulesHelper.ts

Lines changed: 91 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -3,56 +3,111 @@
33
* SPDX-License-Identifier: Apache-2.0
44
*/
55
import { WebviewView, By } from 'vscode-extension-tester'
6-
import { waitForElement } from '../utils/generalUtils'
6+
import { printElementHTML, sleep, waitForElement } from '../utils/generalUtils'
77

88
/**
99
* Clicks the Rules button in the top bar
10-
* @param webviewView The WebviewView instance
10+
* @param webview The WebviewView instance
1111
*/
12-
export async function clickRulesButton(webviewView: WebviewView): Promise<void> {
13-
const wrapper = await webviewView.findElement(By.css('.mynah-chat-prompt-wrapper'))
14-
const topBar = await wrapper.findElement(By.css('.mynah-prompt-input-top-bar'))
15-
console.log('THIS WORKS 1')
16-
const buttons = await topBar.findElement(By.css('[data-testid="prompt-input-top-bar-button"]'))
17-
console.log('THIS WORKS 2')
18-
const button = await buttons.findElement(By.css('*'))
19-
console.log('THIS WORKS 3')
20-
await button.click()
12+
export async function clickRulesButton(webview: WebviewView): Promise<void> {
13+
const body = await webview.findWebElement(By.css('body'))
14+
await printElementHTML(body)
15+
16+
const chatPromptWrapper = await waitForElement(webview, By.css('.mynah-chat-prompt-wrapper'))
17+
const topBar = await chatPromptWrapper.findElement(By.css('[data-testid="prompt-input-top-bar"]'))
18+
const buttons = await topBar.findElements(By.css('.mynah-button.mynah-button-secondary'))
19+
20+
for (const button of buttons) {
21+
try {
22+
const labelElement = await button.findElement(By.css('.mynah-button-label'))
23+
const text = await labelElement.getText()
24+
if (text.trim() === 'Rules') {
25+
await button.click()
26+
return
27+
}
28+
} catch (e) {
29+
continue
30+
}
31+
}
32+
throw new Error('Rules button not found')
33+
}
34+
35+
/**
36+
* Clicks on "Create a new rule" option from the rules menu
37+
* @param webview The WebviewView instance
38+
*/
39+
export async function clickCreateNewRuleOption(webview: WebviewView): Promise<void> {
40+
// needs a bit of time because the overlay has to load
41+
await sleep(1000)
42+
const overlayContainer = await waitForElement(webview, By.css('.mynah-overlay-container'))
43+
const quickPickItems = await overlayContainer.findElements(By.css('[data-testid="prompt-input-quick-pick-item"]'))
44+
45+
if (quickPickItems.length === 0) {
46+
throw new Error('No quick pick items found')
47+
}
48+
const lastItem = quickPickItems[quickPickItems.length - 1]
49+
const bdiElement = await lastItem.findElement(By.css('.mynah-detailed-list-item-description.ltr bdi'))
50+
const text = await bdiElement.getText()
51+
52+
if (text.trim() !== 'Create a new rule') {
53+
throw new Error(`Expected "Create a new rule" but found "${text}"`)
54+
}
55+
await lastItem.click()
2156
}
2257

2358
/**
24-
* Creates a new rule with the specified name
25-
* @param webviewView The WebviewView instance
26-
* @param ruleName The name of the rule to create (defaults to "testRule")
59+
* Enters a rule name in the rule creation form
60+
* @param webview The WebviewView instance
61+
* @param ruleName The name of the rule
2762
*/
28-
export async function createRule(webviewView: WebviewView, ruleName: string = 'testRule'): Promise<void> {
29-
const overlay = await waitForElement(webviewView, By.css('[data-testid="prompt-input-top-bar-action-overlay"]'))
30-
const create = overlay.findElement(By.css('[data-testid="prompt-input-quick-pick-item"]'))
31-
await create.click()
32-
const anotheroverlay = await waitForElement(webviewView, By.css('[data-testid="sheet-wrapper"]'))
33-
const input = await anotheroverlay.findElement(By.css('[data-testid="chat-item-form-item-text-input"]'))
34-
await input.sendKeys(ruleName)
35-
await clickCreateRule(webviewView)
63+
export async function enterRuleName(webview: WebviewView, ruleName: string): Promise<void> {
64+
// needs a bit of time because the overlay has to load
65+
await sleep(1000)
66+
const sheetWrapper = await waitForElement(webview, By.css('[data-testid="sheet-wrapper"]'))
67+
const ruleNameInput = await sheetWrapper.findElement(By.css('[data-testid="chat-item-form-item-text-input"]'))
68+
69+
await ruleNameInput.clear()
70+
await ruleNameInput.sendKeys(ruleName)
71+
}
72+
73+
/**
74+
* Clicks the Create button in the rule creation form
75+
* @param webview The WebviewView instance
76+
*/
77+
export async function clickCreateButton(webview: WebviewView): Promise<void> {
78+
const sheetWrapper = await waitForElement(webview, By.css('[data-testid="sheet-wrapper"]'))
79+
const createButton = await sheetWrapper.findElement(By.xpath('.//button[@action-id="submit-create-rule"]'))
80+
81+
await webview.getDriver().wait(
82+
async () => {
83+
const isDisabled = await createButton.getAttribute('disabled')
84+
return isDisabled === null
85+
},
86+
5000,
87+
'Create button did not become enabled'
88+
)
89+
90+
await createButton.click()
3691
}
3792

3893
/**
39-
* Clicks the Create button in the rule creation dialog
40-
* @param webviewView The WebviewView instance
94+
* Clicks the Cancel button in the rule creation form
95+
* @param webview The WebviewView instance
4196
*/
42-
export async function clickCreateRule(webviewView: WebviewView): Promise<void> {
43-
const anotheroverlay = await waitForElement(webviewView, By.css('[data-testid="sheet-wrapper"]'))
44-
const buttonsContainer = await anotheroverlay.findElement(By.css('[data-testid="chat-item-buttons-wrapper"]'))
45-
const button = await buttonsContainer.findElements(By.css('[data-testid="chat-item-action-button"]'))
46-
await button[1].click()
97+
export async function clickCancelButton(webview: WebviewView): Promise<void> {
98+
const sheetWrapper = await waitForElement(webview, By.css('[data-testid="sheet-wrapper"]'))
99+
const cancelButton = await sheetWrapper.findElement(By.xpath('.//button[@action-id="cancel-create-rule"]'))
100+
await cancelButton.click()
47101
}
48102

49103
/**
50-
* Clicks the Cancel button in the rule creation dialog
51-
* @param webviewView The WebviewView instance
104+
* Creates a new rule with the specified name (complete workflow)
105+
* @param webview The WebviewView instance
106+
* @param ruleName The name of the rule to create
52107
*/
53-
export async function clickCancelRule(webviewView: WebviewView): Promise<void> {
54-
const anotheroverlay = await waitForElement(webviewView, By.css('[data-testid="sheet-wrapper"]'))
55-
const buttonsContainer = await anotheroverlay.findElement(By.css('[data-testid="chat-item-buttons-wrapper"]'))
56-
const button = await buttonsContainer.findElements(By.css('[data-testid="chat-item-action-button"]'))
57-
await button[0].click()
108+
export async function createNewRule(webview: WebviewView, ruleName: string): Promise<void> {
109+
await clickRulesButton(webview)
110+
await clickCreateNewRuleOption(webview)
111+
await enterRuleName(webview, ruleName)
112+
await clickCreateButton(webview)
58113
}

packages/amazonq/test/e2e_new/amazonq/tests/rules.test.ts

Lines changed: 20 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -3,56 +3,48 @@
33
* SPDX-License-Identifier: Apache-2.0
44
*/
55
import '../utils/setup'
6-
import {
7-
WebviewView,
8-
VSBrowser,
9-
DefaultTreeSection,
10-
ActivityBar,
11-
SideBarView,
12-
ViewContent,
13-
Workbench,
14-
} from 'vscode-extension-tester'
15-
import { closeAllTabs } from '../utils/cleanupUtils'
6+
import { WebviewView, ActivityBar, DefaultTreeSection, SideBarView, VSBrowser } from 'vscode-extension-tester'
167
import { testContext } from '../utils/testContext'
17-
import * as path from 'path'
18-
import { clickRulesButton, createRule } from '../helpers/rulesHelper'
8+
import { createNewRule } from '../helpers/rulesHelper'
9+
import path from 'path'
10+
import { sleep } from '../utils/generalUtils'
1911

2012
describe('Amazon Q Rules Functionality', function () {
2113
// this timeout is the general timeout for the entire test suite
2214
this.timeout(150000)
2315
let webviewView: WebviewView
24-
let tree: DefaultTreeSection
25-
let content: ViewContent
26-
let workbench: Workbench
2716

2817
before(async function () {
29-
// switch out of the webview (we assume that the last test was a webview test)
18+
// we assume that we've left off on a webview from a previous test
3019
webviewView = testContext.webviewView
3120
await webviewView.switchBack()
3221

33-
// in order to access rules you must have at least 1 folder
22+
// the "rules" menu won't show unless we have a folder open
3423
await VSBrowser.instance.openResources(path.join('..', 'utils', 'resources', 'testFolder'))
3524
;(await new ActivityBar().getViewControl('Explorer'))?.openView()
3625
const view = new SideBarView()
37-
content = view.getContent()
38-
tree = (await content.getSection('testFolder')) as DefaultTreeSection
26+
const content = view.getContent()
27+
const tree = (await content.getSection('testFolder')) as DefaultTreeSection
3928
await tree.openItem('test-folder')
40-
41-
// once the folder is opened, we switch back to the amazonQ webview
42-
workbench = testContext.workbench
29+
const workbench = testContext.workbench
4330
await workbench.executeCommand('Amazon Q: Open Chat')
31+
32+
// sleep is needed because the workbench needs some time to load
33+
await sleep(5000)
34+
const activityBar = new ActivityBar()
35+
const amazonQControl = await activityBar.getViewControl('Amazon Q')
36+
await amazonQControl?.openView()
37+
38+
// sleep is needed because it takes time to switch to the AmazonQ webview
39+
await sleep(5000)
4440
webviewView = new WebviewView()
4541
await webviewView.switchToFrame()
4642
testContext.webviewView = webviewView
4743
})
4844

49-
after(async function () {
50-
await closeAllTabs(webviewView)
51-
await VSBrowser.instance.quit()
52-
})
45+
after(async function () {})
5346

5447
it('Rules Option Test', async () => {
55-
await clickRulesButton(webviewView)
56-
await createRule(webviewView)
48+
await createNewRule(webviewView, 'testRule')
5749
})
5850
})

packages/amazonq/test/e2e_new/amazonq/utils/generalUtils.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,3 +187,23 @@ export async function findItemByText(items: WebElement[], text: string) {
187187
}
188188
throw new Error(`Item with text "${text}" not found`)
189189
}
190+
191+
/**
192+
* Prints the HTML content of a web element for debugging purposes
193+
* @param element The WebElement to print HTML for
194+
*/
195+
export async function printElementHTML(element: WebElement): Promise<void> {
196+
const htmlContent = await element.getAttribute('outerHTML')
197+
198+
const formattedHTML = htmlContent
199+
.replace(/></g, '>\n<')
200+
.replace(/\s+/g, ' ')
201+
.split('\n')
202+
.map((line) => line.trim())
203+
.filter((line) => line.length > 0)
204+
.join('\n')
205+
206+
console.log(`=== HTML CONTENT ===`)
207+
console.log(formattedHTML)
208+
console.log('=== END HTML ===')
209+
}

0 commit comments

Comments
 (0)