@@ -55,6 +55,34 @@ jest.mock("../../contextProxy", () => {
5555// Mock dependencies
5656jest . mock ( "vscode" )
5757jest . mock ( "delay" )
58+
59+ // Mock BrowserSession
60+ jest . mock ( "../../../services/browser/BrowserSession" , ( ) => ( {
61+ BrowserSession : jest . fn ( ) . mockImplementation ( ( ) => ( {
62+ testConnection : jest . fn ( ) . mockImplementation ( async ( url ) => {
63+ if ( url === "http://localhost:9222" ) {
64+ return {
65+ success : true ,
66+ message : "Successfully connected to Chrome" ,
67+ endpoint : "ws://localhost:9222/devtools/browser/123" ,
68+ }
69+ } else {
70+ return {
71+ success : false ,
72+ message : "Failed to connect to Chrome" ,
73+ endpoint : undefined ,
74+ }
75+ }
76+ } ) ,
77+ } ) ) ,
78+ } ) )
79+
80+ // Mock browserDiscovery
81+ jest . mock ( "../../../services/browser/browserDiscovery" , ( ) => ( {
82+ discoverChromeInstances : jest . fn ( ) . mockImplementation ( async ( ) => {
83+ return "http://localhost:9222"
84+ } ) ,
85+ } ) )
5886jest . mock (
5987 "@modelcontextprotocol/sdk/types.js" ,
6088 ( ) => ( {
@@ -94,31 +122,7 @@ jest.mock("delay", () => {
94122 return delayFn
95123} )
96124
97- // Mock MCP-related modules
98- jest . mock (
99- "@modelcontextprotocol/sdk/types.js" ,
100- ( ) => ( {
101- CallToolResultSchema : { } ,
102- ListResourcesResultSchema : { } ,
103- ListResourceTemplatesResultSchema : { } ,
104- ListToolsResultSchema : { } ,
105- ReadResourceResultSchema : { } ,
106- ErrorCode : {
107- InvalidRequest : "InvalidRequest" ,
108- MethodNotFound : "MethodNotFound" ,
109- InternalError : "InternalError" ,
110- } ,
111- McpError : class McpError extends Error {
112- code : string
113- constructor ( code : string , message : string ) {
114- super ( message )
115- this . code = code
116- this . name = "McpError"
117- }
118- } ,
119- } ) ,
120- { virtual : true } ,
121- )
125+ // MCP-related modules are mocked once above (lines 87-109)
122126
123127jest . mock (
124128 "@modelcontextprotocol/sdk/client/index.js" ,
@@ -598,7 +602,7 @@ describe("ClineProvider", () => {
598602 expect ( mockPostMessage ) . toHaveBeenCalled ( )
599603 } )
600604
601- test ( "requestDelaySeconds defaults to 5 seconds" , async ( ) => {
605+ test ( "requestDelaySeconds defaults to 10 seconds" , async ( ) => {
602606 // Mock globalState.get to return undefined for requestDelaySeconds
603607 ; ( mockContext . globalState . get as jest . Mock ) . mockImplementation ( ( key : string ) => {
604608 if ( key === "requestDelaySeconds" ) {
@@ -1781,6 +1785,173 @@ describe("ClineProvider", () => {
17811785 ] )
17821786 } )
17831787 } )
1788+
1789+ describe ( "browser connection features" , ( ) => {
1790+ beforeEach ( async ( ) => {
1791+ // Reset mocks
1792+ jest . clearAllMocks ( )
1793+ await provider . resolveWebviewView ( mockWebviewView )
1794+ } )
1795+
1796+ // Mock BrowserSession and discoverChromeInstances
1797+ jest . mock ( "../../../services/browser/BrowserSession" , ( ) => ( {
1798+ BrowserSession : jest . fn ( ) . mockImplementation ( ( ) => ( {
1799+ testConnection : jest . fn ( ) . mockImplementation ( async ( url ) => {
1800+ if ( url === "http://localhost:9222" ) {
1801+ return {
1802+ success : true ,
1803+ message : "Successfully connected to Chrome" ,
1804+ endpoint : "ws://localhost:9222/devtools/browser/123" ,
1805+ }
1806+ } else {
1807+ return {
1808+ success : false ,
1809+ message : "Failed to connect to Chrome" ,
1810+ endpoint : undefined ,
1811+ }
1812+ }
1813+ } ) ,
1814+ } ) ) ,
1815+ } ) )
1816+
1817+ jest . mock ( "../../../services/browser/browserDiscovery" , ( ) => ( {
1818+ discoverChromeInstances : jest . fn ( ) . mockImplementation ( async ( ) => {
1819+ return "http://localhost:9222"
1820+ } ) ,
1821+ } ) )
1822+
1823+ test ( "handles testBrowserConnection with provided URL" , async ( ) => {
1824+ // Get the message handler
1825+ const messageHandler = ( mockWebviewView . webview . onDidReceiveMessage as jest . Mock ) . mock . calls [ 0 ] [ 0 ]
1826+
1827+ // Test with valid URL
1828+ await messageHandler ( {
1829+ type : "testBrowserConnection" ,
1830+ text : "http://localhost:9222" ,
1831+ } )
1832+
1833+ // Verify postMessage was called with success result
1834+ expect ( mockPostMessage ) . toHaveBeenCalledWith (
1835+ expect . objectContaining ( {
1836+ type : "browserConnectionResult" ,
1837+ success : true ,
1838+ text : expect . stringContaining ( "Successfully connected to Chrome" ) ,
1839+ } ) ,
1840+ )
1841+
1842+ // Reset mock
1843+ mockPostMessage . mockClear ( )
1844+
1845+ // Test with invalid URL
1846+ await messageHandler ( {
1847+ type : "testBrowserConnection" ,
1848+ text : "http://inlocalhost:9222" ,
1849+ } )
1850+
1851+ // Verify postMessage was called with failure result
1852+ expect ( mockPostMessage ) . toHaveBeenCalledWith (
1853+ expect . objectContaining ( {
1854+ type : "browserConnectionResult" ,
1855+ success : false ,
1856+ text : expect . stringContaining ( "Failed to connect to Chrome" ) ,
1857+ } ) ,
1858+ )
1859+ } )
1860+
1861+ test ( "handles testBrowserConnection with auto-discovery" , async ( ) => {
1862+ // Get the message handler
1863+ const messageHandler = ( mockWebviewView . webview . onDidReceiveMessage as jest . Mock ) . mock . calls [ 0 ] [ 0 ]
1864+
1865+ // Test auto-discovery (no URL provided)
1866+ await messageHandler ( {
1867+ type : "testBrowserConnection" ,
1868+ } )
1869+
1870+ // Verify discoverChromeInstances was called
1871+ const { discoverChromeInstances } = require ( "../../../services/browser/browserDiscovery" )
1872+ expect ( discoverChromeInstances ) . toHaveBeenCalled ( )
1873+
1874+ // Verify postMessage was called with success result
1875+ expect ( mockPostMessage ) . toHaveBeenCalledWith (
1876+ expect . objectContaining ( {
1877+ type : "browserConnectionResult" ,
1878+ success : true ,
1879+ text : expect . stringContaining ( "Auto-discovered and tested connection to Chrome" ) ,
1880+ } ) ,
1881+ )
1882+ } )
1883+
1884+ test ( "handles discoverBrowser message" , async ( ) => {
1885+ // Get the message handler
1886+ const messageHandler = ( mockWebviewView . webview . onDidReceiveMessage as jest . Mock ) . mock . calls [ 0 ] [ 0 ]
1887+
1888+ // Test browser discovery
1889+ await messageHandler ( {
1890+ type : "discoverBrowser" ,
1891+ } )
1892+
1893+ // Verify discoverChromeInstances was called
1894+ const { discoverChromeInstances } = require ( "../../../services/browser/browserDiscovery" )
1895+ expect ( discoverChromeInstances ) . toHaveBeenCalled ( )
1896+
1897+ // Verify postMessage was called with success result
1898+ expect ( mockPostMessage ) . toHaveBeenCalledWith (
1899+ expect . objectContaining ( {
1900+ type : "browserConnectionResult" ,
1901+ success : true ,
1902+ text : expect . stringContaining ( "Successfully discovered and connected to Chrome" ) ,
1903+ } ) ,
1904+ )
1905+ } )
1906+
1907+ test ( "handles errors during browser discovery" , async ( ) => {
1908+ // Mock discoverChromeInstances to throw an error
1909+ const { discoverChromeInstances } = require ( "../../../services/browser/browserDiscovery" )
1910+ discoverChromeInstances . mockImplementationOnce ( ( ) => {
1911+ throw new Error ( "Discovery error" )
1912+ } )
1913+
1914+ // Get the message handler
1915+ const messageHandler = ( mockWebviewView . webview . onDidReceiveMessage as jest . Mock ) . mock . calls [ 0 ] [ 0 ]
1916+
1917+ // Test browser discovery with error
1918+ await messageHandler ( {
1919+ type : "discoverBrowser" ,
1920+ } )
1921+
1922+ // Verify postMessage was called with error result
1923+ expect ( mockPostMessage ) . toHaveBeenCalledWith (
1924+ expect . objectContaining ( {
1925+ type : "browserConnectionResult" ,
1926+ success : false ,
1927+ text : expect . stringContaining ( "Error discovering browser" ) ,
1928+ } ) ,
1929+ )
1930+ } )
1931+
1932+ test ( "handles case when no browsers are discovered" , async ( ) => {
1933+ // Mock discoverChromeInstances to return null (no browsers found)
1934+ const { discoverChromeInstances } = require ( "../../../services/browser/browserDiscovery" )
1935+ discoverChromeInstances . mockImplementationOnce ( ( ) => null )
1936+
1937+ // Get the message handler
1938+ const messageHandler = ( mockWebviewView . webview . onDidReceiveMessage as jest . Mock ) . mock . calls [ 0 ] [ 0 ]
1939+
1940+ // Test browser discovery with no browsers found
1941+ await messageHandler ( {
1942+ type : "discoverBrowser" ,
1943+ } )
1944+
1945+ // Verify postMessage was called with failure result
1946+ expect ( mockPostMessage ) . toHaveBeenCalledWith (
1947+ expect . objectContaining ( {
1948+ type : "browserConnectionResult" ,
1949+ success : false ,
1950+ text : expect . stringContaining ( "No Chrome instances found" ) ,
1951+ } ) ,
1952+ )
1953+ } )
1954+ } )
17841955} )
17851956
17861957describe ( "ContextProxy integration" , ( ) => {
0 commit comments