Bamieh/reflow

View on GitHub
packages/reflow-appium/lib/devices.js

Summary

Maintainability
F
3 days
Test Coverage
const childProcess = require('child_process');
const util = require('util');
const execAsync = util.promisify(childProcess.exec);
const plist = require('plist');

async function systemProfiler(dataTypes) {

  const result = await execAsync('/usr/sbin/system_profiler -xml -detailLevel mini ' + dataTypes.join(' '));

  return plist.parse(result.stdout.toString()).reduce((acc, sec) => {
    return acc.concat({
      name: sec._dataType,
      items: sec._items[0],
      properties: sec._properties
    });
  }, []);
}


const adb = require('adbkit')
const client = adb.createClient()

function getAndroidFeatures(devices) {
  return Promise.all(
    devices
      .filter(device => device.type !== 'unauthorized')
      .map(device => {
        return client.getFeatures(device.id).then(features => {
          return {...device, features}
        });
    }));
}
function getAndroidProperties(devices) {
  return Promise.all(
    devices
      .filter(device => device.type !== 'unauthorized')
      .map(device => {
        return client.getProperties(device.id).then(properties => {
          return {...device, properties}
        });
    }));
}

const INSTRUMENTS_RE = /((.{0,})\((.{0,})\)\s{0,}\s\[(.{0,})])|(((.{0,})\((.{0,})\))(\s-*\s*(.*)))|((\w+ \w+ -)(\s-*\s*(.*)))|((\w*\s\-)(.*))/;
function extractDeviceDetails(line) {
  const match = line.match(INSTRUMENTS_RE);
  if(!match) return null;
  const uuid = match[4];
  const platformVersion = match[3];
  const deviceName = `${match[2]}${match[3]}`;
  return {
    line,
    uuid,
    platformVersion,
    deviceName,
  }
}
async function getIOSDevices() {
  console.log('Getting iOS Devices.');
  const result = await execAsync('xcrun instruments -s devices');
  const devices = result.stdout
    .split('\n')
    .filter(line => !/^(Known Devices:|)$/.test(line))

  const simulators = devices.filter(device => /\(Simulator\)/.test(device));
  const connected = devices.filter(device => !/\(Simulator\)/.test(device));

  return {
    simulators: simulators.map(extractDeviceDetails).filter(Boolean),
    realDevices: connected.map(extractDeviceDetails).filter(Boolean).filter(device => !device.uuid.includes('-')),
  }
}

async function getAndroidDevices() {
  console.log('Getting Android Devices.');

  return client.listDevices()
    .then(getAndroidFeatures)
    .then(getAndroidProperties)
  // const devices =  await client.listDevices();
  // console.log('devices::', devices)

  // const withFeatures = await getAndroidFeatures(devices);
  // const features = await getAndroidProperties(withFeatures);

  // console.log('features::', features)

  // const devices = result.stdout
  //   .split('\n')
  //   .filter(line => {
  //     return line !== '' && line !== 'List of devices attached'
  //   })
  //   .map(line => {
  //     console.log('line::', line)
  //     return /^(.+?)\s*?(.*)$/.match(line);
  //   })

  // const result = await execAsync('adb -t 2 shell getprop ro.build.version.release');
  // const result = await execAsync('adb -t 2 shell getprop ro.build.version.release');

}


function pluckDevices(dataTypes) {
  return dataTypes
    .find(dataType => dataType.name === 'SPUSBDataType')
    .items._items
    .filter(item => !!item.serial_num);
}
function addAppiumCaps(devices) {

}

async function getAllConnectedDevices() {
  console.log('Detecting devices.');
  return {
    android: await getAndroidDevices(),
    ios: await getIOSDevices(),
  }

  // return systemProfiler(['SPUSBDataType'])
  //   .then(pluckDevices)
  //   .then(addAppiumCaps);
}



module.exports = async function() {
  try {
    return {
      android: await getAndroidDevices(),
      ios: await getIOSDevices(),
    };
  } catch(err) {
    throw {
      description: 'Error getting devices.',
      message: err.message,
    };
  }
}