Unable to run test case using detox - react-native

I am facing the error below when running test case using detox.
I had all dependencies installed as part of it.
Can't find a simulator to match with " iPhone 6 ", run 'xcrun simctl list' to list your supported devices.
configuration="ios.sim.debug" artifactsLocation="artifacts/ios.sim.debug.2019-01-31 12-14-41Z" node_modules/.bin/jest "e2e" --config=e2e/config.json --maxWorkers=1 '--testNamePattern=^((?!:android:).)*$'
detox[5864] INFO: [DetoxServer.js] server listening on localhost:57598...
detox[5864] ERROR: [index.js/DETOX_INIT_ERROR]
Error: Can't find a simulator to match with " iPhone 6 ", run 'xcrun simctl list' to list your supported devices.
It is advised to only state a device type, and not to state iOS version, e.g. "iPhone 7"
at AppleSimUtils.findDevicesUDID (/Users/alok/Desktop/malliswari/accordion/node_modules/detox/src/devices/ios/AppleSimUtils.js:46:13)
at process._tickCallback (internal/process/next_tick.js:68:7)

This is caused by setting the simulator in your detox config in your package.json to one that isn't on your system
"detox": {
"configurations": {
"ios.sim.debug": {
"binaryPath": "ios/build/Build/Products/Debug-iphonesimulator/myapp.app",
"build": "RN_SRC_EXT=e2e.js xcodebuild -workspace ios/myapp.xcworkspace -scheme myapp -configuration Debug -sdk iphonesimulator -derivedDataPath ios/build",
"type": "ios.simulator",
"name": "iPhone 7" // <- this is where you define your simulator
}
},
You should run xcrun simctl list in your terminal to see which simulators are available. Then use one of the available ones in your detox configuration. Chances are you should be able to change it to "iPhone 7" or "iPhone 8"

Another possible solution is here
https://github.com/wix/Detox/issues/1103
We need to upgrade AppleSimUtils. In case if you have issues in upgrading check out here

Related

Testing an Android .apk that's built from Expo's Turtle CLI with Detox

I'm hoping to confirm my thought process when trying to test an Android application that's built with Expo's Turtle-CLI tool. I've got iOS running well, just need help getting Android working.
I have a build process that will spit out an .apk to build/android.apk. Here's the command that does that
turtle build:android \
--output $BUILD_DIR/android.apk \
--username $EXPO_USERNAME \
--password $EXPO_PASSWORD \
--config app.config.ts \
--release-channel $RELEASE_CHANNEL \
--type apk \
--mode debug
This successfully outputs the .apk in build.
Here is my detoxrc.json configuration
{
"testRunner": "jest",
"runnerConfig": "e2e/config.json",
"configurations": {
"ios": {
"type": "ios.simulator",
"binaryPath": "build/app-native.app",
"build": "./scripts/build_test_app ios",
"device": {
"type": "iPhone 11"
}
},
"android": {
"type": "android.attached",
"binaryPath": "build/android.apk",
"testBinaryPath": "build/android.apk",
"build": "./scripts/build_test_app android",
"device": {
"adbName": "059aaa47"
}
}
}
}
I then attempt to run my tests with
detox test --configuration android --loglevel trace
Which then yields (more logs at the bottom of this post)
No instrumentation runner found on device 059aaa47 for package com.foobar.mobilern
at ADB.getInstrumentationRunner (../node_modules/detox/src/devices/drivers/android/exec/ADB.js:250:13)
at Instrumentation.launch (../node_modules/detox/src/devices/drivers/android/tools/Instrumentation.js:19:24)
at MonitoredInstrumentation.launch (../node_modules/detox/src/devices/drivers/android/tools/MonitoredInstrumentation.js:18:5)
at AttachedAndroidDriver._launchInstrumentationProcess (../node_modules/detox/src/devices/drivers/android/AndroidDriver.js:284:5)
at AttachedAndroidDriver._launchApp (../node_modules/detox/src/devices/drivers/android/AndroidDriver.js:267:7)
at AttachedAndroidDriver._handleLaunchApp (../node_modules/detox/src/devices/drivers/android/AndroidDriver.js:120:7)
at AttachedAndroidDriver.launchApp (../node_modules/detox/src/devices/drivers/android/AndroidDriver.js:91:12)
at Device._doLaunchApp (../node_modules/detox/src/devices/Device.js:85:19)
at traceCall (../node_modules/detox/src/utils/trace.js:41:20)
If I omit the testBinaryPath key from .detoxrc.json, then I get this result.
Running adb -s 059aaa47 shell pm list instrumentation on the test device yields an empty response, so I'm inclined to believe that some testing setup isn't being completed thoroughly and/or perhaps I'm thinking about this wrong.
I guess the gist of my question is, is it possible to test one .apk without having to make use of some sort of testing harness / binary?
Full Log Output

React Native E2E w/ Detox error: "Failed to run application on the device"

I have a starter app created with React Native CLI on a Mac, added Detox and am trying to run the sample tests. I get this error (newlines added for easier reading):
$ ./node_modules/.bin/detox -c android test
detox[37289] INFO: [test.js] configuration="android" reportSpecs=true readOnlyEmu=false
useCustomLogger=true forceAdbInstall=false DETOX_START_TIMESTAMP=1591313397594
node_modules/.bin/jest --config e2e/config.json '--testNamePattern=^((?!:ios:).)*$' --
maxWorkers 1 android test
detox[37290] INFO: [DetoxServer.js] server listening on localhost:62332...
detox[37290] ERROR: [DetoxExportWrapper.js/DETOX_INIT_ERROR]
DetoxRuntimeError: Failed to run application on the device
HINT: Most likely, your tests have timed out and called detox.cleanup() while it was
waiting for "ready" message (over WebSocket) from the instrumentation process.
When it runs, the emulator starts but the app does not.
The app runs fine separate from E2E tests, through React Native CLI.
.detoxrc.json
{
"testRunner": "jest",
"runnerConfig": "e2e/config.json",
"configurations": {
"android": {
"type": "android.emulator",
"binaryPath": "android/app/build/outputs/apk/debug/app-debug.apk",
"build": "cd android; ./gradlew assembleDebug assembleAndroidTest -DtestBiuldType=debug; cd -",
"device": {
"avdName": "Pixel_3"
}
}
}
}
Environment:
Detox: 16.7.0
React Native: 0.62.2
Node: v12.17.0
Device: Pixel 3, x86, API 29, Android 10
OS: MacOS 10.15.4
Test-runner: Jest
Android Studio: 3.6.3
My bad. I missed a few steps on the second page of getting started instructions specific to Android.
https://github.com/wix/Detox/blob/master/docs/Introduction.Android.md

Pass env file to detox

I would like to pass environment variable when I run detox tests in my react-native app:
"ios.sim.debug": {
"binaryPath": "ios/build/Build/Products/Debug-iphonesimulator/myapp.app",
"build": "export IS_DETOX=true && xcodebuild -workspace ios/myapp.xcworkspace -scheme my app -configuration Debug -sdk iphonesimulator -derivedDataPath ios/build",
"type": "ios.simulator",
"device": {
"type": "iPhone 11 Pro"
}
}
I've installed react-native-config. But the variable IS_DETOX is undefined in JS when I run detox tests.
Thanks
I am setting environmental variable without export.
All my .env variables are stored in config folder and I am able to load different environmental file for different configurations.
iOS
"ios.sim.release": {
"binaryPath": "ios/build/Build/Products/Release-iphonesimulator/Clim8Invest.app",
"build": "ENVFILE=config/.env.acceptance xcodebuild -workspace ios/Clim8Invest.xcworkspace -scheme Clim8Invest -configuration Release -sdk iphonesimulator -derivedDataPath ios/build",
"type": "ios.simulator",
"device": {
"type": "iPhone 11"
}
},
Android
"android.emu.debug.e2e": {
"binaryPath": "android/app/build/outputs/apk/debug/app-debug.apk",
"build": "cd android && ENVFILE=../config/.env.e2e ./gradlew assembleDebug assembleAndroidTest -DtestBuildType=debug && cd ..",
"type": "android.emulator",
"device": {
"avdName": "Nexus_5X_A"
}
}
Thanks #Black !
On my side I ended up using another solution with RN_SRC_EXT=e2e.js from Detox Mocking Guide so that the detox build is using params from MyConfig.e2e.js file instead of MyConfig.js file

detox test as app loading TypeError: null is not an object 'evaluating RNGestureHandler.default.Direction'

I am trying to run the initial test I set up yesterday, which was working. Today when I launch the test I get the TypeError: null is not an object 'evaluating RNGestureHandler.default.Direction' and the app will not load. react-native run-ios launches the app as expected with no issues. When I run the detox test command the app build fails.
Android is behaving properly.
I've tried linking manually in XCode. I've tried clearing the cache. I've removed and installed the RN modules. I've added the podfile reference manually.
I'm trying to figure out why the app will load with react-native run-ios but the detox test app load fails. Could it be loading a different build? Is there a file somewhere Detox saves an iOS build folder? I thought it uses the value in the binaryPath. I can't figure out why it worked yesterday but not today.
Here's the package.json:
"test-runner": "jest",
"configurations": {
"ios.sim.debug": {
"binaryPath": "ios/build/Build/Products/Debug-iphonesimulator/MyApp.app",
"build": "xcodebuild -workspace ios/MyApp.xcworkspace -scheme MyApp -configuration Debug -
sdk iphonesimulator -derivedDataPath ios/build",
"type": "ios.simulator",
"device": {
"type": "iPhone 11"
}
},
"android.emu.debug": {
"binaryPath": "android/app/build/outputs/apk/debug/app-debug.apk",
"build": "cd android && ./gradlew assembleDebug assembleAndroidTest -DtestBuildType=debug && cd ..",
"type": "android.emulator",
"device": {
"avdName": "Nexus_5X_API_26"
}
},
"android.emu.release": {
"binaryPath": "android/app/build/outputs/apk/release/app-release.apk",
"build": "cd android && ./gradlew assembleRelease assembleAndroidTest -DtestBuildType=release && cd ..",
"type": "android.emulator",
"device": {
"avdName": "Nexus_5X_API_26"
}
}
}
}```
Ok Figured it out. Posting it here for anyone who has this issue too.
I removed the ios/build folder and did a new build with Detox:
detox build -c ios.sim.debug
And now everything is working again on iOS.

How to tell Detox is running tests?

I'm using Detox to run end to end tests in my React Native project. I'm also using pretender.js to mock my API requests and I'm struggling to find a way to know if the app is currently in "testing" mode.
I was passing an env variable down (and using babel-transform-inline-environment-variables) to tell if I should mock the requests but that breaks shim.js in our release builds.
Is there any way to tell Detox launched the app & is running tests from within the JS? Ideally I'm looking for some sort of variable set at test time or something passed down from the command line (TESTING=true react-native start or __TESTING__)
Try using react-native-config. Here is also a good article on Managing Configuration in React Native with react-native-config.
I also gave an answer here animated-button-block-the-detox with working example of how react-native-config can be used to disable looping animations during testing.
The basic idea is that you create .env config files for all your different build environments (development, production, test, etc). These hold your configuration variables that you can access from either Javascript, Objective-C/Swift, or Java.
You then specify which .env config file to use when building your app:
$ ENVFILE=.env.staging react-native run-ios # bash
And this is an example of package.json file where detox uses .env config files for building the app.
"detox": {
"specs": "e2e",
"configurations": {
"ios.sim.release": {
"binaryPath": "ios/build/Build/Products/Release-iphonesimulator/example.app",
"build": "ENVFILE=.env.production export RCT_NO_LAUNCH_PACKAGER=true && xcodebuild -project ios/example.xcodeproj -scheme example -configuration Release -sdk iphonesimulator -derivedDataPath ios/build",
"type": "ios.simulator",
"name": "iPhone 5s, iOS 10.3"
},
"ios.sim.test": {
"binaryPath": "ios/build/Build/Products/Debug-iphonesimulator/example.app",
"build": "ENVFILE=.env.testing xcodebuild -project ios/example.xcodeproj -scheme example -configuration Debug -sdk iphonesimulator -derivedDataPath ios/build -arch x86_64",
"type": "ios.simulator",
"name": "iPhone 5s, iOS 10.3"
}
}
}
We are taking advantage of the fact detox invokes your binary with --args -detoxServer ... -detoxSessionId ... on the iOS command line and { detoxServer: ..., detoxSessionId: ... } set in InstrumentationRegistry in android.
The way we are currently exposing this to JS is a bit much for a StackOverflow answer, but here's some sample code that along with react native's docs should get you there - for Android:
// This will throw ClassNotFoundException if not running under any test,
// but it still might not be running under Detox
Class<?> instrumentationRegistry = Class.forName("android.support.test.InstrumentationRegistry");
Method getArguments = instrumentationRegistry.getMethod("getArguments");
Bundle argumentsBundle = (Bundle) getArguments.invoke(null);
// Say you're in your BaseJavaModule.getConstants() implementation:
return Collections.<String, Object>singletonMap("isDetox", null != argumentsBundle.getString("detoxServer"));
And on iOS, something like (don't have an Objective-C compiler ATM):
return #{#"isDetox": [[[NSProcessInfo processInfo] arguments] containsObject: #"-detoxServer"]}
Note it's also possible to get detox to add your own arguments with:
detox.init(config, { launchApp: false });
device.launchApp({ newInstance: true, launchArgs: {
myCustomArg: value,
...,
} });
It would be great to get this polished up to a module at some point.
Tests/production code that has knowledge of the environment is messy IMO.
The way I recommend doing it is by creating different app flavour for testing.
If you use React Native, check out react-native-repackager's instructions.
Alternatively, Detox docs have that section as well.
If you write Java code for Android, use gradle build flavours to create a flavours for testing.
You can find more on how we mock in our E2E suites here.