Skip to content

Commit dd2145c

Browse files
authored
feat(amazonq): Implement inline completion test (#7752)
## Change Implemented the inline completion test within inline.test.ts. This test suite does not need any special helper functions but I added a bunch of new functions in generalUtils.ts Note: I added the types@selenium-webdriver because we have started to interact with elements outside of the Amazon Q webview (ie. the text editor) --- - 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 9c36413 commit dd2145c

File tree

5 files changed

+132
-7
lines changed

5 files changed

+132
-7
lines changed

package-lock.json

Lines changed: 23 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@
8383
},
8484
"dependencies": {
8585
"@types/node": "^22.7.5",
86+
"@types/selenium-webdriver": "^4.1.28",
8687
"buffer": "^6.0.3",
8788
"jaro-winkler": "^0.2.8",
8889
"mocha": "^11.7.1",
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/*!
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
import '../utils/setup'
6+
import { Workbench, EditorView, InputBox, TextEditor, WebviewView, Key } from 'vscode-extension-tester'
7+
import { testContext } from '../utils/testContext'
8+
import { pressKey, createNewTextFile, writeToTextEditor } from '../utils/generalUtils'
9+
import assert from 'assert'
10+
11+
describe('Amazon Q Inline Completion / Chat Functionality', function () {
12+
// this timeout is the general timeout for the entire test suite
13+
this.timeout(150000)
14+
let workbench: Workbench
15+
let editorView: EditorView
16+
let textEditor: TextEditor
17+
let webviewView: WebviewView
18+
19+
before(async function () {
20+
webviewView = testContext.webviewView
21+
await webviewView.switchBack()
22+
workbench = testContext.workbench
23+
24+
editorView = new EditorView()
25+
testContext.editorView = editorView
26+
27+
textEditor = await createNewTextFile(workbench, editorView)
28+
})
29+
30+
it('Inline Test', async () => {
31+
await writeToTextEditor(textEditor, 'Select Me')
32+
const text = await textEditor.getText()
33+
assert.equal(text, 'Select Me')
34+
await textEditor.clearText()
35+
36+
await workbench.executeCommand('Amazon Q: Inline Chat')
37+
const input = new InputBox()
38+
await input.sendKeys('Write a simple sentece')
39+
await input.sendKeys(Key.ENTER)
40+
const driver = textEditor.getDriver()
41+
await pressKey(driver, 'ENTER')
42+
await pressKey(driver, 'TAB')
43+
})
44+
})

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

Lines changed: 60 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
33
* SPDX-License-Identifier: Apache-2.0
44
*/
5-
import { By, WebviewView, WebElement } from 'vscode-extension-tester'
6-
import { until } from 'selenium-webdriver'
5+
import { By, WebviewView, WebElement, EditorView, InputBox, Workbench, TextEditor, Key } from 'vscode-extension-tester'
6+
import { until, WebDriver } from 'selenium-webdriver'
77

88
/**
99
* General sleep function to wait for a specified amount of time
@@ -39,6 +39,35 @@ export async function waitForElements(webview: WebviewView, locator: By, timeout
3939
return await webview.findWebElements(locator)
4040
}
4141

42+
/**
43+
* Presses a single key globally
44+
* @param driver The WebDriver instance
45+
* @param key The key to press
46+
*/
47+
export async function pressKey(driver: WebDriver, key: keyof typeof Key): Promise<void> {
48+
await driver.actions().sendKeys(key).perform()
49+
}
50+
51+
/**
52+
* Presses a keyboard shortcut with modifier keys
53+
* @param driver The WebDriver instance
54+
* @param key The keys to press
55+
*
56+
* Examples:
57+
* Ctrl + C | await pressShortcut(driver, Key.CONTROL, 'c')
58+
* Ctrl + Shift + T | await pressShortcut(driver, Key.CONTROL, Key.SHIFT, 't')
59+
*/
60+
export async function pressShortcut(driver: WebDriver, ...keys: (keyof typeof Key)[]): Promise<void> {
61+
const actions = driver.actions()
62+
for (const key of keys) {
63+
actions.keyDown(key)
64+
}
65+
for (const key of keys.reverse()) {
66+
actions.keyUp(key)
67+
}
68+
await actions.perform()
69+
}
70+
4271
/**
4372
* Writes text to the chat input and optionally sends it
4473
* @param prompt The text to write in the chat input
@@ -104,6 +133,35 @@ export async function clearChat(webview: WebviewView): Promise<boolean> {
104133
}
105134
}
106135

136+
/**
137+
* Creates a new text file and returns the editor
138+
* @param workbench The Workbench instance
139+
* @returns Promise<TextEditor> The text editor for the new file
140+
*/
141+
export async function createNewTextFile(workbench: Workbench, editorView: EditorView): Promise<TextEditor> {
142+
await workbench.executeCommand('Create: New File...')
143+
await (await InputBox.create()).selectQuickPick('Text File')
144+
await sleep(1000)
145+
const editor = await editorView.openEditor('Untitled-1')
146+
if (!editor || !(editor instanceof TextEditor)) {
147+
throw new Error('Failed to open text editor')
148+
}
149+
const textEditor = editor as TextEditor
150+
return textEditor
151+
}
152+
153+
/**
154+
* Writes the given string in the textEditor in the next empty line
155+
* @param textEditor The TextEditor instance
156+
* @param text The text the user wants to type
157+
* @returns Promise<void>
158+
*/
159+
export async function writeToTextEditor(textEditor: TextEditor, text: string): Promise<void> {
160+
const currentLines = await textEditor.getNumberOfLines()
161+
const nextLine = currentLines + 1
162+
await textEditor.typeTextAt(nextLine, 1, text)
163+
}
164+
107165
/**
108166
* Finds an item based on the text
109167
* @param items WebElement array to search

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,12 @@
22
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
33
* SPDX-License-Identifier: Apache-2.0
44
*/
5-
import { Workbench, WebviewView } from 'vscode-extension-tester'
5+
import { Workbench, WebviewView, EditorView } from 'vscode-extension-tester'
66

77
export interface TestContext {
88
workbench: Workbench
99
webviewView: WebviewView
10+
editorView: EditorView
1011
}
1112

1213
export const testContext = new Proxy<TestContext>({} as TestContext, {
@@ -24,7 +25,8 @@ export const testContext = new Proxy<TestContext>({} as TestContext, {
2425
},
2526
})
2627

27-
export function initializeTestContext(workbench: Workbench, webviewView: WebviewView): void {
28+
export function initializeTestContext(workbench: Workbench, webviewView: WebviewView, editorView: EditorView): void {
2829
testContext.workbench = workbench
2930
testContext.webviewView = webviewView
31+
testContext.editorView = editorView
3032
}

0 commit comments

Comments
 (0)