33 * SPDX-License-Identifier: Apache-2.0
44 */
55import { WebviewView , By } from 'vscode-extension-tester'
6- import { sleep , waitForElement } from '../utils/generalUtils'
6+ import { waitForElement } from '../utils/generalUtils'
77
8+ /**
9+ * Clicks the tools to get to the MCP server overlay
10+ * @param webviewView The WebviewView instance
11+ * @returns Promise<boolean> True if tools button was found and clicked, false otherwise
12+ */
813export async function clickToolsButton ( webviewView : WebviewView ) : Promise < boolean > {
914 try {
10- const menuList = await waitForElement ( webviewView , By . css ( '.mynah-nav-tabs-wrapper.mynah-ui-clickable-item' ) )
11- const menuListItem = await menuList . findElement ( By . css ( '.mynah-nav-tabs-bar-buttons-wrapper' ) )
12- const menuListItems = await menuListItem . findElements (
15+ const navWrapper = await waitForElement ( webviewView , By . css ( '.mynah-nav-tabs-wrapper.mynah-ui-clickable-item' ) )
16+ const buttonsWrapper = await navWrapper . findElement ( By . css ( '.mynah-nav-tabs-bar-buttons-wrapper' ) )
17+ const buttons = await buttonsWrapper . findElements (
1318 By . css ( '.mynah-button.mynah-button-secondary.fill-state-always.mynah-ui-clickable-item' )
1419 )
15- for ( const item of menuListItems ) {
16- const icon = await item . findElement ( By . css ( 'i.mynah-ui-icon.mynah-ui-icon-tools' ) )
20+ for ( const button of buttons ) {
21+ const icon = await button . findElement ( By . css ( 'i.mynah-ui-icon.mynah-ui-icon-tools' ) )
1722 if ( icon ) {
18- await item . click ( )
23+ await button . click ( )
24+ await webviewView . getDriver ( ) . actions ( ) . move ( { x : 0 , y : 0 } ) . perform ( )
1925 return true
2026 }
2127 }
@@ -27,39 +33,245 @@ export async function clickToolsButton(webviewView: WebviewView): Promise<boolea
2733 }
2834}
2935
30- export async function clickMCPCloseButton ( webviewView : WebviewView ) : Promise < boolean > {
36+ /**
37+ * Clicks the add button in the MCP server configuration panel
38+ * @param webviewView The WebviewView instance
39+ * @returns Promise<boolean> True if add button was found and clicked, false otherwise
40+ */
41+ export async function clickMCPAddButton ( webviewView : WebviewView ) : Promise < boolean > {
3142 try {
32- const menuList = await waitForElement ( webviewView , By . id ( 'mynah-sheet-wrapper' ) )
33- console . log ( 'THIS WORKS 1' )
34- sleep ( 5000 )
35- const menuu = await menuList . findElement ( By . css ( '.mynah-sheet-header' ) )
36- console . log ( 'THIS WORKS 2' )
37- sleep ( 5000 )
38- const menuListItems = await menuu . findElement (
39- By . css ( '.mynah-button.mynah-button-secondary.fill-state-always.mynah-ui-clickable-item' )
43+ const sheetWrapper = await waitForElement ( webviewView , By . id ( 'mynah-sheet-wrapper' ) )
44+ const header = await sheetWrapper . findElement ( By . css ( '.mynah-sheet-header' ) )
45+ const actionsContainer = await header . findElement ( By . css ( '.mynah-sheet-header-actions-container' ) )
46+ const addButton = await actionsContainer . findElement ( By . css ( 'button:has(i.mynah-ui-icon-plus)' ) )
47+ await addButton . click ( )
48+ return true
49+ } catch ( e ) {
50+ console . error ( 'Error clicking the MCP add button:' , e )
51+ return false
52+ }
53+ }
54+
55+ /**
56+ * Configures an MCP server with the provided settings
57+ * @param webviewView The WebviewView instance
58+ * @param config Configuration object with optional parameters
59+ * @returns Promise<boolean> True if configuration was successful, false otherwise
60+ * Note: I have the default settings in the config variable
61+ */
62+ interface MCPServerConfig {
63+ scope ?: 'global' | 'workspace'
64+ name ?: string
65+ transport ?: number
66+ command ?: string
67+ args ?: string [ ]
68+ nameEnvironmentVariable ?: string
69+ valueEnvironmentVariable ?: string
70+ timeout ?: number
71+ }
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
83+ 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 ]
170+
171+ const nameContainer = items [ 6 ]
172+ const inputName = nameContainer . findElement ( By . css ( '.mynah-form-input' ) )
173+ await inputName . sendKeys ( nameEnvironmentVariable )
174+
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
201+ }
202+ }
203+ return true
204+ } catch ( e ) {
205+ console . log ( 'Error configuring the MCP Server' )
206+ return false
207+ }
208+ }
209+
210+ export async function saveMCPServerConfiguration ( webviewView : WebviewView ) : Promise < boolean > {
211+ try {
212+ const sheetWrapper = await waitForElement ( webviewView , By . id ( 'mynah-sheet-wrapper' ) )
213+ const body = await sheetWrapper . findElement ( By . css ( '.mynah-sheet-body' ) )
214+ const filterActions = await body . findElement ( By . css ( '.mynah-detailed-list-filter-actions-wrapper' ) )
215+ const saveButton = await filterActions . findElement (
216+ By . css ( '.mynah-button.fill-state-always.status-primary.mynah-ui-clickable-item' )
40217 )
41- console . log ( 'THIS WORKS 3' )
42- sleep ( 5000 )
43- await menuListItems . click ( )
44- console . log ( 'THIS WORKS 4' )
45- sleep ( 5000 )
46- // for (const item of menuListItems) {
47- // const icon = await item.findElement(By.css('i.mynah-ui-icon.mynah-ui-icon-cancel'))
48- // console.log('THIS WORKS 4')
49- // if (icon) {
50- // await webviewView.getDriver().executeScript('arguments[0].click()', item)
51- // sleep(5000)
52- // return true
53- // }
54- // }
55- // console.log('I DID NOT ACTUALLY CLICK THE CLOSE BUTTON')
218+ await saveButton . click ( )
56219 return true
57220 } catch ( e ) {
58- console . error ( 'Error closing the MCP overlay :' , e )
221+ console . error ( 'Error saving the MCP server configuration :' , e )
59222 return false
60223 }
61224}
62225
63- export async function dismissOverlay ( webviewView : WebviewView ) : Promise < void > {
64- await webviewView . getDriver ( ) . executeScript ( 'document.elementFromPoint(200, 200).click()' )
226+ export async function cancelMCPServerConfiguration ( webviewView : WebviewView ) : Promise < boolean > {
227+ try {
228+ const sheetWrapper = await waitForElement ( webviewView , By . id ( 'mynah-sheet-wrapper' ) )
229+ const body = await sheetWrapper . findElement ( By . css ( '.mynah-sheet-body' ) )
230+ const filterActions = await body . findElement ( By . css ( '.mynah-detailed-list-filter-actions-wrapper' ) )
231+ const saveButton = await filterActions . findElement (
232+ By . css ( '.mynah-button.mynah-button-secondary.mynah-button-border.fill-state-always.mynah-ui-clickable-item' )
233+ )
234+ await saveButton . click ( )
235+ return true
236+ } catch ( e ) {
237+ console . error ( 'Error saving the MCP server configuration:' , e )
238+ return false
239+ }
240+ }
241+
242+ /**
243+ * Clicks the refresh button in the MCP server configuration panel
244+ * @param webviewView The WebviewView instance
245+ * @returns Promise<boolean> True if refresh button was found and clicked, false otherwise
246+ */
247+ export async function clickMCPRefreshButton ( webviewView : WebviewView ) : Promise < boolean > {
248+ try {
249+ const sheetWrapper = await waitForElement ( webviewView , By . id ( 'mynah-sheet-wrapper' ) )
250+ const header = await sheetWrapper . findElement ( By . css ( '.mynah-sheet-header' ) )
251+ const actionsContainer = await header . findElement ( By . css ( '.mynah-sheet-header-actions-container' ) )
252+ const refreshButton = await actionsContainer . findElement ( By . css ( 'button:has(i.mynah-ui-icon-refresh)' ) )
253+ await refreshButton . click ( )
254+ return true
255+ } catch ( e ) {
256+ console . error ( 'Error clicking the MCP refresh button:' , e )
257+ return false
258+ }
259+ }
260+
261+ /**
262+ * Clicks the close/cancel button in the MCP server configuration panel
263+ * @param webviewView The WebviewView instance
264+ * @returns Promise<boolean> True if close button was found and clicked, false otherwise
265+ */
266+ export async function clickMCPCloseButton ( webviewView : WebviewView ) : Promise < boolean > {
267+ try {
268+ const sheetWrapper = await waitForElement ( webviewView , By . id ( 'mynah-sheet-wrapper' ) )
269+ const header = await sheetWrapper . findElement ( By . css ( '.mynah-sheet-header' ) )
270+ const cancelButton = await header . findElement ( By . css ( 'button:has(i.mynah-ui-icon-cancel)' ) )
271+ await webviewView . getDriver ( ) . executeScript ( 'arguments[0].click()' , cancelButton )
272+ return true
273+ } catch ( e ) {
274+ console . error ( 'Error closing the MCP overlay:' , e )
275+ return false
276+ }
65277}
0 commit comments