Files
react-native/packages/dev-middleware/src/__tests__/InspectorProtocolUtils.js
Sam ZhouandFacebook GitHub Bot cf664c65e2 Standardize subtyping error code into incompatible-type in react native and metro (#53312)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/53312

Changelog: [Internal]

Reviewed By: jbrown215

Differential Revision: D80400976

fbshipit-source-id: 196af69c0b9621b2a2675b232406639773e04933
2025-08-18 09:04:31 -07:00

164 lines
4.7 KiB
JavaScript

/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow strict-local
* @format
*/
import type {
JSONSerializable,
PageDescription,
PageFromDevice,
} from '../inspector-proxy/types';
import type {DebuggerMock} from './InspectorDebuggerUtils';
import type {DeviceMock} from './InspectorDeviceUtils';
import {fetchJson} from './FetchUtils';
import {createDebuggerMock} from './InspectorDebuggerUtils';
import {createDeviceMock} from './InspectorDeviceUtils';
import until from 'wait-for-expect';
export type CdpMessageFromTarget = $ReadOnly<{
method: string,
id?: number,
params?: JSONSerializable,
}>;
export type CdpResponseFromTarget = $ReadOnly<{
id: number,
result: JSONSerializable,
}>;
export type CdpMessageToTarget = $ReadOnly<{
method: string,
id: number,
params?: JSONSerializable,
}>;
/**
* Send a CDP message from from the target with the given pageId to the debugger.
* Returns the message as received by the debugger.
*/
export async function sendFromTargetToDebugger<Message: CdpMessageFromTarget>(
device: DeviceMock,
debugger_: DebuggerMock,
pageId: string,
message: Message,
): Promise<Message> {
const originalHandleCallsArray = debugger_.handle.mock.calls;
const originalHandleCallCount = originalHandleCallsArray.length;
device.sendWrappedEvent(pageId, message);
await until(() =>
expect(debugger_.handle).toBeCalledWith(
expect.objectContaining({
method: message.method,
}),
),
);
// Find the first handle call that wasn't already in the mock calls array
// before we sent the message.
const newHandleCalls =
originalHandleCallsArray === debugger_.handle.mock.calls
? debugger_.handle.mock.calls.slice(originalHandleCallCount)
: debugger_.handle.mock.calls;
// $FlowFixMe[incompatible-type]
const [receivedMessage]: [Message] = newHandleCalls.find(
// $FlowFixMe[incompatible-type]
(call: [Message]) => call[0].method === message.method,
);
return receivedMessage;
}
/**
* Send a CDP message from the debugger to the target with the given pageId.
* Returns the message as received by the target.
*/
export async function sendFromDebuggerToTarget<Message: CdpMessageToTarget>(
debugger_: DebuggerMock,
device: DeviceMock,
pageId: string,
message: Message,
): Promise<Message> {
const originalEventCallsArray = device.wrappedEventParsed.mock.calls;
const originalEventCallCount = originalEventCallsArray.length;
debugger_.send(message);
await until(() =>
expect(device.wrappedEventParsed).toBeCalledWith({
pageId,
wrappedEvent: expect.objectContaining({id: message.id}),
}),
);
// Find the first handle call that wasn't already in the mock calls array
// before we sent the message.
const newEventCalls =
originalEventCallsArray === device.wrappedEventParsed.mock.calls
? device.wrappedEventParsed.mock.calls.slice(originalEventCallCount)
: device.wrappedEventParsed.mock.calls;
// $FlowFixMe[incompatible-use]
const [receivedMessage] = newEventCalls.find(
// $FlowFixMe[prop-missing]
// $FlowFixMe[incompatible-use]
call => call[0].wrappedEvent.id === message.id,
);
// $FlowFixMe[incompatible-type]
return receivedMessage.wrappedEvent;
}
export async function createAndConnectTarget(
serverRef: $ReadOnly<{
serverBaseUrl: string,
serverBaseWsUrl: string,
...
}>,
signal: AbortSignal,
page: PageFromDevice,
{
debuggerHostHeader = null,
deviceId = null,
deviceHostHeader = null,
}: $ReadOnly<{
debuggerHostHeader?: ?string,
deviceId?: ?string,
deviceHostHeader?: ?string,
}> = {},
): Promise<{device: DeviceMock, debugger_: DebuggerMock}> {
let device;
let debugger_;
try {
device = await createDeviceMock(
`${serverRef.serverBaseWsUrl}/inspector/device?device=${
deviceId ?? 'device' + Date.now()
}&name=foo&app=bar`,
signal,
deviceHostHeader,
);
device.getPages.mockImplementation(() => [page]);
let pageList: Array<PageDescription> = [];
await until(async () => {
pageList = (await fetchJson(
`${serverRef.serverBaseUrl}/json`,
// $FlowFixMe[unclear-type]
): any);
expect(pageList).toHaveLength(1);
});
const [{webSocketDebuggerUrl}] = pageList;
expect(webSocketDebuggerUrl).toBeDefined();
debugger_ = await createDebuggerMock(
webSocketDebuggerUrl,
signal,
debuggerHostHeader,
);
await until(() => expect(device.connect).toBeCalled());
} catch (e) {
device?.close();
debugger_?.close();
throw e;
}
return {device, debugger_};
}