All files / src/platformTools/apple deviceManager.js

19.78% Statements 18/91
0% Branches 0/55
0% Functions 0/10
20% Lines 14/70

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 1234x 4x 4x 4x       4x     4x   4x               4x   4x                                                                                       4x                                                         4x     4x                 4x                           4x  
import inquirer from 'inquirer';
import chalk from 'chalk';
import child_process from 'child_process';
import {
    getAppFolder,
    isPlatformActive,
} from '../../common';
import { logToSummary, logTask,
    logError,
    logWarning, logDebug } from '../../systemTools/logger';
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 = async (c, platform, target) => {
    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);
        return selectedDevice.name;
    }
 
    logWarning(`Your specified simulator target ${chalk.white(target)} doesn't exists`);
    const devices = devicesArr.map(v => ({ name: `${v.name} | ${v.icon} | v: ${chalk.green(v.version)} | udid: ${chalk.grey(v.udid)}${v.isDevice ? chalk.red(' (device)') : ''}`, value: v }));
 
    const { sim } = await inquirer.prompt({
        name: 'sim',
        message: 'Select the simulator you want to launch',
        type: 'list',
        choices: devices
    });
 
    if (sim) {
        _launchSimulator(sim);
        return sim.name;
    }
    return Promise.reject('Action canceled!');
};
 
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 = '';
    devicesArr.forEach((v, i) => {
        devicesString += ` [${i + 1}]> ${chalk.bold(v.name)} | ${v.icon} | v: ${chalk.green(v.version)} | udid: ${chalk.grey(v.udid)}${
            v.isDevice ? chalk.red(' (device)') : ''
        }\n`;
    });
 
    logToSummary(`${platform} Targets:\n\n${devicesString}`);
 
    resolve();
});