1'use strict'; 2 3import { Platform, UnavailabilityError } from '@unimodules/core'; 4import Constants from 'expo-constants'; 5import { isDeviceFarm } from './utils/Environment'; 6import ExponentTest from './ExponentTest'; 7 8function browserSupportsWebGL() { 9 try { 10 const canvas = document.createElement('canvas'); 11 return ( 12 !!window.WebGLRenderingContext && 13 (canvas.getContext('webgl') || canvas.getContext('experimental-webgl')) 14 ); 15 } catch (e) { 16 return false; 17 } 18} 19 20function optionalRequire(requirer) { 21 try { 22 return requirer(); 23 } catch (e) { 24 // eslint-disable-next-line 25 return; 26 } 27} 28 29// List of all modules for tests. Each file path must be statically present for 30// the packager to pick them all up. 31export function getTestModules() { 32 if (Platform.OS === 'web') { 33 const modules = [ 34 optionalRequire(() => require('./tests/Asset')), 35 optionalRequire(() => require('./tests/SVG')), 36 optionalRequire(() => require('./tests/Basic')), 37 optionalRequire(() => require('./tests/Constants')), 38 optionalRequire(() => require('./tests/SVG')), 39 optionalRequire(() => require('./tests/Contacts')), 40 optionalRequire(() => require('./tests/Crypto')), 41 optionalRequire(() => require('./tests/Font')), 42 optionalRequire(() => require('./tests/Random')), 43 optionalRequire(() => require('./tests/Localization')), 44 ]; 45 46 if (browserSupportsWebGL()) { 47 modules.push(optionalRequire(() => require('./tests/GLView'))); 48 } 49 50 if (ExponentTest && !ExponentTest.isInCI) { 51 // modules.push(optionalRequire(() => require('./tests/Speech'))); 52 } 53 return modules.filter(Boolean); 54 } 55 56 const modules = [ 57 require('./tests/Basic'), 58 optionalRequire(() => require('./tests/Application')), 59 optionalRequire(() => require('./tests/Asset')), 60 optionalRequire(() => require('./tests/Constants')), 61 optionalRequire(() => require('./tests/Crypto')), 62 optionalRequire(() => require('./tests/Device')), 63 optionalRequire(() => require('./tests/GLView')), 64 optionalRequire(() => require('./tests/Haptics')), 65 optionalRequire(() => require('./tests/Localization')), 66 optionalRequire(() => require('./tests/Network')), 67 optionalRequire(() => require('./tests/SecureStore')), 68 optionalRequire(() => require('./tests/Segment')), 69 optionalRequire(() => require('./tests/SQLite')), 70 optionalRequire(() => require('./tests/Random')), 71 ]; 72 73 if (global.DETOX) { 74 modules.push( 75 modules.push(optionalRequire(() => require('./tests/Permissions'))), 76 modules.push(optionalRequire(() => require('./tests/Calendar'))), 77 modules.push(optionalRequire(() => require('./tests/Video'))), 78 modules.push(optionalRequire(() => require('./tests/Audio'))) 79 ); 80 } else { 81 modules.push( 82 optionalRequire(() => require('./tests/Speech')), 83 optionalRequire(() => require('./tests/Recording')), 84 optionalRequire(() => require('./tests/FileSystem')), 85 optionalRequire(() => require('./tests/ScreenOrientation')), 86 optionalRequire(() => require('./tests/Payments')), 87 optionalRequire(() => require('./tests/AdMobInterstitial')), 88 optionalRequire(() => require('./tests/AdMobRewarded')), 89 optionalRequire(() => require('./tests/FBBannerAd')) 90 ); 91 } 92 93 if (!global.DETOX && !isDeviceFarm()) { 94 // Times out sometimes 95 modules.push( 96 optionalRequire(() => require('./tests/AdMobPublisherBanner')), 97 optionalRequire(() => require('./tests/AdMobBanner')) 98 ); 99 // Invalid placementId in CI (all tests fail) 100 modules.push(optionalRequire(() => require('./tests/FBNativeAd'))); 101 // Requires interaction (sign in popup) 102 modules.push(optionalRequire(() => require('./tests/GoogleSignIn'))); 103 // Popup to request device's location which uses Google's location service 104 modules.push(optionalRequire(() => require('./tests/Location'))); 105 // Fails to redirect because of malformed URL in published version with release channel parameter 106 modules.push(optionalRequire(() => require('./tests/Linking'))); 107 // Requires permission 108 modules.push(optionalRequire(() => require('./tests/Calendar'))); 109 modules.push(optionalRequire(() => require('./tests/Contacts'))); 110 modules.push(optionalRequire(() => require('./tests/Permissions'))); 111 modules.push(optionalRequire(() => require('./tests/MediaLibrary'))); 112 modules.push(optionalRequire(() => require('./tests/Notifications'))); 113 if (Constants.isDevice) { 114 modules.push(optionalRequire(() => require('./tests/Battery'))); 115 modules.push(optionalRequire(() => require('./tests/Brightness'))); 116 } 117 // Crashes app when mounting component 118 modules.push(optionalRequire(() => require('./tests/Video'))); 119 // "sdkUnversionedTestSuite failed: java.lang.NullPointerException: Attempt to invoke interface method 120 // 'java.util.Map org.unimodules.interfaces.taskManager.TaskInterface.getOptions()' on a null object reference" 121 modules.push(optionalRequire(() => require('./tests/TaskManager'))); 122 // Audio tests are flaky in CI due to asynchronous fetching of resources 123 modules.push(optionalRequire(() => require('./tests/Audio'))); 124 // The Camera tests are flaky on iOS, i.e. they fail randomly 125 if (Constants.isDevice && Platform.OS === 'android') 126 modules.push(optionalRequire(() => require('./tests/Camera'))); 127 } 128 if (Platform.OS === 'android') modules.push(optionalRequire(() => require('./tests/JSC'))); 129 if (Constants.isDevice) { 130 modules.push(optionalRequire(() => require('./tests/Cellular'))); 131 modules.push(optionalRequire(() => require('./tests/BarCodeScanner'))); 132 } 133 return modules.filter(Boolean); 134} 135 136export async function acceptPermissionsAndRunCommandAsync(fn) { 137 if (!ExponentTest) { 138 return await fn(); 139 } 140 141 const results = await Promise.all([ 142 ExponentTest.action({ 143 selectorType: 'text', 144 selectorValue: 'Allow', 145 actionType: 'click', 146 delay: 1000, 147 timeout: 100, 148 }), 149 fn(), 150 ]); 151 152 return results[1]; 153} 154 155export async function shouldSkipTestsRequiringPermissionsAsync() { 156 if (!ExponentTest || !ExponentTest.shouldSkipTestsRequiringPermissionsAsync) { 157 return false; 158 } 159 return ExponentTest.shouldSkipTestsRequiringPermissionsAsync(); 160} 161 162export async function expectMethodToBeUnavailableAsync(expect, method) { 163 const error = await expectMethodToThrowAsync(method); 164 expect(error instanceof UnavailabilityError).toBeTruthy(); 165} 166 167export async function expectMethodToThrowAsync(method) { 168 try { 169 await method(); 170 } catch (error) { 171 return error; 172 } 173} 174