1'use strict'; 2 3import Constants from 'expo-constants'; 4import { Platform } from 'expo-modules-core'; 5 6import ExponentTest from './ExponentTest'; 7import { isDeviceFarm } from './utils/Environment'; 8 9function browserSupportsWebGL() { 10 try { 11 const canvas = document.createElement('canvas'); 12 return ( 13 !!window.WebGLRenderingContext && 14 (canvas.getContext('webgl') || canvas.getContext('experimental-webgl')) 15 ); 16 } catch (e) { 17 return false; 18 } 19} 20 21function optionalRequire(requirer) { 22 try { 23 return requirer(); 24 } catch (e) { 25 // eslint-disable-next-line 26 return; 27 } 28} 29 30// Both Location and TaskManager test suites define tasks in TaskManager. 31// Since tasks can only be defined during initialization phase (not as a result 32// of calling some function when the application is running, but rather in global scope), 33// we need to trigger code execution of these modules here (not in `getTestModules` 34// which is called in one of the components). 35const LocationTestScreen = optionalRequire(() => require('./tests/Location')); 36const TaskManagerTestScreen = optionalRequire(() => require('./tests/TaskManager')); 37// I have a hunch that optionalRequire doesn't work when *not* in global scope 38// since I had to move Camera screen import here too to get rid of an error 39// caused by missing native module. 40const CameraTestScreen = optionalRequire(() => require('./tests/Camera')); 41 42// List of all modules for tests. Each file path must be statically present for 43// the packager to pick them all up. 44export function getTestModules() { 45 const modules = [ 46 // Sanity 47 require('./tests/Basic'), 48 ]; 49 50 // Expo core modules should run everywhere 51 modules.push( 52 require('./tests/Asset'), 53 require('./tests/Constants'), 54 require('./tests/FileSystem'), 55 require('./tests/Font'), 56 require('./tests/Permissions'), 57 require('./tests/ImagePicker'), 58 optionalRequire(() => require('./tests/Image')) 59 ); 60 61 // Universally tested APIs 62 modules.push( 63 require('./tests/Random'), 64 require('./tests/Crypto'), 65 require('./tests/KeepAwake'), 66 require('./tests/Blur'), 67 require('./tests/LinearGradient'), 68 require('./tests/Facebook'), 69 require('./tests/HTML'), 70 require('./tests/FirebaseCore'), 71 require('./tests/FirebaseAnalytics'), 72 require('./tests/FirebaseRecaptcha'), 73 require('./tests/FirebaseJSSDKCompat'), 74 require('./tests/FirebaseJSSDK'), 75 require('./tests/ImageManipulator'), 76 require('./tests/Clipboard'), 77 optionalRequire(() => require('./tests/SQLite')) 78 ); 79 80 if (Platform.OS === 'android') { 81 modules.push(require('./tests/JSC')); 82 modules.push(require('./tests/Hermes')); 83 } 84 85 if (global.DETOX) { 86 modules.push( 87 require('./tests/Contacts'), 88 require('./tests/Haptics'), 89 require('./tests/Localization'), 90 require('./tests/SecureStore'), 91 require('./tests/SMS'), 92 require('./tests/StoreReview'), 93 require('./tests/Notifications') 94 ); 95 return modules; 96 } 97 98 if (Platform.OS === 'web') { 99 modules.push( 100 require('./tests/Contacts'), 101 // require('./tests/SVG'), 102 require('./tests/Localization'), 103 require('./tests/Recording'), 104 optionalRequire(() => require('./tests/Notifications')), 105 LocationTestScreen 106 ); 107 108 if (browserSupportsWebGL()) { 109 modules.push(optionalRequire(() => require('./tests/GLView'))); 110 } 111 112 if (ExponentTest && !ExponentTest.isInCI) { 113 // modules.push(optionalRequire(() => require('./tests/Speech'))); 114 } 115 return modules.filter(Boolean); 116 } 117 118 modules.push( 119 optionalRequire(() => require('./tests/Application')), 120 optionalRequire(() => require('./tests/AuthSession')), 121 optionalRequire(() => require('./tests/Device')), 122 optionalRequire(() => require('./tests/GLView')), 123 optionalRequire(() => require('./tests/Haptics')), 124 optionalRequire(() => require('./tests/Localization')), 125 optionalRequire(() => require('./tests/Network')), 126 optionalRequire(() => require('./tests/SecureStore')), 127 optionalRequire(() => require('./tests/Segment')), 128 optionalRequire(() => require('./tests/Speech')), 129 optionalRequire(() => require('./tests/Recording')), 130 optionalRequire(() => require('./tests/ScreenOrientation')), 131 optionalRequire(() => require('./tests/AdMobInterstitial')), 132 optionalRequire(() => require('./tests/AdMobRewarded')), 133 optionalRequire(() => require('./tests/FBBannerAd')), 134 optionalRequire(() => require('./tests/Notifications')), 135 optionalRequire(() => require('./tests/NavigationBar')), 136 optionalRequire(() => require('./tests/SystemUI')) 137 ); 138 139 if (!isDeviceFarm()) { 140 // Times out sometimes 141 modules.push( 142 optionalRequire(() => require('./tests/AdMobPublisherBanner')), 143 optionalRequire(() => require('./tests/AdMobBanner')) 144 ); 145 // Invalid placementId in CI (all tests fail) 146 modules.push(optionalRequire(() => require('./tests/FBNativeAd'))); 147 // Requires interaction (sign in popup) 148 modules.push(optionalRequire(() => require('./tests/GoogleSignIn'))); 149 // Popup to request device's location which uses Google's location service 150 modules.push(LocationTestScreen); 151 // Fails to redirect because of malformed URL in published version with release channel parameter 152 modules.push(optionalRequire(() => require('./tests/Linking'))); 153 // Has uncontrolled view controllers 154 modules.push(require('./tests/SMS')); 155 // Requires permission 156 modules.push(optionalRequire(() => require('./tests/Contacts'))); 157 modules.push(optionalRequire(() => require('./tests/Calendar'))); 158 modules.push(optionalRequire(() => require('./tests/CalendarReminders'))); 159 modules.push(optionalRequire(() => require('./tests/MediaLibrary'))); 160 161 modules.push(optionalRequire(() => require('./tests/Battery'))); 162 if (Constants.isDevice) { 163 modules.push(optionalRequire(() => require('./tests/Brightness'))); 164 } 165 // Crashes app when mounting component 166 modules.push(optionalRequire(() => require('./tests/Video'))); 167 // "sdkUnversionedTestSuite failed: java.lang.NullPointerException: Attempt to invoke interface method 168 // 'java.util.Map org.unimodules.interfaces.taskManager.TaskInterface.getOptions()' on a null object reference" 169 modules.push(TaskManagerTestScreen); 170 // Audio tests are flaky in CI due to asynchronous fetching of resources 171 modules.push(optionalRequire(() => require('./tests/Audio'))); 172 173 // The Camera tests are flaky on iOS, i.e. they fail randomly 174 if (Constants.isDevice) { 175 modules.push(CameraTestScreen); 176 } 177 } 178 if (Constants.isDevice) { 179 modules.push(optionalRequire(() => require('./tests/Cellular'))); 180 modules.push(optionalRequire(() => require('./tests/BarCodeScanner'))); 181 } 182 return modules 183 .filter(Boolean) 184 .sort((a, b) => (a.name.toLowerCase() > b.name.toLowerCase() ? 1 : -1)); 185} 186