@@ -8,33 +8,128 @@ import assert from 'node:assert';
88import { describe , it } from 'node:test' ;
99
1010import { listPages , navigatePage , selectPage } from '../../src/tools/pages.js' ;
11- import { withMcpContext } from '../utils.js' ;
11+ import { html , withMcpContext } from '../utils.js' ;
12+ import { executeWebMcpTool } from '../../src/tools/webmcp.js' ;
13+ import { ParsedArguments } from '../../src/bin/chrome-devtools-mcp-cli-options.js' ;
14+ import { McpPage } from '../../src/McpPage.js' ;
1215
1316describe ( 'webmcp' , ( ) => {
14- it ( 'list webmcp tools in navigate_page response' , async ( ) => {
15- await withMcpContext ( async ( response , context ) => {
16- await navigatePage . handler (
17- { params : { url : 'about:blank' } , page : context . getSelectedMcpPage ( ) } ,
18- response ,
19- context ,
20- ) ;
21- assert . ok ( response . listWebMcpTools ) ;
17+ describe ( 'list_webmcp_tools' , ( ) => {
18+ it ( 'list webmcp tools in navigate_page response' , async ( ) => {
19+ await withMcpContext ( async ( response , context ) => {
20+ await navigatePage . handler (
21+ { params : { url : 'about:blank' } , page : context . getSelectedMcpPage ( ) } ,
22+ response ,
23+ context ,
24+ ) ;
25+ assert . ok ( response . listWebMcpTools ) ;
26+ } ) ;
27+ } ) ;
28+
29+ it ( 'list webmcp tools in list_pages response' , async ( ) => {
30+ await withMcpContext ( async ( response , context ) => {
31+ await listPages ( ) . handler ( { params : { } } , response , context ) ;
32+ assert . ok ( response . listWebMcpTools ) ;
33+ } ) ;
2234 } ) ;
23- } ) ;
2435
25- it ( 'list webmcp tools in list_pages response' , async ( ) => {
26- await withMcpContext ( async ( response , context ) => {
27- await listPages ( ) . handler ( { params : { } } , response , context ) ;
28- assert . ok ( response . listWebMcpTools ) ;
36+ it ( 'list webmcp tools in select_page response' , async ( ) => {
37+ await withMcpContext ( async ( response , context ) => {
38+ const pageId =
39+ context . getPageId ( context . getSelectedMcpPage ( ) . pptrPage ) ?? 1 ;
40+ await selectPage . handler ( { params : { pageId} } , response , context ) ;
41+ assert . ok ( response . listWebMcpTools ) ;
42+ } ) ;
2943 } ) ;
3044 } ) ;
3145
32- it ( 'list webmcp tools in select_page response' , async ( ) => {
33- await withMcpContext ( async ( response , context ) => {
34- const pageId =
35- context . getPageId ( context . getSelectedMcpPage ( ) . pptrPage ) ?? 1 ;
36- await selectPage . handler ( { params : { pageId} } , response , context ) ;
37- assert . ok ( response . listWebMcpTools ) ;
46+ describe ( 'execute_webmcp_tool' , ( ) => {
47+ async function setupWebMcpTool ( page : McpPage ) {
48+ await page . pptrPage . setContent (
49+ html `< form
50+ toolname ="test_tool "
51+ tooldescription ="A test tool "
52+ toolautosubmit
53+ > </ form
54+ > < script >
55+ document . querySelector ( 'form' ) . onsubmit = event => {
56+ event . preventDefault ( ) ;
57+ event . respondWith ( 'hello' ) ;
58+ } ;
59+ </ script > ` ,
60+ ) ;
61+ }
62+
63+ it ( 'executes a tool successfully' , async ( ) => {
64+ await withMcpContext (
65+ async ( response , context ) => {
66+ const page = context . getSelectedMcpPage ( ) ;
67+ await setupWebMcpTool ( page ) ;
68+
69+ await executeWebMcpTool . handler (
70+ { params : { toolName : 'test_tool' , input : JSON . stringify ( { } ) } , page} ,
71+ response ,
72+ context ,
73+ ) ;
74+ assert . strictEqual (
75+ response . responseLines [ 0 ] ,
76+ JSON . stringify ( { status : 'Completed' , output : 'hello' } , null , 2 ) ,
77+ ) ;
78+ } ,
79+ {
80+ args : [ '--enable-features=WebMCPTesting,DevToolsWebMCPSupport' ] ,
81+ executablePath :
82+ '/Applications/Google Chrome Canary.app/Contents/MacOS/Google Chrome Canary' ,
83+ } ,
84+ { experimentalWebmcp : true } as ParsedArguments ,
85+ ) ;
86+ } ) ;
87+
88+ it ( 'throws if tool is not found' , async ( ) => {
89+ await withMcpContext (
90+ async ( response , context ) => {
91+ await assert . rejects (
92+ async ( ) => {
93+ await executeWebMcpTool . handler (
94+ {
95+ params : { toolName : 'missing-tool' , input : JSON . stringify ( { } ) } ,
96+ page : context . getSelectedMcpPage ( ) ,
97+ } ,
98+ response ,
99+ context ,
100+ ) ;
101+ } ,
102+ { message : / T o o l m i s s i n g - t o o l n o t f o u n d / } ,
103+ ) ;
104+ } ,
105+ { args : [ '--enable-features=WebMCPTesting,DevToolsWebMCPSupport' ] } ,
106+ { experimentalWebmcp : true } as ParsedArguments ,
107+ ) ;
108+ } ) ;
109+
110+ it ( 'throws if input is invalid' , async ( ) => {
111+ await withMcpContext (
112+ async ( response , context ) => {
113+ await assert . rejects (
114+ async ( ) => {
115+ const page = context . getSelectedMcpPage ( ) ;
116+ await setupWebMcpTool ( page ) ;
117+
118+ await executeWebMcpTool . handler (
119+ { params : { toolName : 'test_tool' , input : 'invalid' } , page} ,
120+ response ,
121+ context ,
122+ ) ;
123+ } ,
124+ {
125+ message :
126+ / F a i l e d t o p a r s e i n p u t a s J S O N : U n e x p e c t e d t o k e n ' i ' , " i n v a l i d " i s n o t v a l i d J S O N / ,
127+ } ,
128+ ) ;
129+ } ,
130+ { args : [ '--enable-features=WebMCPTesting,DevToolsWebMCPSupport' ] } ,
131+ { experimentalWebmcp : true } as ParsedArguments ,
132+ ) ;
38133 } ) ;
39134 } ) ;
40135} ) ;
0 commit comments