Extract idb device querying to IOSBridge
Summary: Again this is just a code move for now. However, we now have a common method between simctl and idb cases. This means that the next diff can call an `IOSBridge` with polymorpism taking over. This is still delegated out, but there's an argument to be made to move `iosUtil` functionality back so that this all lives in the same place. Reviewed By: passy Differential Revision: D33843093 fbshipit-source-id: 5cd884140817df851cccf63e5780582b16d4231c
This commit is contained in:
committed by
Facebook GitHub Bot
parent
aeb0b5f317
commit
ccae37aa71
@@ -8,6 +8,8 @@
|
||||
*/
|
||||
|
||||
import fs from 'fs-extra';
|
||||
import iosUtil from './iOSContainerUtility';
|
||||
|
||||
import child_process from 'child_process';
|
||||
import type {IOSDeviceParams} from 'flipper-common';
|
||||
import {DeviceType} from 'flipper-common';
|
||||
@@ -42,10 +44,22 @@ export interface IOSBridge {
|
||||
serial: string,
|
||||
outputFile: string,
|
||||
) => child_process.ChildProcess;
|
||||
getActiveDevices: (bootedOnly: boolean) => Promise<Array<IOSDeviceParams>>;
|
||||
}
|
||||
|
||||
class IDBBridge implements IOSBridge {
|
||||
constructor(private idbPath: string) {}
|
||||
export class IDBBridge implements IOSBridge {
|
||||
constructor(
|
||||
private idbPath: string,
|
||||
private enablePhysicalDevices: boolean,
|
||||
) {}
|
||||
async getActiveDevices(_bootedOnly: boolean): Promise<IOSDeviceParams[]> {
|
||||
return iosUtil
|
||||
.targets(this.idbPath, this.enablePhysicalDevices)
|
||||
.catch((e) => {
|
||||
console.error('Failed to get active iOS devices:', e.message);
|
||||
return [];
|
||||
});
|
||||
}
|
||||
|
||||
async navigate(serial: string, location: string): Promise<void> {
|
||||
this._execIdb(`open --udid ${serial} "${location}"`);
|
||||
@@ -216,11 +230,12 @@ export function getDeviceSetPath() {
|
||||
export async function makeIOSBridge(
|
||||
idbPath: string,
|
||||
isXcodeDetected: boolean,
|
||||
enablePhysicalDevices: boolean,
|
||||
isAvailableFn: (idbPath: string) => Promise<boolean> = isAvailable,
|
||||
): Promise<IOSBridge> {
|
||||
// prefer idb
|
||||
if (await isAvailableFn(idbPath)) {
|
||||
return new IDBBridge(idbPath);
|
||||
return new IDBBridge(idbPath, enablePhysicalDevices);
|
||||
}
|
||||
|
||||
// no idb, if it's a simulator and xcode is available, we can use xcrun
|
||||
|
||||
@@ -26,7 +26,7 @@ afterEach(() => {
|
||||
});
|
||||
|
||||
test('uses xcrun with no idb when xcode is detected', async () => {
|
||||
const ib = await makeIOSBridge('', true);
|
||||
const ib = await makeIOSBridge('', true, false);
|
||||
|
||||
ib.startLogListener('deadbeef', 'emulator');
|
||||
|
||||
@@ -50,7 +50,12 @@ test('uses xcrun with no idb when xcode is detected', async () => {
|
||||
});
|
||||
|
||||
test('uses idb when present and xcode detected', async () => {
|
||||
const ib = await makeIOSBridge('/usr/local/bin/idb', true, async (_) => true);
|
||||
const ib = await makeIOSBridge(
|
||||
'/usr/local/bin/idb',
|
||||
true,
|
||||
true,
|
||||
async (_) => true,
|
||||
);
|
||||
|
||||
ib.startLogListener('deadbeef', 'emulator');
|
||||
|
||||
@@ -77,7 +82,12 @@ test('uses idb when present and xcode detected', async () => {
|
||||
});
|
||||
|
||||
test('uses idb when present and xcode detected and physical device connected', async () => {
|
||||
const ib = await makeIOSBridge('/usr/local/bin/idb', true, async (_) => true);
|
||||
const ib = await makeIOSBridge(
|
||||
'/usr/local/bin/idb',
|
||||
true,
|
||||
true,
|
||||
async (_) => true,
|
||||
);
|
||||
|
||||
ib.startLogListener('deadbeef', 'physical');
|
||||
|
||||
@@ -99,12 +109,12 @@ test('uses idb when present and xcode detected and physical device connected', a
|
||||
});
|
||||
|
||||
test("without idb physical devices can't log", async () => {
|
||||
const ib = await makeIOSBridge('', true);
|
||||
const ib = await makeIOSBridge('', true, false);
|
||||
expect(ib.startLogListener).toBeDefined(); // since we have xcode
|
||||
});
|
||||
|
||||
test('throws if no iOS support', async () => {
|
||||
await expect(makeIOSBridge('', false)).rejects.toThrow(
|
||||
await expect(makeIOSBridge('', false, false)).rejects.toThrow(
|
||||
'Neither Xcode nor idb available. Cannot provide iOS device functionality.',
|
||||
);
|
||||
});
|
||||
@@ -112,7 +122,7 @@ test('throws if no iOS support', async () => {
|
||||
test.unix(
|
||||
'uses xcrun to take screenshots with no idb when xcode is detected',
|
||||
async () => {
|
||||
const ib = await makeIOSBridge('', true);
|
||||
const ib = await makeIOSBridge('', true, false);
|
||||
|
||||
await expect(() => ib.screenshot('deadbeef')).rejects.toThrow();
|
||||
|
||||
@@ -123,7 +133,12 @@ test.unix(
|
||||
);
|
||||
|
||||
test.unix('uses idb to take screenshots when available', async () => {
|
||||
const ib = await makeIOSBridge('/usr/local/bin/idb', true, async (_) => true);
|
||||
const ib = await makeIOSBridge(
|
||||
'/usr/local/bin/idb',
|
||||
true,
|
||||
true,
|
||||
async (_) => true,
|
||||
);
|
||||
|
||||
await expect(() => ib.screenshot('deadbeef')).rejects.toThrow();
|
||||
|
||||
@@ -133,7 +148,7 @@ test.unix('uses idb to take screenshots when available', async () => {
|
||||
});
|
||||
|
||||
test('uses xcrun to navigate with no idb when xcode is detected', async () => {
|
||||
const ib = await makeIOSBridge('', true);
|
||||
const ib = await makeIOSBridge('', true, false);
|
||||
|
||||
await ib.navigate('deadbeef', 'fb://dummy');
|
||||
|
||||
@@ -143,7 +158,12 @@ test('uses xcrun to navigate with no idb when xcode is detected', async () => {
|
||||
});
|
||||
|
||||
test('uses idb to navigate when available', async () => {
|
||||
const ib = await makeIOSBridge('/usr/local/bin/idb', true, async (_) => true);
|
||||
const ib = await makeIOSBridge(
|
||||
'/usr/local/bin/idb',
|
||||
true,
|
||||
true,
|
||||
async (_) => true,
|
||||
);
|
||||
|
||||
await ib.navigate('deadbeef', 'fb://dummy');
|
||||
|
||||
@@ -153,7 +173,7 @@ test('uses idb to navigate when available', async () => {
|
||||
});
|
||||
|
||||
test('uses xcrun to record with no idb when xcode is detected', async () => {
|
||||
const ib = await makeIOSBridge('', true);
|
||||
const ib = await makeIOSBridge('', true, false);
|
||||
|
||||
ib.recordVideo('deadbeef', '/tmp/video.mp4');
|
||||
|
||||
@@ -163,7 +183,12 @@ test('uses xcrun to record with no idb when xcode is detected', async () => {
|
||||
});
|
||||
|
||||
test('uses idb to record when available', async () => {
|
||||
const ib = await makeIOSBridge('/usr/local/bin/idb', true, async (_) => true);
|
||||
const ib = await makeIOSBridge(
|
||||
'/usr/local/bin/idb',
|
||||
true,
|
||||
true,
|
||||
async (_) => true,
|
||||
);
|
||||
|
||||
ib.recordVideo('deadbeef', '/tmo/video.mp4');
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ import IOSDevice from './IOSDevice';
|
||||
import {
|
||||
ERR_NO_IDB_OR_XCODE_AVAILABLE,
|
||||
IOSBridge,
|
||||
IDBBridge,
|
||||
makeIOSBridge,
|
||||
SimctlBridge,
|
||||
} from './IOSBridge';
|
||||
@@ -174,7 +175,11 @@ export class IOSDeviceManager {
|
||||
}
|
||||
try {
|
||||
// Awaiting the promise here to trigger immediate error handling.
|
||||
this.iosBridge = await makeIOSBridge(settings.idbPath, isDetected);
|
||||
this.iosBridge = await makeIOSBridge(
|
||||
settings.idbPath,
|
||||
isDetected,
|
||||
settings.enablePhysicalIOS,
|
||||
);
|
||||
this.queryDevicesForever();
|
||||
} catch (err) {
|
||||
// This case is expected if both Xcode and idb are missing.
|
||||
@@ -252,10 +257,7 @@ function getActiveDevices(
|
||||
idbPath: string,
|
||||
isPhysicalDeviceEnabled: boolean,
|
||||
): Promise<Array<IOSDeviceParams>> {
|
||||
return iosUtil.targets(idbPath, isPhysicalDeviceEnabled).catch((e) => {
|
||||
console.error('Failed to get active iOS devices:', e.message);
|
||||
return [];
|
||||
});
|
||||
return new IDBBridge(idbPath, isPhysicalDeviceEnabled).getActiveDevices(true);
|
||||
}
|
||||
|
||||
export function parseXcodeFromCoreSimPath(
|
||||
|
||||
Reference in New Issue
Block a user