All files / src/platformTools/apple deviceManager.js

22.35% Statements 19/85
0% Branches 0/49
0% Functions 0/11
21.05% Lines 16/76

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 1293x 3x 3x 3x 3x 3x               3x 3x   3x               3x   3x                                                                                       3x                                                                     3x   3x                 3x                     3x  
import path from 'path';
import fs from 'fs';
import chalk from 'chalk';
import readline from 'readline';
import child_process from 'child_process';
import {
    logTask,
    logError,
    logWarning,
    getAppFolder,
    isPlatformActive,
    logDebug
} from '../../common';
import { getQuestion } from '../../systemTools/prompt';
import { IOS, TVOS } from '../../constants';
 
export const getAppleDevices = (c, platform, ignoreDevices, ignoreSimulators) => {
    logTask(`getAppleDevices:${platform},ignoreDevices:${ignoreDevices},ignoreSimulators${ignoreSimulators}`);
    const devices = child_process.execFileSync('xcrun', ['instruments', '-s'], {
        encoding: 'utf8',
    });
 
    const devicesArr = _parseIOSDevicesList(devices, platform, ignoreDevices, ignoreSimulators);
    return devicesArr;
};
 
const _parseIOSDevicesList = (text, platform, ignoreDevices = false, ignoreSimulators = false) => {
    const devices = [];
    text.split('\n').forEach((line) => {
        const s1 = line.match(/\[.*?\]/);
        const s2 = line.match(/\(.*?\)/g);
        const s3 = line.substring(0, line.indexOf('(') - 1);
        const s4 = line.substring(0, line.indexOf('[') - 1);
        let isSim = false;
        if (s2 && s1) {
            if (s2[s2.length - 1] === '(Simulator)') {
                isSim = true;
                s2.pop();
            }
            const version = s2.pop();
            let name = `${s4.substring(0, s4.lastIndexOf('(') - 1)}`;
            name = name || 'undefined';
            const udid = s1[0].replace(/\[|\]/g, '');
            const isDevice = !isSim;
 
            if ((isDevice && !ignoreDevices) || (!isDevice && !ignoreSimulators)) {
                switch (platform) {
                case IOS:
                    if (name.includes('iPhone') || name.includes('iPad') || name.includes('iPod') || isDevice) {
                        let icon = 'Phone 📱';
                        if (name.includes('iPad')) icon = 'Tablet 💊';
                        devices.push({ udid, name, version, isDevice, icon });
                    }
                    break;
                case TVOS:
                    if ((name.includes('Apple TV') || isDevice) && !name.includes('iPhone') && !name.includes('iPad')) {
                        devices.push({ udid, name, version, isDevice, icon: 'TV 📺' });
                    }
                    break;
                default:
                    devices.push({ udid, name, version, isDevice });
                    break;
                }
            }
        }
    });
 
    return devices;
};
 
export const launchAppleSimulator = (c, platform, target) => new Promise((resolve) => {
    logTask(`launchAppleSimulator:${platform}:${target}`);
 
    const devicesArr = getAppleDevices(c, platform, true);
    let selectedDevice;
    for (let i = 0; i < devicesArr.length; i++) {
        if (devicesArr[i].name === target) {
            selectedDevice = devicesArr[i];
        }
    }
    if (selectedDevice) {
        _launchSimulator(selectedDevice);
        resolve(selectedDevice.name);
    } else {
        logWarning(`Your specified simulator target ${chalk.white(target)} doesn't exists`);
        const readlineInterface = readline.createInterface({
            input: process.stdin,
            output: process.stdout,
        });
        let devicesString = '\n';
        devicesArr.forEach((v, i) => {
            devicesString += `-[${i + 1}] ${chalk.white(v.name)} | ${v.icon} | v: ${chalk.green(v.version)} | udid: ${chalk.blue(
                v.udid,
            )}${v.isDevice ? chalk.red(' (device)') : ''}\n`;
        });
        readlineInterface.question(getQuestion(`${devicesString}\nType number of the simulator you want to launch`), (v) => {
            const chosenDevice = devicesArr[parseInt(v, 10) - 1];
            if (chosenDevice) {
                _launchSimulator(chosenDevice);
                resolve(chosenDevice.name);
            } else {
                logError(`Wrong choice ${v}! Ingoring`);
            }
        });
    }
});
 
const _launchSimulator = (selectedDevice) => {
    try {
        child_process.spawnSync('xcrun', ['instruments', '-w', selectedDevice.udid]);
    } catch (e) {
        // instruments always fail with 255 because it expects more arguments,
        // but we want it to only launch the simulator
    }
};
 
export const listAppleDevices = (c, platform) => new Promise((resolve) => {
    logTask(`listAppleDevices:${platform}`);
 
    const devicesArr = getAppleDevices(c, platform);
    let devicesString = '\n';
    devicesArr.forEach((v, i) => {
        devicesString += `-[${i + 1}] ${chalk.white(v.name)} | ${v.icon} | v: ${chalk.green(v.version)} | udid: ${chalk.blue(v.udid)}${
            v.isDevice ? chalk.red(' (device)') : ''
        }\n`;
    });
    console.log(devicesString);
});