Skip to content

Commit

Permalink
Fix tests
Browse files Browse the repository at this point in the history
  • Loading branch information
mykola-mokhnach committed Sep 23, 2023
1 parent b845d72 commit c1064b3
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 27 deletions.
9 changes: 9 additions & 0 deletions lib/device-utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import Simctl from 'node-simctl';

/**
* @param {Record<string, any>} [simctlOpts]
* @returns {Promise<any[]>}
*/
export async function getDevices(simctlOpts) {
return await new Simctl(simctlOpts).getDevices();
}
38 changes: 25 additions & 13 deletions lib/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,8 @@ import _ from 'lodash';
import { exec } from 'teen_process';
import { waitForCondition } from 'asyncbox';
import { getVersion } from 'appium-xcode';
import Simctl from 'node-simctl';
import path from 'path';

import { getDevices } from './device-utils';

const DEFAULT_SIM_SHUTDOWN_TIMEOUT_MS = 30000;
const SAFARI_STARTUP_TIMEOUT_MS = 25 * 1000;
Expand Down Expand Up @@ -34,6 +33,10 @@ const BIOMETRICS = {
faceId: 'pearl',
};

/**
* @param {string} name
* @returns {string}
*/
function toBiometricDomainComponent (name) {
if (!BIOMETRICS[name]) {
throw new Error(`'${name}' is not a valid biometric. Use one of: ${JSON.stringify(_.keys(BIOMETRICS))}`);
Expand All @@ -42,25 +45,22 @@ function toBiometricDomainComponent (name) {
}

/**
* @param {Record<string, any>|undefined} [simctlOpts]
* @returns {Promise<any[]>}
* @param {string} appName
* @param {boolean} [forceKill=false]
* @returns {Promise<number>}
*/
export async function getDevices(simctlOpts) {
return await new Simctl(simctlOpts).getDevices();
}

// pgrep/pkill exit codes:
// 0 One or more processes were matched.
// 1 No processes were matched.
// 2 Invalid options were specified on the command line.
// 3 An internal error occurred.
async function pkill (appName, forceKill = false) {
let args = forceKill ? ['-9'] : [];
args.push('-x', appName);
try {
await exec('pkill', args);
return 0;
} catch (err) {
// pgrep/pkill exit codes:
// 0 One or more processes were matched.
// 1 No processes were matched.
// 2 Invalid options were specified on the command line.
// 3 An internal error occurred.
if (!_.isUndefined(err.code)) {
throw new Error(`Cannot forcefully terminate ${appName}. pkill error code: ${err.code}`);
}
Expand All @@ -69,6 +69,10 @@ async function pkill (appName, forceKill = false) {
}
}

/**
* @param {number} [timeout=DEFAULT_SIM_SHUTDOWN_TIMEOUT_MS]
* @returns {Promise<void>}
*/
async function killAllSimulators (timeout = DEFAULT_SIM_SHUTDOWN_TIMEOUT_MS) {
log.debug('Killing all iOS Simulators');
const xcodeVersion = await getVersion(true);
Expand Down Expand Up @@ -143,6 +147,11 @@ async function killAllSimulators (timeout = DEFAULT_SIM_SHUTDOWN_TIMEOUT_MS) {
}
}

/**
* @param {string} udid
* @param {Record<string, any>} [opts={}]
* @returns {Promise<any>}
*/
async function getSimulatorInfo (udid, opts = {}) {
const {
devicesSetPath
Expand All @@ -162,6 +171,9 @@ async function simExists (udid) {
return !!(await getSimulatorInfo(udid));
}

/**
* @returns {Promise<string>}
*/
async function getDeveloperRoot () {
const {stdout} = await exec('xcode-select', ['-p']);
return stdout.trim();
Expand Down
21 changes: 8 additions & 13 deletions test/unit/simulator-specs.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
// transpile:mocha

import { getSimulator } from '../../lib/simulator';
import _ from 'lodash';
import * as utilMethods from '../../lib/utils';
import * as teenProcess from 'teen_process';
import * as deviceUtils from '../../lib/device-utils';
import chai from 'chai';
import chaiAsPromised from 'chai-as-promised';
import sinon from 'sinon';
Expand All @@ -23,22 +24,16 @@ const UDID = devices['8.1'][0].udid;

describe('simulator', function () {
let xcodeMock;
let getSimInfoStub;
let getDevicesStub;

beforeEach(function () {
xcodeMock = sinon.mock(xcode);
getSimInfoStub = sinon.stub(utilMethods, 'getSimulatorInfo').callsFake(
async (udid) => {
const result = _.toPairs(devices)
.map((pair) => pair[1])
.reduce((a, b) => a.concat(b), []);
return await B.resolve(_.find(result, (dev) => dev.udid === udid));
}
);
getDevicesStub = sinon.stub(deviceUtils, 'getDevices');
getDevicesStub.returns(B.resolve(devices));
});
afterEach(function () {
xcodeMock.restore();
getSimInfoStub.restore();
getDevicesStub.restore();
});

describe('getSimulator', function () {
Expand Down Expand Up @@ -91,8 +86,8 @@ describe('simulator', function () {
sinon.stub(sim.simctl, 'getDevices').returns(B.resolve(devices));
return sim;
});
const stats = await B.all(sims.map((sim) => sim.stat()));

const stats = await B.all(sims.map((sim) => sim.stat()));
stats[0].state.should.equal('Shutdown');
stats[0].name.should.equal('Resizable iPhone');
stats[1].state.should.equal('Shutdown');
Expand Down
48 changes: 47 additions & 1 deletion test/unit/utils-specs.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@ import B from 'bluebird';
import * as TeenProcess from 'teen_process';
import xcode from 'appium-xcode';
import {
toBiometricDomainComponent, killAllSimulators,
toBiometricDomainComponent, killAllSimulators, simExists,
} from '../../lib/utils';
import * as deviceUtils from '../../lib/device-utils';
import { devices } from '../assets/deviceList';
import SimulatorXcode9 from '../../lib/simulator-xcode-9';

chai.should();
Expand Down Expand Up @@ -40,14 +42,18 @@ const XCODE_VERSION_6 = {
describe('util', function () {
let execStub;
let xcodeMock;
let getDevicesStub;

beforeEach(function () {
execStub = sinon.stub(TeenProcess, 'exec');
xcodeMock = sinon.mock(xcode);
getDevicesStub = sinon.stub(deviceUtils, 'getDevices');
getDevicesStub.returns(B.resolve(devices));
});
afterEach(function () {
execStub.restore();
xcodeMock.restore();
getDevicesStub.restore();
});

describe('killAllSimulators', function () {
Expand All @@ -67,7 +73,47 @@ describe('util', function () {
await killAllSimulators();
execStub.callCount.should.equal(2);
});
it('should call exec if pgrep does find running Simulator with Xcode6 and shutdown fails', async function () {
xcodeMock.expects('getVersion').once().withArgs(true).returns(B.resolve(XCODE_VERSION_6));
execStub.withArgs('pgrep').returns('0');
execStub.withArgs('xcrun').throws();
execStub.withArgs('pkill').returns();

try {
await killAllSimulators(500);
} catch (e) {}
execStub.callCount.should.equal(3);
});
});

describe('simExists', function () {
it('returns true if device is found', async function () {
let results = await B.all([
simExists('8F4A3349-3ABF-4597-953A-285C5C0FFD00'),
simExists('7DEA409E-159A-4730-B1C6-7C18279F72B8'),
simExists('F33783B2-9EE9-4A99-866E-E126ADBAD410'),
simExists('DFBC2970-9455-4FD9-BB62-9E4AE5AA6954'),
]);

for (let result of results) {
result.should.be.true;
}
});

it('returns false if device is not found', async function () {
let existence = [];
existence.push(simExists('A94E4CD7-D412-4198-BCD4-26799672975E'));
existence.push(simExists('asdf'));
existence.push(simExists(4));

let results = await B.all(existence);

for (let result of results) {
result.should.be.false;
}
});
});

});

describe('Device preferences verification', function () {
Expand Down

0 comments on commit c1064b3

Please sign in to comment.