Skip to content

Commit

Permalink
Session per configuration (#173)
Browse files Browse the repository at this point in the history
Support for session per configuration
  • Loading branch information
silyevsk authored and rotemmiz committed Jun 25, 2017
1 parent bbf909f commit 124afe6
Show file tree
Hide file tree
Showing 4 changed files with 149 additions and 61 deletions.
89 changes: 49 additions & 40 deletions detox/src/Detox.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,33 +20,30 @@ class Detox {
throw new Error(`No configuration was passed to detox, make sure you pass a config when calling 'detox.init(config)'`);
}

this.client = null;
this.userConfig = userConfig;
this.detoxConfig = {};
this.client = null;
this.device = null;
}

async config() {
async init() {
if (!(this.userConfig.configurations && _.size(this.userConfig.configurations) >= 1)) {
throw new Error(`no configured devices`);
}

this.detoxConfig.configurations = this.userConfig.configurations;
const deviceConfig = await this._getDeviceConfig();
const [session, shouldStartServer] = await this._chooseSession(deviceConfig);
const deviceClass = await this._chooseDeviceClass(deviceConfig);

if (this.userConfig.session) {
configuration.validateSession(this.userConfig.session);
this.detoxConfig.session = this.userConfig.session;
} else {
this.detoxConfig.session = await configuration.defaultSession();
const server = new DetoxServer(new URL(this.detoxConfig.session.server).port);
if(shouldStartServer) {
this.server = new DetoxServer(new URL(session.server).port);
}
return this.detoxConfig;
}

async init() {
await this.config();
this.client = new Client(this.detoxConfig.session);
await this.client.connect();
await this.initConfiguration();
const client = new Client(session);
await client.connect();
await this._initIosExpectations(client);
await this._setDevice(session, deviceClass, deviceConfig, client);

this.client = client
}

async cleanup() {
Expand All @@ -59,53 +56,65 @@ class Detox {
}
}

async initConfiguration() {
async _chooseSession(deviceConfig) {
var session = deviceConfig.session;
var shouldStartServer = false;

if(!session) {
session = this.userConfig.session;
}

if(!session) {
session = await configuration.defaultSession();
shouldStartServer = true;
}

configuration.validateSession(session);

return [session, shouldStartServer];
}

async _getDeviceConfig() {
const configurationName = argparse.getArgValue('configuration');
const configurations = this.userConfig.configurations;

let deviceConfig;
if (!configurationName && _.size(this.detoxConfig.configurations) === 1) {
deviceConfig = _.values(this.detoxConfig.configurations)[0];
if (!configurationName && _.size(configurations) === 1) {
deviceConfig = _.values(configurations)[0];
} else {
deviceConfig = this.detoxConfig.configurations[configurationName];
deviceConfig = configurations[configurationName];
}

if (!deviceConfig) {
throw new Error(`Cannot determine which configuration to use. use --configuration to choose one of the following:
${Object.keys(this.detoxConfig.configurations)}`);
${Object.keys(configurations)}`);
}

return deviceConfig;
}

async _chooseDeviceClass(deviceConfig)
{
switch (deviceConfig.type) {
case "ios.simulator":
await this.initIosSimulator(deviceConfig);
break;
return Simulator;
case "ios.none":
await this.initIosNoneDevice(deviceConfig);
break;
return IosNoneDevice;
default:
throw new Error('only simulator is supported currently');
}
}

async setDevice(device, deviceConfig) {
this.device = new device(this.client, this.detoxConfig.session, deviceConfig);
async _setDevice(session, deviceClass, deviceConfig, client) {
this.device = new deviceClass(client, session, deviceConfig);
await this.device.prepare();
global.device = this.device;
}

async initIosExpectations() {
async _initIosExpectations(client) {
this.expect = require('./ios/expect');
this.expect.exportGlobals();
this.expect.setInvocationManager(new InvocationManager(this.client));
}

async initIosSimulator(deviceConfig) {
await this.initIosExpectations();
await this.setDevice(Simulator, deviceConfig);
}

async initIosNoneDevice(deviceConfig) {
await this.initIosExpectations();
await this.setDevice(IosNoneDevice, deviceConfig);
this.expect.setInvocationManager(new InvocationManager(client));
}
}

Expand Down
66 changes: 49 additions & 17 deletions detox/src/Detox.test.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,31 @@
import _ from 'lodash';

const schemes = require('./configurations.mock');

describe('Detox', () => {
let Detox;
let detox;
let minimist;
let clientMockData = {lastConstructorArguments: null};
let simulatorMockData = {lastConstructorArguments: null};

beforeEach(async () => {
function setCustomMock(modulePath, dataObject) {
const JestMock = jest.genMockFromModule(modulePath);
class FinalMock extends JestMock {
constructor() {
super(...arguments);
dataObject.lastConstructorArguments = arguments;
}
}
jest.setMock(modulePath, FinalMock);
}

jest.mock('minimist');
minimist = require('minimist');
jest.mock('./ios/expect');
jest.mock('./client/Client');
jest.mock('./devices/Simulator');
setCustomMock('./client/Client', clientMockData);
setCustomMock('./devices/Simulator', simulatorMockData);
jest.mock('detox-server');
});

Expand Down Expand Up @@ -64,17 +79,15 @@ describe('Detox', () => {
Detox = require('./Detox');
detox = new Detox(schemes.validOneDeviceNoSession);
await detox.init();

expect(detox.detoxConfig.session.server).toBeDefined();
expect(clientMockData.lastConstructorArguments[0]).toBeDefined();
});

it(`One valid device, detox should use session config and default to this device`, async () => {
Detox = require('./Detox');
detox = new Detox(schemes.validOneDeviceAndSession);
await detox.init();

expect(detox.detoxConfig.session.server).toBe(schemes.validOneDeviceAndSession.session.server);
expect(detox.detoxConfig.session.sessionId).toBe(schemes.validOneDeviceAndSession.session.sessionId);
expect(clientMockData.lastConstructorArguments[0]).toBe(schemes.validOneDeviceAndSession.session);
});

it(`Two valid devices, detox should init with the device passed in '--configuration' cli option`, async () => {
Expand All @@ -84,17 +97,7 @@ describe('Detox', () => {
detox = new Detox(schemes.validTwoDevicesNoSession);
await detox.init();

expect(detox.detoxConfig.configurations).toEqual(schemes.validTwoDevicesNoSession.configurations);
});

it(`Two valid devices, detox should init an ios.none device`, async () => {
mockCommandLineArgs({configuration: 'ios.sim.none'});
Detox = require('./Detox');

detox = new Detox(schemes.validOneIosNoneDeviceNoSession);
await detox.init();

expect(detox.detoxConfig.configurations).toEqual(schemes.validOneIosNoneDeviceNoSession.configurations);
expect(simulatorMockData.lastConstructorArguments[2]).toEqual(schemes.validTwoDevicesNoSession.configurations['ios.sim.debug']);
});

it(`Two valid devices, detox should throw if device passed in '--configuration' cli option doesn't exist`, async () => {
Expand Down Expand Up @@ -142,6 +145,35 @@ describe('Detox', () => {
detox.cleanup();
});

it(`Detox should use session defined per configuration - none`, async () => {
mockCommandLineArgs({configuration: 'ios.sim.none'});
Detox = require('./Detox');
detox = new Detox(schemes.sessionPerConfiguration);
await detox.init();

let expectedSession = schemes.sessionPerConfiguration.configurations['ios.sim.none'].session;
expect(clientMockData.lastConstructorArguments[0]).toBe(expectedSession);
});

it(`Detox should use session defined per configuration - release`, async () => {
mockCommandLineArgs({configuration: 'ios.sim.release'});
Detox = require('./Detox');
detox = new Detox(schemes.sessionPerConfiguration);
await detox.init();

let expectedSession = schemes.sessionPerConfiguration.configurations['ios.sim.release'].session;
expect(clientMockData.lastConstructorArguments[0]).toBe(expectedSession);
});

it(`Detox should prefer session defined per configuration over common session`, async () => {
Detox = require('./Detox');
detox = new Detox(schemes.sessionInCommonAndInConfiguration);
await detox.init();

let expectedSession = schemes.sessionInCommonAndInConfiguration.configurations['ios.sim.none'].session;
expect(clientMockData.lastConstructorArguments[0]).toBe(expectedSession);
});

function mockCommandLineArgs(args) {
minimist.mockReturnValue(args);
}
Expand Down
47 changes: 45 additions & 2 deletions detox/src/configurations.mock.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const validOneIosNoneDeviceNoSession = {
"binaryPath": "ios/build/Build/Products/Release-iphonesimulator/example.app",
"type": "ios.none",
"name": "iPhone 7 Plus, iOS 10.2"
}
},
}
};

Expand Down Expand Up @@ -101,6 +101,47 @@ const invalidOneDeviceTypeEmulatorNoSession = {
}
};

const sessionPerConfiguration = {
"configurations": {
"ios.sim.none": {
"binaryPath": "ios/build/Build/Products/Release-iphonesimulator/example.app",
"type": "ios.none",
"name": "iPhone 7 Plus, iOS 10.2",
"session": {
"server": "ws://localhost:1111",
"sessionId": "test_1111"
}
},
"ios.sim.release": {
"binaryPath": "ios/build/Build/Products/Release-iphonesimulator/example.app",
"type": "ios.none",
"name": "iPhone 7 Plus, iOS 10.2",
"session": {
"server": "ws://localhost:2222",
"sessionId": "test_2222"
}
}
}
};

const sessionInCommonAndInConfiguration = {
"session": {
"server": "ws://localhost:1111",
"sessionId": "test_1"
},
"configurations": {
"ios.sim.none": {
"binaryPath": "ios/build/Build/Products/Release-iphonesimulator/example.app",
"type": "ios.none",
"name": "iPhone 7 Plus, iOS 10.2",
"session": {
"server": "ws://localhost:2222",
"sessionId": "test_2"
}
}
}
};

module.exports = {
validOneDeviceNoSession,
validOneIosNoneDeviceNoSession,
Expand All @@ -112,5 +153,7 @@ module.exports = {
validOneDeviceAndSession,
invalidSessionNoSessionId,
invalidSessionNoServer,
invalidOneDeviceTypeEmulatorNoSession
invalidOneDeviceTypeEmulatorNoSession,
sessionPerConfiguration,
sessionInCommonAndInConfiguration
};
8 changes: 6 additions & 2 deletions detox/test/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,12 @@
},
"ios.none": {
"type": "ios.none",
"name": "iPhone 7 Plus"
}
"name": "iPhone 7 Plus",
"session": {
"server": "ws://localhost:8099",
"sessionId": "test"
}
}
}
}
}

0 comments on commit 124afe6

Please sign in to comment.