Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Android] Enable usage of custom instrumentation test runners #675

Merged
merged 4 commits into from
Apr 24, 2018
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions detox/src/devices/AndroidDriver.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,13 @@ class AndroidDriver extends DeviceDriverBase {
}
}

async getInstrumentationRunner(deviceId, bundleId) {
const instrumentationRunners = await this.adb.listInstrumentation(deviceId);
const expr = new RegExp(`^instrumentation:(.*) \\(target=${bundleId.replace(new RegExp('\\.', 'g'), "\\.")}\\)$`, 'gm');
const regexRes = expr.exec(instrumentationRunners);
return regexRes[1];
}

async launch(deviceId, bundleId, launchArgs) {
const args = [];
_.forEach(launchArgs, (value, key) => {
Expand All @@ -72,6 +79,8 @@ class AndroidDriver extends DeviceDriverBase {
return this.instrumentationProcess.pid;
}

const testRunner = await this.adb.getInstrumentationRunner(deviceId, bundleId)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

;

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

; missing


this.instrumentationProcess = spawn(this.adb.adbBin, [`-s`, `${deviceId}`, `shell`, `am`, `instrument`, `-w`, `-r`, `${args.join(' ')}`, `-e`, `debug`,
`false`, `${bundleId}.test/android.support.test.runner.AndroidJUnitRunner`]);
log.verbose(this.instrumentationProcess.spawnargs.join(" "));
Expand All @@ -96,7 +105,7 @@ class AndroidDriver extends DeviceDriverBase {
const call = invoke.call(invoke.Android.Class("com.wix.detox.Detox"), 'startActivityFromUrl', invoke.Android.String(params.url));
await this.invocationManager.execute(call);
}

//The other types are not yet supported.
}

Expand Down Expand Up @@ -171,7 +180,7 @@ class AndroidDriver extends DeviceDriverBase {
landscape: 1, // top at left side landscape
portrait: 0 // non-reversed portrait.
};

const call = invoke.call(invoke.Android.Class(EspressoDetox), 'changeOrientation', invoke.Android.Integer(orientationMapping[orientation]));
await this.invocationManager.execute(call);
}
Expand Down
37 changes: 37 additions & 0 deletions detox/src/devices/AndroidDriver.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
describe("AndroidDriver", () => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Drivers are not unit tested on purpose. The mostly touch command line tools and are just wrappers. Unit tests don't give much value. They are being tested in the e2e suite.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function is doing some regex voodoo so that's why I thought about adding one at least, but I'm ok with removing it.

let mockClient;
let driver;
let ADB;

beforeEach(() => {
jest.mock("npmlog");

jest.mock("./android/ADB");
ADB = require("./android/ADB");

const AndroidDriver = require("./AndroidDriver");

driver = new AndroidDriver(jest.fn());
});

it("getInstrumentationRunner", async () => {
const adbShellPmListInstrumentationOutput =
"instrumentation:com.android.emulator.smoketests/android.support.test.runner.AndroidJUnitRunner (target=com.android.emulator.smoketests)\n" +
"instrumentation:com.android.smoketest.tests/com.android.smoketest.SmokeTestRunner (target=com.android.smoketest)\n" +
"instrumentation:com.example.android.apis/.app.LocalSampleInstrumentation (target=com.example.android.apis)\n" +
"instrumentation:org.chromium.webview_shell/.WebViewLayoutTestRunner (target=org.chromium.webview_shell)\n";

const adbMockInstance = ADB.mock.instances[0];
adbMockInstance.listInstrumentation.mockReturnValue(
Promise.resolve(adbShellPmListInstrumentationOutput)
);

const result = await driver.getInstrumentationRunner(
"deviceId",
"com.example.android.apis"
);
expect(result).toEqual(
"com.example.android.apis/.app.LocalSampleInstrumentation"
);
});
});
6 changes: 5 additions & 1 deletion detox/src/devices/android/ADB.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ class ADB {
await this.adbCmd(deviceId, `install -r -g ${apkPath}`);
} else {
await this.adbCmd(deviceId, `install -rg ${apkPath}`);
}
}
}

async uninstall(deviceId, appId) {
Expand Down Expand Up @@ -102,6 +102,10 @@ class ADB {
async sleep(ms = 0) {
return new Promise((resolve, reject) => setTimeout(resolve, ms));
}

async listInstrumentation(deviceId) {
return await this.shell(deviceId, 'pm list instrumentation');
}
}

module.exports = ADB;
5 changes: 5 additions & 0 deletions detox/src/devices/android/ADB.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,5 +55,10 @@ xdescribe('ADB', () => {
await adb.unlockScreen('deviceId');
expect(exec).toHaveBeenCalledTimes(1);
});

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess we should consider dropping unit tests on ADB as well, but for now, don't delete this test

it('listInstrumentation', async () => {
await adb.listInstrumentation('deviceId');
expect(exec).toHaveBeenCalledTimes(1);
});
});