22 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
33 * SPDX-License-Identifier: Apache-2.0
44 */
5- import { WebviewView , By } from 'vscode-extension-tester'
5+ import { WebviewView , By , WebElement } from 'vscode-extension-tester'
66import { waitForElement } from '../utils/generalUtils'
77
88/**
@@ -57,7 +57,7 @@ export async function clickMCPAddButton(webviewView: WebviewView): Promise<boole
5757 * @param webviewView The WebviewView instance
5858 * @param config Configuration object with optional parameters
5959 * @returns Promise<boolean> True if configuration was successful, false otherwise
60- * Note: I have the default settings in the config variable
60+ * Note: I have the default settings in the defaultConfig
6161 */
6262interface MCPServerConfig {
6363 scope ?: 'global' | 'workspace'
@@ -69,135 +69,166 @@ interface MCPServerConfig {
6969 valueEnvironmentVariable ?: string
7070 timeout ?: number
7171}
72- export async function configureMCPServer ( webviewView : WebviewView , config : MCPServerConfig = { } ) : Promise < boolean > {
73- const {
74- scope = 'workspace' ,
75- name = 'aws-documentation' ,
76- transport = 0 ,
77- command = 'uvx' ,
78- args = [ 'awslabs.aws-documentation-mcp-server@latest' ] ,
79- nameEnvironmentVariable = 'hi' ,
80- valueEnvironmentVariable = 'hi' ,
81- timeout = 0 ,
82- } = config
72+
73+ const defaultConfig : MCPServerConfig = {
74+ scope : 'global' ,
75+ name : 'aws-documentation' ,
76+ transport : 0 ,
77+ command : 'uvx' ,
78+ args : [ 'awslabs.aws-documentation-mcp-server@latest' ] ,
79+ nameEnvironmentVariable : 'hi' ,
80+ valueEnvironmentVariable : 'hi' ,
81+ timeout : 0 ,
82+ }
83+
84+ const formItemsMap = {
85+ SCOPE : 0 ,
86+ NAME : 1 ,
87+ TRANSPORT : 2 ,
88+ COMMAND : 3 ,
89+ ARGS : 4 ,
90+ ENV_VARS : 6 ,
91+ TIMEOUT : 9 ,
92+ } as const
93+
94+ type McpFormItem = keyof typeof formItemsMap
95+
96+ async function selectScope ( container : WebElement , scope : string ) {
97+ try {
98+ const a = await container . findElements ( By . css ( '.mynah-form-input-radio-label.mynah-ui-clickable-item' ) )
99+ if ( scope === 'global' ) {
100+ const b = a [ 0 ]
101+ await b . click ( )
102+ } else {
103+ const b = a [ 1 ]
104+ await b . click ( )
105+ }
106+ } catch ( e ) {
107+ console . error ( 'Error selecting the scope:' , e )
108+ throw e
109+ }
110+ }
111+
112+ async function inputName ( container : WebElement , name : string ) {
113+ try {
114+ const input = container . findElement ( By . css ( '.mynah-form-input' ) )
115+ await input . sendKeys ( name )
116+ } catch ( e ) {
117+ console . error ( 'Error inputing the name:' , e )
118+ throw e
119+ }
120+ }
121+
122+ async function selectTransport ( container : WebElement , transport : number ) {
123+ try {
124+ const selectElement = await container . findElement ( By . css ( 'select' ) )
125+ const options = await selectElement . findElements ( By . css ( 'option' ) )
126+ const optionIndex = transport
127+ await options [ optionIndex ] . click ( )
128+ } catch ( e ) {
129+ console . error ( 'Error selecting the transport:' , e )
130+ throw e
131+ }
132+ }
133+
134+ async function inputCommand ( container : WebElement , command : string ) {
135+ try {
136+ const input = container . findElement ( By . css ( '.mynah-form-input' ) )
137+ await input . sendKeys ( command )
138+ } catch ( e ) {
139+ console . error ( 'Error inputing the command:' , e )
140+ throw e
141+ }
142+ }
143+
144+ async function inputArgs ( container : WebElement , args : string [ ] ) {
83145 try {
84- const a = await waitForElement ( webviewView , By . id ( 'mynah-sheet-wrapper' ) )
85- const b = await a . findElement ( By . css ( '.mynah-sheet-body' ) )
86- const c = await b . findElement ( By . css ( '.mynah-detailed-list-filters-wrapper' ) )
87- const d = await c . findElement ( By . css ( '.mynah-chat-item-form-items-container' ) )
88- const items = await d . findElements ( By . css ( '.mynah-form-input-wrapper' ) )
89- console . log ( 'THERE ARE X ITEMS:' , items . length ) // returns 10 items
90- for ( let i = 0 ; i < items . length ; i ++ ) {
91- switch ( i ) {
92- // select the scope
93- case 0 :
94- try {
95- const scopeContainer = items [ i ]
96- const a = await scopeContainer . findElements (
97- By . css ( '.mynah-form-input-radio-label.mynah-ui-clickable-item' )
98- )
99- if ( scope === 'global' ) {
100- const b = a [ 0 ]
101- await b . click ( )
102- } else {
103- const b = a [ 1 ]
104- await b . click ( )
105- }
106- } catch ( e ) {
107- console . error ( 'Error in case 0:' , e )
108- throw e
109- }
110- break
111- // input the name
112- case 1 :
113- try {
114- const scopeContainer = items [ i ]
115- const input = scopeContainer . findElement ( By . css ( '.mynah-form-input' ) )
116- await input . sendKeys ( name )
117- } catch ( e ) {
118- console . error ( 'Error in case 1:' , e )
119- throw e
120- }
121- break
122- // select the transport (must know the index of your selection)
123- case 2 :
124- try {
125- const scopeContainer = items [ i ]
126- const selectElement = await scopeContainer . findElement ( By . css ( 'select' ) )
127- const options = await selectElement . findElements ( By . css ( 'option' ) )
128- const optionIndex = transport
129- await options [ optionIndex ] . click ( )
130- } catch ( e ) {
131- console . error ( 'Error in case 2:' , e )
132- throw e
133- }
134- break
135- // type the command
136- case 3 :
137- try {
138- const scopeContainer = items [ i ]
139- const input = scopeContainer . findElement ( By . css ( '.mynah-form-input' ) )
140- await input . sendKeys ( command )
141- } catch ( e ) {
142- console . error ( 'Error in case 3:' , e )
143- throw e
144- }
145- break
146- // add arguments (NOTE: I AM PURPOSELY SKIPPING CASE 5)
147- case 4 :
148- try {
149- const scopeContainer = items [ i ]
150- const input = scopeContainer . findElement ( By . css ( '.mynah-form-input' ) )
151- const addButton = scopeContainer . findElement (
152- By . css (
153- '.mynah-button.mynah-button-secondary.fill-state-always.mynah-form-item-list-row-remove-button.mynah-ui-clickable-item'
154- )
155- )
156- for ( let i = 0 ; i < args . length ; i ++ ) {
157- await input . sendKeys ( args [ i ] )
158- await addButton . click ( )
159- }
160- } catch ( e ) {
161- console . error ( 'Error in case 5:' , e )
162- throw e
163- }
164- break
165- // THE ISSUE IS THAT CASE 5 ENCOMPASSES ALL THE HTML ELEMENTS NEEDED
166- case 5 :
167- try {
168- if ( nameEnvironmentVariable && valueEnvironmentVariable ) {
169- const scopeContainer = items [ i ]
146+ const input = container . findElement ( By . css ( '.mynah-form-input' ) )
147+ const addButton = container . findElement (
148+ By . css (
149+ '.mynah-button.mynah-button-secondary.fill-state-always.mynah-form-item-list-row-remove-button.mynah-ui-clickable-item'
150+ )
151+ )
152+ for ( let i = 0 ; i < args . length ; i ++ ) {
153+ await input . sendKeys ( args [ i ] )
154+ await addButton . click ( )
155+ }
156+ } catch ( e ) {
157+ console . error ( 'Error inputing the arguments:' , e )
158+ throw e
159+ }
160+ }
170161
171- const nameContainer = items [ 6 ]
172- const inputName = nameContainer . findElement ( By . css ( '.mynah-form-input' ) )
173- await inputName . sendKeys ( nameEnvironmentVariable )
162+ async function inputEnvironmentVariables (
163+ container : WebElement ,
164+ nameEnvironmentVariable ?: string ,
165+ valueEnvironmentVariable ?: string
166+ ) {
167+ try {
168+ if ( nameEnvironmentVariable && valueEnvironmentVariable ) {
169+ const a = await container . findElements ( By . css ( '.mynah-form-input' ) )
170+ await a [ 0 ] . sendKeys ( nameEnvironmentVariable )
171+ await a [ 1 ] . sendKeys ( valueEnvironmentVariable )
172+ const addButton = await container . findElement ( By . css ( '.mynah-form-item-list-add-button' ) )
173+ await addButton . click ( )
174+ } else {
175+ console . log ( 'No environmental variables for this configuration' )
176+ }
177+ } catch ( e ) {
178+ console . error ( 'Error inputing the environment variables:' , e )
179+ throw e
180+ }
181+ }
182+
183+ async function inputTimeout ( container : WebElement , timeout : number ) {
184+ try {
185+ const input = container . findElement ( By . css ( '.mynah-form-input' ) )
186+ await input . clear ( )
187+ await input . sendKeys ( timeout )
188+ } catch ( e ) {
189+ console . error ( 'Error inputing the timeout:' , e )
190+ throw e
191+ }
192+ }
193+
194+ async function processFormItems ( mcpFormItem : McpFormItem , container : WebElement , config : MCPServerConfig ) {
195+ switch ( mcpFormItem ) {
196+ case 'SCOPE' :
197+ await selectScope ( container , config . scope ! )
198+ break
199+ case 'NAME' :
200+ await inputName ( container , config . name ! )
201+ break
202+ case 'TRANSPORT' :
203+ await selectTransport ( container , config . transport ! )
204+ break
205+ case 'COMMAND' :
206+ await inputCommand ( container , config . command ! )
207+ break
208+ case 'ARGS' :
209+ await inputArgs ( container , config . args ! )
210+ break
211+ case 'ENV_VARS' :
212+ await inputEnvironmentVariables ( container , config . nameEnvironmentVariable , config . valueEnvironmentVariable )
213+ break
214+ case 'TIMEOUT' :
215+ await inputTimeout ( container , config . timeout ! )
216+ break
217+ }
218+ }
219+
220+ export async function configureMCPServer ( webviewView : WebviewView , config : MCPServerConfig = { } ) : Promise < boolean > {
221+ const mergedConfig = { ...defaultConfig , ...config }
222+ try {
223+ const sheetWrapper = await waitForElement ( webviewView , By . id ( 'mynah-sheet-wrapper' ) )
224+ const sheetBody = await sheetWrapper . findElement ( By . css ( '.mynah-sheet-body' ) )
225+ const filtersWrapper = await sheetBody . findElement ( By . css ( '.mynah-detailed-list-filters-wrapper' ) )
226+ const formContainer = await filtersWrapper . findElement ( By . css ( '.mynah-chat-item-form-items-container' ) )
227+ const items = await formContainer . findElements ( By . css ( '.mynah-form-input-wrapper' ) )
174228
175- const valueContainer = items [ 7 ]
176- const inputValue = valueContainer . findElement ( By . css ( '.mynah-form-input' ) )
177- await inputValue . sendKeys ( valueEnvironmentVariable )
178- const addButton = scopeContainer . findElement (
179- By . css (
180- '.mynah-button.mynah-button-secondary.fill-state-always.mynah-form-item-list-row-remove-button.mynah-ui-clickable-item'
181- )
182- )
183- await addButton . click ( )
184- }
185- } catch ( e ) {
186- console . error ( 'Error in case 5:' , e )
187- throw e
188- }
189- break
190- // this timeout container goes to the environment variable
191- case 9 :
192- try {
193- const scopeContainer = items [ i ]
194- const input = scopeContainer . findElement ( By . css ( '.mynah-form-input' ) )
195- await input . sendKeys ( timeout )
196- } catch ( e ) {
197- console . error ( 'Error in case 8:' , e )
198- throw e
199- }
200- break
229+ for ( const [ formItem , index ] of Object . entries ( formItemsMap ) ) {
230+ if ( index < items . length ) {
231+ await processFormItems ( formItem as McpFormItem , items [ index ] , mergedConfig )
201232 }
202233 }
203234 return true
0 commit comments