Skip to content

Commit

Permalink
refactor: rename facade
Browse files Browse the repository at this point in the history
  • Loading branch information
noomorph committed Aug 23, 2022
1 parent 69e14c1 commit e7acceb
Show file tree
Hide file tree
Showing 27 changed files with 270 additions and 214 deletions.
2 changes: 2 additions & 0 deletions detox/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,8 @@ declare global {
type DetoxExportWrapper = DetoxWorker;

interface DetoxWorker {
readonly id: string;

readonly device: Device;

readonly element: ElementFacade;
Expand Down
51 changes: 32 additions & 19 deletions detox/internals.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,33 +3,40 @@

declare global {
namespace DetoxInternals {
type DetoxStatus = 'inactive' | 'init' | 'active' | 'cleanup';

type Facade = {
// region Initialization
/**
* Use with a caution, when you still have no config, yet need to avoid {@link Facade#globalSetup}
* Use with a caution, when you still have no config, yet need to avoid {@link Facade#init}
*/
resolveConfig(options?: Partial<DetoxGlobalSetupOptions>): Promise<RuntimeConfig>;
resolveConfig(options?: Partial<DetoxInitOptions>): Promise<RuntimeConfig>;

/**
*
*/
getStatus(): DetoxStatus;

/**
* This is the phase where Detox reads its configuration, starts a server.
*/
globalSetup(options?: Partial<DetoxGlobalSetupOptions>): Promise<void>;
init(options?: Partial<DetoxInitOptions>): Promise<void>;

/**
* This is the phase where Detox loads its expection library and starts a device.
* This is the phase where Detox loads its expectation library and starts a device.
*/
setup(options?: Partial<DetoxConfigurationSetupOptions>): Promise<void>;
installWorker(options?: Partial<DetoxInstallWorkerOptions>): Promise<void>;

/**
* The teardown phase deallocates the device.
* Deallocates the device.
*/
teardown(): Promise<void>;
uninstallWorker(): Promise<void>;

/**
* The global cleanup phase should happen after all the tests have finished.
* This is the phase where the Detox server shuts down.
*/
globalTeardown(): Promise<void>;
cleanup(): Promise<void>;
// endregion

// region Lifecycle
Expand Down Expand Up @@ -65,28 +72,38 @@ declare global {
readonly worker: Detox.DetoxWorker;
}

type DetoxGlobalSetupOptions = {
type DetoxInitOptions = {
cwd: string;
argv: Record<string, unknown>;
testRunnerArgv: Record<string, unknown>;
override: Partial<Detox.DetoxConfig>;
/** @inheritDoc */
global: NodeJS.Global;
/**
* Worker ID. Used to distinguish allocated workers in parallel test execution environment.
*
* If explicitly set to null, tells {@link Facade#init} to skip {@link Facade#installWorker} call.
* Useful for complex test runner integrations, where you have to install the worker via a separate call,
* when the environment is ready for that.
*
* @default 'worker'
*/
workerId: string | null;
};

type DetoxConfigurationSetupOptions = {
type DetoxInstallWorkerOptions = {
/**
* Used for integration with sandboxed test environments.
* {@link DetoxInternals.Facade#setup} might override {@link Console} methods
* to integrate it with Detox loggeing subsystem.
*/
global: NodeJS.Global;
/**
* Worker index. Used to distinguish allocated workers
* in multi-worker (parallel) test execution environment.
* Worker ID. Used to distinguish allocated workers in parallel test execution environment.
*
* Use undefined if you don't wish to allocate a device
* in a specific process.
* @default 'worker'
*/
workerIndex: undefined | number;
workerId: string;
};

type SessionState = Readonly<{
Expand All @@ -106,10 +123,6 @@ declare global {
* Retry index of the test session: 0..retriesCount.
*/
testSessionIndex: number;
/**
* TODO
*/
workerIndex: number;
/**
* TODO
*/
Expand Down
5 changes: 3 additions & 2 deletions detox/local-cli/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@ module.exports.middlewares = require('./testCommand/middlewares').default;

module.exports.handler = async function test({ detoxArgs, runnerArgs }) {
try {
await detox.globalSetup({
await detox.init({
argv: detoxArgs,
testRunnerArgv: runnerArgs,
workerId: null,
});

const runnerCommand = new TestRunnerCommand()
Expand All @@ -21,6 +22,6 @@ module.exports.handler = async function test({ detoxArgs, runnerArgs }) {

await runnerCommand.execute();
} finally {
await detox.globalTeardown();
await detox.cleanup();
}
};
2 changes: 1 addition & 1 deletion detox/runners/jest/globalSetup.js
Original file line number Diff line number Diff line change
@@ -1 +1 @@
module.exports = async () => require('../../internals').globalSetup();
module.exports = async () => require('../../internals').init({ workerId: null });
2 changes: 1 addition & 1 deletion detox/runners/jest/globalTeardown.js
Original file line number Diff line number Diff line change
@@ -1 +1 @@
module.exports = async () => require('../../internals').globalTeardown();
module.exports = async () => require('../../internals').cleanup();
20 changes: 16 additions & 4 deletions detox/runners/jest/testEnvironment/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ class DetoxCircusEnvironment extends NodeEnvironment {
SpecReporter,
WorkerAssignReporter,
};
/** @private */
this._shouldManageDetox = detox.getStatus() === 'inactive';
/** @protected */
this.testPath = context.testPath;
/** @protected */
Expand Down Expand Up @@ -115,15 +117,25 @@ class DetoxCircusEnvironment extends NodeEnvironment {
* @protected
*/
async initDetox() {
await detox.setup({
const opts = {
global: this.global,
workerIndex: +(process.env.JEST_WORKER_ID || '1'),
});
workerId: `worker-${process.env.JEST_WORKER_ID}`,
};

if (this._shouldManageDetox) {
await detox.init(opts);
} else {
await detox.installWorker(opts);
}
}

/** @protected */
async cleanupDetox() {
await detox.teardown();
if (this._shouldManageDetox) {
await detox.cleanup();
} else {
await detox.uninstallWorker();
}
}

/** @private */
Expand Down
2 changes: 2 additions & 0 deletions detox/src/DetoxWorker.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ class DetoxWorker {
onError: this._onEmitError.bind(this),
});

/** @type {string} */
this.id = 'worker';
/** @type {Detox.Device} */
this.device = null;
/** @type {Detox.ElementFacade} */
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
const session = () => require('../../../../../../../internals').session;
const internals = () => require('../../../../../../../internals');

class GenyInstanceNaming {
generateName() {
const { id, workerIndex } = session();
return `Detox.${id}.${workerIndex}`;
const { session, worker } = internals();
return `Detox.${session.id}.${worker.id}`;
}

isFamilial(name) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,31 +1,32 @@
jest.mock('../../../../../../../internals', () => ({}));

describe('Genymotion-Cloud instance unique-name strategy', () => {
let sessionId, workerIndex;
let sessionId, workerId;

function uut() {
const GenyInstanceNaming = require('./GenyInstanceNaming');
return new GenyInstanceNaming();
}

beforeEach(() => {
Object.defineProperty(require('../../../../../../../internals'), 'session', {
get: () => ({ id: sessionId, workerIndex }),
Object.defineProperties(require('../../../../../../../internals'), {
session: { get: () => ({ id: sessionId }) } ,
worker: { get: () => ({ id: workerId }) } ,
});
});

it('should generate a session-scope unique name', () => {
sessionId = '71dd7a96-bdd7-480a-b4a0-fd265fb208cd';
workerIndex = 1;
workerId = 'worker-1';

expect(uut().generateName()).toBe('Detox.71dd7a96-bdd7-480a-b4a0-fd265fb208cd.1');
expect(uut().generateName()).toBe('Detox.71dd7a96-bdd7-480a-b4a0-fd265fb208cd.worker-1');
});

it('should accept only the same session and worker id as a familial device', () => {
sessionId = 'session';
workerIndex = 3;
workerId = 'worker-3';

expect(uut().isFamilial('Detox.session.3')).toEqual(true);
expect(uut().isFamilial('Detox.session.2')).toEqual(false);
expect(uut().isFamilial('Detox.session.worker-3')).toEqual(true);
expect(uut().isFamilial('Detox.session.worker-2')).toEqual(false);
});
});
5 changes: 2 additions & 3 deletions detox/src/ipc/IPCClient.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,8 @@ class IPCClient {
return this.sessionState.detoxIPCServer;
}

async registerWorker(workerIndex) {
this._state.workerIndex = workerIndex;
await this._emit('registerWorker', { workerIndex });
async registerWorker(workerId) {
await this._emit('registerWorker', { workerId });
}

/**
Expand Down
12 changes: 8 additions & 4 deletions detox/src/ipc/IPCServer.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ class IPCServer {
this._sessionState = sessionState;
this._logger = logger.child({ __filename, cat: 'ipc' });
this._ipc = null;
this._workers = new Set();
}

get id() {
Expand Down Expand Up @@ -62,13 +63,16 @@ class IPCServer {
});
}

onRegisterWorker({ workerIndex }, socket = null) {
onRegisterWorker({ workerId }, socket = null) {
const workersCount = this._workers.add(workerId).size;
const shouldBroadcast = workersCount > this._sessionState.workersCount;
this._sessionState.workersCount = workersCount;

if (socket) {
this._ipc.server.emit(socket, 'registerWorkerDone', {});
this._ipc.server.emit(socket, 'registerWorkerDone', { workersCount });
}

if (workerIndex > this._sessionState.workersCount) {
const workersCount = this._sessionState.workersCount = workerIndex;
if (shouldBroadcast) {
this._ipc.server.broadcast('sessionStateUpdate', { workersCount });
}
}
Expand Down
2 changes: 0 additions & 2 deletions detox/src/ipc/state.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ class SecondarySessionState extends SessionState {
failedTestFiles = [],
testFilesToRetry = [],
testSessionIndex = 0,
workerIndex = undefined,
workersCount = 0
}) {
super();
Expand All @@ -58,7 +57,6 @@ class SecondarySessionState extends SessionState {
this.failedTestFiles = failedTestFiles;
this.testFilesToRetry = testFilesToRetry;
this.testSessionIndex = testSessionIndex;
this.workerIndex = workerIndex;
this.workersCount = workersCount;
}
}
Expand Down

0 comments on commit e7acceb

Please sign in to comment.