Skip to content

Commit 50e27f5

Browse files
committed
tests: Introduce an e2e testing framework for Amazon Q
Problem: - Amazon Q has to be manually tested on each release for everything e2e because we don't have any automation Solution: - Introduce a testing framework for Amazon Q that will allow teams to easily test Amazon Q e2e. - Since VSCode doesn't have a built in way to do e2e tests against a webview, we instead hoist everything that would run inside of the webview into the current test instance, allowing us to test directly against the mynah UI instance programatically. This makes it so that we don't have to maintain any DOM elements + makes writing tests simple/easy to maintain while still testing all the same code flow e2e (minus the code that loads mynah ui into the webview)
1 parent 6bebba6 commit 50e27f5

File tree

17 files changed

+863
-57
lines changed

17 files changed

+863
-57
lines changed

docs/E2E_TESTING_ARCHITECTURE.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
### E2E Testing
2+
3+
This document describes the testing architecture specifically for more complicated E2E tests running the toolkits.
4+
5+
#### Amazon Q E2E Tests
6+
7+
Since VSCode does not have native support for writing E2E/UI tests for components occuring inside of a webview, we have taken a slightly different approach to write E2E tests for Amazon Q.
8+
9+
The E2E tests for Amazon Q follow the following flow: ![Amazon Q E2E flow](./images/amazon_q_e2e.png)
10+
11+
This means instead of running the E2E tests inside of the webview, we hoist the Mynah UI package into the test structure using JSDOM. This allows us to directly interface with Mynah UI allowing us to not rely on any DOM elements, making tests a lot easier to create and simple to maintain.
12+
13+
The downsides are that we technically aren't testing any of the actual contents of the webview to make sure things are behaving correctly. Instead, we are testing that when we programatically send a message to the UI that the Mynah UI <-> Amazon Q VSCode code interacts successfully.
14+
15+
With this approach, the follow things can be tested:
16+
17+
- Whether or not certain features show/not show depending on the status of the users auth
18+
- Run requests directly against the backend and see if we get results back
19+
- Clicking any follow up buttons (including examples)

docs/TESTPLAN.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ The test suite has the following categories of tests:
4141
- E2E Tests: **slow** tests
4242
- Live in `src/testE2E`
4343
- These tests are heavier than Integration tests.
44+
- Some E2E tests have a more complicated architecture, described in [E2E_TESTING](./E2E_TESTING_ARCHITECTURE.md)
4445

4546
## Test files
4647

docs/images/amazon_q_e2e.png

45.3 KB
Loading

package-lock.json

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

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4282,6 +4282,7 @@
42824282
"@types/fs-extra": "^9.0.11",
42834283
"@types/glob": "^8.1.0",
42844284
"@types/js-yaml": "^4.0.5",
4285+
"@types/jsdom": "^21.1.6",
42854286
"@types/lodash": "^4.14.180",
42864287
"@types/markdown-it": "^13.0.2",
42874288
"@types/mime-types": "^2.1.1",
@@ -4321,6 +4322,7 @@
43214322
"file-loader": "^6.2.0",
43224323
"husky": "^7.0.2",
43234324
"json-schema-to-typescript": "^13.1.1",
4325+
"jsdom": "^23.0.1",
43244326
"marked": "^11.1.1",
43254327
"mocha": "^10.1.0",
43264328
"mocha-junit-reporter": "^2.2.1",

src/amazonq/activation.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import { telemetry } from '../shared/telemetry/telemetry'
1818
import { focusAmazonQPanel } from '../auth/ui/vue/show'
1919

2020
export async function activate(context: ExtensionContext) {
21-
const appInitContext = new DefaultAmazonQAppInitContext()
21+
const appInitContext = DefaultAmazonQAppInitContext.instance
2222

2323
registerApps(appInitContext)
2424

src/amazonq/apps/initContext.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,12 @@ export class DefaultAmazonQAppInitContext implements AmazonQAppInitContext {
2121
private readonly webViewToAppsMessagePublishers: Map<TabType, MessagePublisher<any>> = new Map()
2222
public readonly onDidChangeAmazonQVisibility = new EventEmitter<boolean>()
2323

24+
static #instance: DefaultAmazonQAppInitContext
25+
26+
public static get instance() {
27+
return (this.#instance ??= new this())
28+
}
29+
2430
constructor() {}
2531

2632
registerWebViewToAppMessagePublisher(messagePublisher: MessagePublisher<any>, tabType: TabType): void {

src/amazonq/messages/messageListener.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,6 @@ export class MessageListener<T> {
99
constructor(private readonly eventEmitter: EventEmitter<T>) {}
1010

1111
public onMessage(listener: (e: T) => any) {
12-
this.eventEmitter.event(listener)
12+
return this.eventEmitter.event(listener)
1313
}
1414
}

src/amazonq/webview/generators/webViewContent.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,14 @@ export class WebViewContentGenerator {
2020
return `<!DOCTYPE html>
2121
<html>
2222
<head>
23+
<style>
24+
body.vscode-dark,
25+
body.vscode-high-contrast:not(.vscode-high-contrast-light) {
26+
--mynah-color-light: rgba(255, 255, 255, 0.05);
27+
--mynah-color-highlight: rgba(0, 137, 255, 0.2);
28+
--mynah-color-highlight-text: rgba(0, 137, 255, 1);
29+
}
30+
</style>
2331
<meta http-equiv="Content-Security-Policy" content="${contentPolicy}">
2432
<title>Amazon Q (Preview)</title>
2533
${await this.generateJS(extensionURI, webView)}

src/amazonq/webview/ui/main.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
*/
55
import { Connector } from './connector'
66
import { ChatItem, ChatItemType, MynahUI, MynahUIDataModel, NotificationType } from '@aws/mynah-ui'
7-
import './styles/dark.scss'
87
import { ChatPrompt } from '@aws/mynah-ui/dist/static'
98
import { TabsStorage, TabType } from './storages/tabsStorage'
109
import { WelcomeFollowupType } from './apps/amazonqCommonsConnector'
@@ -369,4 +368,9 @@ export const createMynahUI = (ideApi: any, featureDevInitEnabled: boolean, gumby
369368
isFeatureDevEnabled,
370369
isGumbyEnabled,
371370
})
371+
372+
return {
373+
mynahUI,
374+
messageReceiver: connector.handleMessageReceive,
375+
}
372376
}

0 commit comments

Comments
 (0)