2025-03-21 10:58:58 -07:00
/ * *
* Copyright ( c ) Microsoft Corporation .
*
* Licensed under the Apache License , Version 2.0 ( the "License" ) ;
* you may not use this file except in compliance with the License .
* You may obtain a copy of the License at
*
* http : //www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing , software
* distributed under the License is distributed on an "AS IS" BASIS ,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND , either express or implied .
* See the License for the specific language governing permissions and
* limitations under the License .
* /
2025-03-27 20:49:57 +01:00
import fs from 'fs/promises' ;
2025-03-21 10:58:58 -07:00
import { test , expect } from './fixtures' ;
2025-04-04 17:14:30 -07:00
test ( 'browser_navigate' , async ( { client } ) = > {
2025-03-27 16:50:43 -07:00
expect ( await client . callTool ( {
name : 'browser_navigate' ,
arguments : {
url : 'data:text/html,<html><title>Title</title><body>Hello, world!</body></html>' ,
} ,
} ) ) . toHaveTextContent ( `
2025-04-15 12:54:45 -07:00
- Ran code :
\ ` \` \` js
// Navigate to data:text/html,<html><title>Title</title><body>Hello, world!</body></html>
await page . goto ( 'data:text/html,<html><title>Title</title><body>Hello, world!</body></html>' ) ;
\ ` \` \`
2025-04-15 19:55:20 +02:00
2025-03-21 10:58:58 -07:00
- Page URL : data : text / html , < html > < title > Title < / title > < body > Hello , world ! < / body > < / html >
- Page Title : Title
- Page Snapshot
\ ` \` \` yaml
2025-04-01 23:47:53 +02:00
- text : Hello , world !
2025-03-21 10:58:58 -07:00
\ ` \` \`
2025-03-27 23:47:15 +01:00
`
2025-03-27 16:50:43 -07:00
) ;
2025-03-21 10:58:58 -07:00
} ) ;
2025-04-04 17:14:30 -07:00
test ( 'browser_click' , async ( { client } ) = > {
2025-03-27 16:50:43 -07:00
await client . callTool ( {
name : 'browser_navigate' ,
arguments : {
url : 'data:text/html,<html><title>Title</title><button>Submit</button></html>' ,
} ,
} ) ;
2025-03-21 10:58:58 -07:00
2025-03-27 16:50:43 -07:00
expect ( await client . callTool ( {
name : 'browser_click' ,
arguments : {
element : 'Submit button' ,
2025-04-01 23:47:53 +02:00
ref : 's1e3' ,
2025-03-27 16:50:43 -07:00
} ,
2025-04-15 19:55:20 +02:00
} ) ) . toHaveTextContent ( `
2025-04-15 12:54:45 -07:00
- Ran code :
\ ` \` \` js
// Click Submit button
await page . getByRole ( 'button' , { name : 'Submit' } ) . click ( ) ;
\ ` \` \`
2025-03-21 10:58:58 -07:00
- Page URL : data : text / html , < html > < title > Title < / title > < button > Submit < / button > < / html >
- Page Title : Title
- Page Snapshot
\ ` \` \` yaml
2025-04-01 23:47:53 +02:00
- button "Submit" [ ref = s2e3 ]
2025-03-21 10:58:58 -07:00
\ ` \` \`
2025-03-27 16:50:43 -07:00
` );
2025-03-21 10:58:58 -07:00
} ) ;
2025-03-25 13:05:28 -07:00
2025-03-26 13:53:56 +09:00
2025-04-04 17:14:30 -07:00
test ( 'browser_select_option' , async ( { client } ) = > {
2025-03-27 16:50:43 -07:00
await client . callTool ( {
name : 'browser_navigate' ,
arguments : {
2025-03-27 23:47:15 +01:00
url : 'data:text/html,<html><title>Title</title><select><option value="foo">Foo</option><option value="bar">Bar</option></select></html>' ,
2025-03-27 16:50:43 -07:00
} ,
} ) ;
2025-03-26 13:53:56 +09:00
2025-03-27 16:50:43 -07:00
expect ( await client . callTool ( {
name : 'browser_select_option' ,
arguments : {
element : 'Select' ,
2025-04-01 23:47:53 +02:00
ref : 's1e3' ,
2025-03-27 16:50:43 -07:00
values : [ 'bar' ] ,
} ,
2025-04-15 19:55:20 +02:00
} ) ) . toHaveTextContent ( `
2025-04-15 12:54:45 -07:00
- Ran code :
\ ` \` \` js
// Select options [bar] in Select
await page . getByRole ( 'combobox' ) . selectOption ( [ 'bar' ] ) ;
\ ` \` \`
2025-03-26 13:53:56 +09:00
- Page URL : data : text / html , < html > < title > Title < / title > < select > < option value = "foo" > Foo < / option > < option value = "bar" > Bar < / option > < / select > < / html >
- Page Title : Title
- Page Snapshot
\ ` \` \` yaml
2025-04-01 23:47:53 +02:00
- combobox [ ref = s2e3 ] :
- option "Foo" [ ref = s2e4 ]
- option "Bar" [ selected ] [ ref = s2e5 ]
2025-03-26 13:53:56 +09:00
\ ` \` \`
2025-03-27 16:50:43 -07:00
` );
} ) ;
2025-03-26 13:53:56 +09:00
2025-04-04 17:14:30 -07:00
test ( 'browser_select_option (multiple)' , async ( { client } ) = > {
2025-03-27 16:50:43 -07:00
await client . callTool ( {
name : 'browser_navigate' ,
arguments : {
2025-03-27 23:47:15 +01:00
url : 'data:text/html,<html><title>Title</title><select multiple><option value="foo">Foo</option><option value="bar">Bar</option><option value="baz">Baz</option></select></html>' ,
2025-03-27 16:50:43 -07:00
} ,
} ) ;
2025-03-26 13:53:56 +09:00
2025-03-27 16:50:43 -07:00
expect ( await client . callTool ( {
name : 'browser_select_option' ,
arguments : {
element : 'Select' ,
2025-04-01 23:47:53 +02:00
ref : 's1e3' ,
2025-03-27 16:50:43 -07:00
values : [ 'bar' , 'baz' ] ,
} ,
2025-04-15 19:55:20 +02:00
} ) ) . toHaveTextContent ( `
2025-04-15 12:54:45 -07:00
- Ran code :
\ ` \` \` js
// Select options [bar, baz] in Select
await page . getByRole ( 'listbox' ) . selectOption ( [ 'bar' , 'baz' ] ) ;
\ ` \` \`
2025-03-26 13:53:56 +09:00
- Page URL : data : text / html , < html > < title > Title < / title > < select multiple > < option value = "foo" > Foo < / option > < option value = "bar" > Bar < / option > < option value = "baz" > Baz < / option > < / select > < / html >
- Page Title : Title
- Page Snapshot
\ ` \` \` yaml
2025-04-01 23:47:53 +02:00
- listbox [ ref = s2e3 ] :
- option "Foo" [ ref = s2e4 ]
- option "Bar" [ selected ] [ ref = s2e5 ]
- option "Baz" [ selected ] [ ref = s2e6 ]
2025-03-26 13:53:56 +09:00
\ ` \` \`
2025-03-27 16:50:43 -07:00
` );
2025-03-26 13:53:56 +09:00
} ) ;
2025-03-26 16:27:55 +01:00
2025-04-04 17:14:30 -07:00
test ( 'browser_file_upload' , async ( { client } ) = > {
2025-03-27 16:50:43 -07:00
expect ( await client . callTool ( {
name : 'browser_navigate' ,
arguments : {
url : 'data:text/html,<html><title>Title</title><input type="file" /><button>Button</button></html>' ,
} ,
2025-04-01 23:47:53 +02:00
} ) ) . toContainTextContent ( '- textbox [ref=s1e3]' ) ;
2025-03-27 16:50:43 -07:00
expect ( await client . callTool ( {
name : 'browser_click' ,
arguments : {
element : 'Textbox' ,
2025-04-01 23:47:53 +02:00
ref : 's1e3' ,
2025-03-27 16:50:43 -07:00
} ,
2025-04-04 17:14:30 -07:00
} ) ) . toContainTextContent ( 'There is a file chooser visible that requires browser_file_upload to be called' ) ;
2025-03-27 20:49:57 +01:00
const filePath = test . info ( ) . outputPath ( 'test.txt' ) ;
await fs . writeFile ( filePath , 'Hello, world!' ) ;
2025-03-27 16:50:43 -07:00
{
const response = await client . callTool ( {
2025-04-04 17:14:30 -07:00
name : 'browser_file_upload' ,
2025-03-27 16:50:43 -07:00
arguments : {
paths : [ filePath ] ,
} ,
} ) ;
2025-03-27 23:47:15 +01:00
2025-04-04 17:14:30 -07:00
expect ( response ) . not . toContainTextContent ( 'There is a file chooser visible that requires browser_file_upload to be called' ) ;
2025-04-01 23:47:53 +02:00
expect ( response ) . toContainTextContent ( 'textbox [ref=s3e3]: C:\\fakepath\\test.txt' ) ;
2025-03-27 16:50:43 -07:00
}
2025-03-27 23:47:15 +01:00
2025-03-27 16:50:43 -07:00
{
const response = await client . callTool ( {
name : 'browser_click' ,
arguments : {
element : 'Textbox' ,
2025-04-01 23:47:53 +02:00
ref : 's3e3' ,
2025-03-27 16:50:43 -07:00
} ,
} ) ;
2025-03-27 23:47:15 +01:00
2025-04-04 17:14:30 -07:00
expect ( response ) . toContainTextContent ( 'There is a file chooser visible that requires browser_file_upload to be called' ) ;
2025-04-01 23:47:53 +02:00
expect ( response ) . toContainTextContent ( 'button "Button" [ref=s4e4]' ) ;
2025-03-27 16:50:43 -07:00
}
{
const response = await client . callTool ( {
name : 'browser_click' ,
arguments : {
element : 'Button' ,
2025-04-01 23:47:53 +02:00
ref : 's4e4' ,
2025-03-27 16:50:43 -07:00
} ,
} ) ;
2025-03-27 23:47:15 +01:00
2025-04-04 17:14:30 -07:00
expect ( response , 'not submitting browser_file_upload dismisses file chooser' ) . not . toContainTextContent ( 'There is a file chooser visible that requires browser_file_upload to be called' ) ;
2025-03-27 19:23:50 +01:00
}
} ) ;
2025-03-30 09:05:58 -07:00
2025-04-04 17:14:30 -07:00
test ( 'browser_type' , async ( { client } ) = > {
2025-04-02 14:36:30 -07:00
await client . callTool ( {
name : 'browser_navigate' ,
arguments : {
url : ` data:text/html,<input type='keypress' onkeypress="console.log('Key pressed:', event.key, ', Text:', event.target.value)"></input> ` ,
} ,
} ) ;
await client . callTool ( {
name : 'browser_type' ,
arguments : {
element : 'textbox' ,
ref : 's1e3' ,
text : 'Hi!' ,
submit : true ,
} ,
} ) ;
const resource = await client . readResource ( {
uri : 'browser://console' ,
} ) ;
expect ( resource . contents ) . toEqual ( [ {
uri : 'browser://console' ,
mimeType : 'text/plain' ,
text : '[LOG] Key pressed: Enter , Text: Hi!' ,
} ] ) ;
} ) ;
2025-04-04 17:14:30 -07:00
test ( 'browser_type (slowly)' , async ( { client } ) = > {
2025-04-02 14:36:30 -07:00
await client . callTool ( {
name : 'browser_navigate' ,
arguments : {
url : ` data:text/html,<input type='text' onkeydown="console.log('Key pressed:', event.key, 'Text:', event.target.value)"></input> ` ,
} ,
} ) ;
await client . callTool ( {
name : 'browser_type' ,
arguments : {
element : 'textbox' ,
ref : 's1e3' ,
text : 'Hi!' ,
submit : true ,
slowly : true ,
} ,
} ) ;
const resource = await client . readResource ( {
uri : 'browser://console' ,
} ) ;
expect ( resource . contents ) . toEqual ( [ {
uri : 'browser://console' ,
mimeType : 'text/plain' ,
text : [
'[LOG] Key pressed: H Text: ' ,
'[LOG] Key pressed: i Text: H' ,
'[LOG] Key pressed: ! Text: Hi' ,
'[LOG] Key pressed: Enter Text: Hi!' ,
] . join ( '\n' ) ,
} ] ) ;
} ) ;
2025-04-15 01:09:48 +02:00
test ( 'browser_resize' , async ( { client } ) = > {
await client . callTool ( {
name : 'browser_navigate' ,
arguments : {
url : 'data:text/html,<html><title>Resize Test</title><body><div id="size">Waiting for resize...</div><script>new ResizeObserver(() => { document.getElementById("size").textContent = `Window size: ${window.innerWidth}x${window.innerHeight}`; }).observe(document.body);</script></body></html>' ,
} ,
} ) ;
const response = await client . callTool ( {
name : 'browser_resize' ,
arguments : {
width : 390 ,
height : 780 ,
} ,
} ) ;
2025-04-15 12:54:45 -07:00
expect ( response ) . toContainTextContent ( ` - Ran code:
\ ` \` \` js
// Resize browser window to 390x780
await page . setViewportSize ( { width : 390 , height : 780 } ) ;
\ ` \` \` ` ) ;
2025-04-15 16:10:49 +02:00
await expect . poll ( ( ) = > client . callTool ( { name : 'browser_snapshot' } ) ) . toContainTextContent ( 'Window size: 390x780' ) ;
2025-04-15 01:09:48 +02:00
} ) ;