Code coverage report for appium-instruments/lib/utils.js

Statements: 91.19% (145 / 159)      Branches: 86.44% (51 / 59)      Functions: 88.24% (15 / 17)      Lines: 73.47% (36 / 49)      Ignored: 30 statements, 2 functions, 17 branches     

All files » appium-instruments/lib/ » utils.js
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 129 130 131 132                  1 1   1 2   2 2 2       2       2       1 1 1 1 1   1 1       1 3         1 1           1               1     13 4 4         13 9       13     1 2 2   1   2             1                                         1                                    
import path from 'path';
import { exec } from 'teen_process';
import { fs } from 'appium-support';
import log from './logger';
import xcode from 'appium-xcode';
import _ from 'lodash';
import Instruments from './instruments';
 
 
const rootDir = path.resolve(__dirname, '../..');
const INST_STALL_TIMEOUT = 12000;
 
async function getInstrumentsPath () {
  let instrumentsPath;
  try {
    let {stdout} = await exec('xcrun', ['-find', 'instruments']);
    stdout = stdout || '';
    instrumentsPath = stdout.trim().replace('\n$', '');
  } catch (err) {
    if (err) log.error(err.message);
  }
  Iif (!instrumentsPath) {
    log.errorAndThrow('Could not find the instruments binary. Please ensure ' +
                      '`xcrun -find instruments` can locate it.');
  }
  log.debug(`Instruments is at: ${instrumentsPath}`);
  return instrumentsPath;
}
 
async function getAvailableDevices () {
  log.debug('Getting list of devices instruments supports');
  let instrumentsPath = await getInstrumentsPath();
  let opts = {timeout: INST_STALL_TIMEOUT};
  let lines;
  try {
    let {stdout} = await exec(instrumentsPath, ['-s', 'devices'], opts);
    lines = stdout.split('\n');
  } catch (err) {
    log.errorAndThrow(`Failed getting devices, err: ${err}.`);
  }
  let devices = lines.filter((line) => {
    return /^i.+$/.test(line);
  });
  return devices;
}
 
async function killAllInstruments () {
  log.debug("Killing all instruments");
  try {
    await exec('pkill',  ['-f', 'instruments']);
  } catch (ign) {}
}
 
async function cleanAllTraces () {
  if (process.env.CLEAN_TRACES) {
    try {
      await exec('rm', ['-rf', 'instrumentscli*.trace']);
    } catch (ign) {}
  }
}
 
function parseLaunchTimeout (launchTimeout) {
  // number or object like { global: 40000, afterSimLaunch: 5000 }
  // may also parse JSON strings.
  if (_.isString(launchTimeout)) {
    try {
      launchTimeout = JSON.parse(launchTimeout);
    } catch (err) {
      log.warn(`Invalid launch timeout: ${launchTimeout}`);
    }
  }
  if (_.isNumber(launchTimeout)) {
    launchTimeout = {
      global: launchTimeout
    };
  }
  return launchTimeout;
}
 
async function getIwdPath(xcodeMajorVersion) {
  let thirdpartyPath = path.resolve(rootDir, 'thirdparty');
  let iwdPath = path.resolve(thirdpartyPath, `iwd${xcodeMajorVersion}`);
  if (!await fs.exists(iwdPath)) {
    iwdPath = path.resolve(thirdpartyPath, 'iwd');
  }
  log.debug(`Found Insruments-Without-Delay: ${iwdPath}`);
  return iwdPath;
}
 
// this function launches an instruments test with a default test
// that immediately passes. In this way we can start a simulator
// and be notified when it completely launches
async function quickLaunch (udid, appPath = path.resolve(__dirname, '..', '..', 'assets', 'TestApp.app')) {
  let traceTemplatePath = await xcode.getAutomationTraceTemplatePath();
  let scriptPath = path.resolve(__dirname, '..', '..', 'assets', 'blank_instruments_test.js');
  let traceDocument = path.resolve('/', 'tmp', 'testTrace.trace');
  let resultsPath = path.resolve('/', 'tmp');
 
  // the trace document can be in a weird state
  // but we never do anything with it, so delete
  await fs.rimraf(traceDocument);
 
  let args = ['instruments',
              '-D', traceDocument,
               '-t', traceTemplatePath,
               '-w', udid,
               appPath,
               '-e', 'UIASCRIPT', scriptPath,
               '-e', 'UIARESULTSPATH', resultsPath];
  log.debug(`Running command: 'xcrun ${args.join(' ')}'`);
  await exec('xcrun', args);
}
 
async function quickInstruments (opts) {
  opts = _.cloneDeep(opts);
  let xcodeTraceTemplatePath = await xcode.getAutomationTraceTemplatePath();
  _.defaults(opts, {
        launchTimeout: 60000,
        template: xcodeTraceTemplatePath,
        withoutDelay: true,
        xcodeVersion: '8.1',
        webSocket: null,
        flakeyRetries: true,
        logNoColors: false,
  });
  return new Instruments(opts);
}
 
export { rootDir, killAllInstruments, cleanAllTraces,
         getInstrumentsPath, getAvailableDevices, parseLaunchTimeout,
         getIwdPath, quickLaunch, quickInstruments };