diff --git a/detox/src/Detox.js b/detox/src/Detox.js index 1e344aa0c8..64244ed5f7 100644 --- a/detox/src/Detox.js +++ b/detox/src/Detox.js @@ -3,6 +3,7 @@ const Device = require('./devices/Device'); const IosDriver = require('./devices/IosDriver'); const SimulatorDriver = require('./devices/SimulatorDriver'); const EmulatorDriver = require('./devices/EmulatorDriver'); +const AttachedAndroidDriver = require('./devices/AttachedAndroidDriver'); const argparse = require('./utils/argparse'); const configuration = require('./configuration'); const Client = require('./client/Client'); @@ -18,7 +19,8 @@ log.heading = 'detox'; const DEVICE_CLASSES = { 'ios.simulator': SimulatorDriver, 'ios.none': IosDriver, - 'android.emulator': EmulatorDriver + 'android.emulator': EmulatorDriver, + 'android.attached': AttachedAndroidDriver, }; class Detox { diff --git a/detox/src/devices/AndroidDriver.js b/detox/src/devices/AndroidDriver.js index 31947db8cd..943251b12c 100644 --- a/detox/src/devices/AndroidDriver.js +++ b/detox/src/devices/AndroidDriver.js @@ -110,6 +110,27 @@ class AndroidDriver extends DeviceDriverBase { return 'android'; } + async findDeviceId(filter) { + const adbDevices = await this.adb.devices(); + const filteredDevices = _.filter(adbDevices, filter); + + let adbName; + switch (filteredDevices.length) { + case 1: + const adbDevice = filteredDevices[0]; + adbName = adbDevice.adbName; + break; + case 0: + throw new Error(`Could not find '${name}' on the currently ADB attached devices, + try restarting adb 'adb kill-server && adb start-server'`); + break; + default: + throw new Error(`Got more than one device corresponding to the name: ${name}`); + } + + return adbName; + } + async setURLBlacklist(urlList) { const call = invoke.call(invoke.Android.Class(EspressoDetox), 'setURLBlacklist', urlList); await this.invocationManager.execute(call); diff --git a/detox/src/devices/AttachedAndroidDriver.js b/detox/src/devices/AttachedAndroidDriver.js new file mode 100644 index 0000000000..d55e14383e --- /dev/null +++ b/detox/src/devices/AttachedAndroidDriver.js @@ -0,0 +1,19 @@ +const Emulator = require('./android/Emulator'); +const AndroidDriver = require('./AndroidDriver'); + +class AttachedAndroidDriver extends AndroidDriver { + + constructor(client) { + super(client); + + this.emulator = new Emulator(); + } + + async acquireFreeDevice(name) { + const deviceId = await this.findDeviceId({name: name}); + await this.adb.unlockScreen(deviceId); + return deviceId; + } +} + +module.exports = AttachedAndroidDriver; \ No newline at end of file diff --git a/detox/src/devices/EmulatorDriver.js b/detox/src/devices/EmulatorDriver.js index 1751d3b0bf..cf618647da 100644 --- a/detox/src/devices/EmulatorDriver.js +++ b/detox/src/devices/EmulatorDriver.js @@ -36,25 +36,9 @@ class EmulatorDriver extends AndroidDriver { await this.emulator.boot(name); - const adbDevices = await this.adb.devices(); - const filteredDevices = _.filter(adbDevices, {type: 'emulator', name: name}); - - let adbName; - switch (filteredDevices.length) { - case 1: - const adbDevice = filteredDevices[0]; - adbName = adbDevice.adbName; - break; - case 0: - throw new Error(`Could not find '${name}' on the currently ADB attached devices, - try restarting adb 'adb kill-server && adb start-server'`); - break; - default: - throw new Error(`Got more than one device corresponding to the name: ${name}`); - } - - await this.adb.unlockScreen(adbName); - return adbName; + const deviceId = await this.findDeviceId({type: 'emulator', name: name}); + await this.adb.unlockScreen(deviceId); + return deviceId; } async shutdown(deviceId) { diff --git a/docs/Introduction.Android.md b/docs/Introduction.Android.md index aa559ee737..f9bf6c1199 100644 --- a/docs/Introduction.Android.md +++ b/docs/Introduction.Android.md @@ -77,6 +77,13 @@ Add this part to your `package.json`: } ``` +Following device types could be used to control Android devices: + +`android.emulator`. Boot stock SDK emulator with provided `name`, for example `Nexus_5X_API_25`. After booting connect to it. + +`android.attached`. Connect to already-attached android device. The device should be listed in the output of `adb devices` command under provided `name`. +Use this type to connect to Genymotion emulator. + ### 7. Run the tests Using the `android.emu.debug` configuration from above, you can invoke it in the standard way. diff --git a/docs/More.AndroidSupportStatus.md b/docs/More.AndroidSupportStatus.md index c04a30a935..90ecdcf89f 100644 --- a/docs/More.AndroidSupportStatus.md +++ b/docs/More.AndroidSupportStatus.md @@ -58,7 +58,19 @@ All Core APIs are 100% implemented. ## Emulator control 1. **Emulators** are fully supported, to choose an emulator to run your tests on check `emulator -list-avds`. If none exist, create one. 2. **Devices** - Coming soon! -3. **Genymotion** - Coming a bit later... +3. **Genymotion** +To utilize Genymotion you should use 'android.attached' as configuration type parameter and Genymotion emulator name as configuration name parameter. For example, + +```json +"android": { + "binaryPath": "./android/app/build/outputs/apk/app-debug.apk", + "build": "pushd ./android && ./gradlew assembleDebug assembleAndroidTest -DtestBuildType=debug && popd", + "type": "android.attached", + "name": "192.168.57.101:5555" +} +``` + +Type 'android.attached' could be used to connect to any of already attached devices that are visible through 'adb devices' command. ## Mocking 1. Deep Links - Done