diff --git a/packages/dev-middleware/src/__tests__/FetchUtils.js b/packages/dev-middleware/src/__tests__/FetchUtils.js index 413ada1523ee..43195383e800 100644 --- a/packages/dev-middleware/src/__tests__/FetchUtils.js +++ b/packages/dev-middleware/src/__tests__/FetchUtils.js @@ -21,7 +21,7 @@ declare var globalThis: $FlowFixMe; */ export async function fetchLocal( url: string, - options?: Parameters[1] & {dispatcher?: mixed}, + options?: Partial[1] & {dispatcher?: mixed}>, ): ReturnType { return await fetch(url, { ...options, diff --git a/packages/dev-middleware/src/__tests__/InspectorProxyHttpApi-test.js b/packages/dev-middleware/src/__tests__/InspectorProxyHttpApi-test.js index cb94b100bfbf..52a53de214b0 100644 --- a/packages/dev-middleware/src/__tests__/InspectorProxyHttpApi-test.js +++ b/packages/dev-middleware/src/__tests__/InspectorProxyHttpApi-test.js @@ -18,6 +18,7 @@ import {fetchJson, fetchLocal} from './FetchUtils'; import {createDeviceMock} from './InspectorDeviceUtils'; import {withAbortSignalForEachTest} from './ResourceUtils'; import {withServerForEachTest} from './ServerUtils'; +import DefaultBrowserLauncher from '../utils/DefaultBrowserLauncher'; // Must be greater than or equal to PAGES_POLLING_INTERVAL in `InspectorProxy.js`. const PAGES_POLLING_DELAY = 1000; @@ -368,4 +369,60 @@ describe('inspector proxy HTTP API', () => { } }); }); + + describe('/open-debugger endpoint', () => { + it('opens requested device using appId, device, and target', async () => { + // Connect a device to use when opening the debugger + const device = await createDeviceMock( + `${serverRef.serverBaseWsUrl}/inspector/device?device=device1&name=foo&app=bar`, + autoCleanup.signal, + ); + device.getPages.mockImplementation(() => [ + { + app: 'bar-app', + id: 'page1', + title: 'bar-title', + vm: 'bar-vm', + capabilities: { + // Ensure the device target can be found when launching the debugger + nativePageReloads: true, + }, + }, + ]); + jest.advanceTimersByTime(PAGES_POLLING_DELAY); + + // Hook into `DefaultBrowserLauncher.launchDebuggerAppWindow` to ensure debugger was launched + const launchDebuggerSpy = jest + .spyOn(DefaultBrowserLauncher, 'launchDebuggerAppWindow') + .mockResolvedValueOnce(); + + try { + // Fetch the target information for the device + const pageListResponse = await fetchJson( + `${serverRef.serverBaseUrl}/json`, + ); + // Select the first target from the page list response + expect(pageListResponse.length).toBeGreaterThanOrEqual(1); + const firstPage = pageListResponse[0]; + + // Build the URL for the debugger + const openUrl = new URL('/open-debugger', serverRef.serverBaseUrl); + openUrl.searchParams.set('appId', firstPage.description); + openUrl.searchParams.set( + 'device', + firstPage.reactNative.logicalDeviceId, + ); + openUrl.searchParams.set('target', firstPage.id); + // Request to open the debugger for the first device + const response = await fetchLocal(openUrl.toString(), {method: 'POST'}); + + // Ensure the request was handled properly + expect(response.status).toBe(200); + // Ensure the debugger was launched + expect(launchDebuggerSpy).toHaveBeenCalledWith(expect.any(String)); + } finally { + device.close(); + } + }); + }); }); diff --git a/packages/dev-middleware/src/middleware/openDebuggerMiddleware.js b/packages/dev-middleware/src/middleware/openDebuggerMiddleware.js index 69051ec09c39..97fcb9c984f3 100644 --- a/packages/dev-middleware/src/middleware/openDebuggerMiddleware.js +++ b/packages/dev-middleware/src/middleware/openDebuggerMiddleware.js @@ -132,6 +132,7 @@ export default function openDebuggerMiddleware({ {launchId, useFuseboxEntryPoint}, ), ); + res.writeHead(200); res.end(); break; case 'redirect':