@@ -75,6 +75,14 @@ describe('executeRunTaskOperation', () => {
7575 error : undefined ,
7676 } )
7777 expect ( mockFetch ) . toHaveBeenCalledTimes ( 3 )
78+ for ( const [ , request ] of mockFetch . mock . calls ) {
79+ expect ( request ) . toEqual (
80+ expect . objectContaining ( {
81+ redirect : 'error' ,
82+ headers : expect . objectContaining ( { 'X-Browser-Use-API-Key' : 'api-key' } ) ,
83+ } )
84+ )
85+ }
7886 } )
7987
8088 it ( 'rejects a malformed successful create-task response' , async ( ) => {
@@ -116,4 +124,57 @@ describe('executeRunTaskOperation', () => {
116124 error : 'Error creating task: provider unavailable' ,
117125 } )
118126 } )
127+
128+ it . each ( [
129+ [ 'an HTTP error' , new Response ( 'rejected' , { status : 400 , statusText : 'Bad Request' } ) ] ,
130+ [ 'a schema-invalid success' , jsonResponse ( { sessionId : 'session-1' } ) ] ,
131+ ] ) ( 'stops a profile session when task creation returns %s' , async ( _case , taskResponse ) => {
132+ mockFetch
133+ . mockResolvedValueOnce ( jsonResponse ( { id : 'profile-session' } ) )
134+ . mockResolvedValueOnce ( taskResponse )
135+ . mockResolvedValueOnce ( new Response ( null , { status : 204 } ) )
136+
137+ const result = await executeRunTaskOperation ( {
138+ task : 'Open the page' ,
139+ apiKey : 'api-key' ,
140+ profile_id : 'profile-1' ,
141+ } )
142+
143+ expect ( result . success ) . toBe ( false )
144+ expect ( mockFetch ) . toHaveBeenNthCalledWith (
145+ 3 ,
146+ 'https://api.browser-use.com/api/v2/sessions/profile-session' ,
147+ expect . objectContaining ( {
148+ method : 'PATCH' ,
149+ body : JSON . stringify ( { action : 'stop' } ) ,
150+ redirect : 'error' ,
151+ } )
152+ )
153+ } )
154+
155+ it ( 'propagates cancellation while still stopping a created profile session' , async ( ) => {
156+ const controller = new AbortController ( )
157+ const abortError = new DOMException ( 'cancelled' , 'AbortError' )
158+ mockFetch
159+ . mockResolvedValueOnce ( jsonResponse ( { id : 'profile-session' } ) )
160+ . mockImplementationOnce ( async ( _input , request ) => {
161+ expect ( request ?. signal ) . toBe ( controller . signal )
162+ controller . abort ( abortError )
163+ throw abortError
164+ } )
165+ . mockResolvedValueOnce ( new Response ( null , { status : 204 } ) )
166+
167+ await expect (
168+ executeRunTaskOperation (
169+ { task : 'Open the page' , apiKey : 'api-key' , profile_id : 'profile-1' } ,
170+ controller . signal
171+ )
172+ ) . rejects . toBe ( abortError )
173+
174+ expect ( mockFetch ) . toHaveBeenNthCalledWith (
175+ 3 ,
176+ 'https://api.browser-use.com/api/v2/sessions/profile-session' ,
177+ expect . objectContaining ( { method : 'PATCH' , redirect : 'error' } )
178+ )
179+ } )
119180} )
0 commit comments