├── .gitignore ├── README.md ├── lerna.json ├── package.json ├── packages ├── expo-detox-cli │ ├── README.md │ ├── cli.js │ └── package.json └── expo-detox-hook │ ├── .npmignore │ ├── ExpoDetoxHook-ios-src.tbz │ ├── README.md │ ├── ios │ ├── .tbzignore │ ├── ExpoDetoxHook.xcodeproj │ │ ├── project.pbxproj │ │ ├── project.xcworkspace │ │ │ ├── contents.xcworkspacedata │ │ │ └── xcshareddata │ │ │ │ └── IDEWorkspaceChecks.plist │ │ └── xcuserdata │ │ │ └── quin.xcuserdatad │ │ │ └── xcschemes │ │ │ ├── ExpoDetoxHook.xcscheme │ │ │ └── xcschememanagement.plist │ └── ExpoDetoxHook │ │ ├── DetoxOverride.h │ │ ├── DetoxOverride.m │ │ ├── ExpoDetoxHook.h │ │ └── Info.plist │ ├── local-cli │ ├── expotox-build-framework-cache.js │ ├── expotox-clean-framework-cache.js │ └── expotox.js │ ├── package-lock.json │ ├── package.json │ └── scripts │ ├── build.js │ ├── build_framework.ios.sh │ ├── build_universal_framework.sh │ └── postinstall.js └── scripts └── publish.sh /.gitignore: -------------------------------------------------------------------------------- 1 | packages/expo-detox-hook/ExpoDetoxHook-ios-src.tbz 2 | node_modules 3 | packages/expo-detox-hook/package-lock.json 4 | packages/expo-detox-cli/package-lock.json -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Welcome to the monorepo for expo's detox tools. Here are some README's: 2 | 3 | # Detox Tool Documentation 4 | 5 | ## Packages 6 | 7 | - [Detox Helpers](https://github.com/expo/detox-expo-helpers) 8 | - [Detox CLI](packages/expo-detox-cli/README.md) 9 | - [Detox Hook](packages/expo-detox-hook/README.md) -------------------------------------------------------------------------------- /lerna.json: -------------------------------------------------------------------------------- 1 | { 2 | "lerna": "2.4.0", 3 | "packages": [ 4 | "packages/*" 5 | ], 6 | "version": "1.0.10", 7 | "npmClient": "npm" 8 | } 9 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "devDependencies": { 3 | "lerna": "^2.4.0" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /packages/expo-detox-cli/README.md: -------------------------------------------------------------------------------- 1 | # What is this 2 | The `expo-detox-cli` runs self repair scripts for the dynamic library we insert in at runtime in order to have an expo app play well with the detox testing harness. 3 | 4 | # Installation 5 | You can install the cli by running `npm install -g expo-detox-cli`. 6 | 7 | # Usage 8 | Reset and build the framework by running `expotox clean-framework-cache && expotox build-framework-cache` 9 | -------------------------------------------------------------------------------- /packages/expo-detox-cli/cli.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | const cp = require('child_process'); 3 | const path = require('path'); 4 | 5 | const result = cp.spawnSync( 6 | path.join(process.cwd(), 'node_modules/.bin/expotox'), 7 | process.argv.slice(2), 8 | { stdio: 'inherit' }); 9 | 10 | process.exit(result.status); -------------------------------------------------------------------------------- /packages/expo-detox-cli/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "expo-detox-cli", 3 | "version": "1.0.10", 4 | "description": "", 5 | "bin": { 6 | "expotox": "./cli.js" 7 | }, 8 | "repository": { 9 | "type": "git", 10 | "url": "git+https://github.com/expo/detox-tools.git" 11 | }, 12 | "author": "Quinlan Jung", 13 | "license": "MIT", 14 | "bugs": { 15 | "url": "https://github.com/expo/detox-tools/issues" 16 | }, 17 | "homepage": "https://github.com/expo/detox-tools#readme", 18 | "dependencies": { 19 | "child-process-promise": "^2.2.1" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /packages/expo-detox-hook/.npmignore: -------------------------------------------------------------------------------- 1 | /ios/ 2 | ios_src 3 | 4 | # Dependency directories 5 | node_modules 6 | 7 | ## Build generated 8 | ios/build/ 9 | ios/DerivedData/ 10 | 11 | ################## 12 | # React-Native 13 | ################## 14 | # OSX 15 | # 16 | .DS_Store 17 | 18 | # node.js 19 | # 20 | node_modules/ 21 | npm-debug.log 22 | -------------------------------------------------------------------------------- /packages/expo-detox-hook/ExpoDetoxHook-ios-src.tbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/expo/detox-tools/8befcf631f18f14cb45eafe6256c855a12fd06b0/packages/expo-detox-hook/ExpoDetoxHook-ios-src.tbz -------------------------------------------------------------------------------- /packages/expo-detox-hook/README.md: -------------------------------------------------------------------------------- 1 | # What is this 2 | The `expo-detox-hook` is an iOS framework that you install via npm, and it gets put in your Library directory. This package exists because we need to call into the test runtime and add some extra changes in order to get Detox and Expo platforms to play well with each other. 3 | 4 | # Installation 5 | You can install the framework by declaring `expo-detox-hook` in your `package.json` and running `npm install`, which should install the framework to your Library directory. 6 | 7 | # Usage 8 | Unless you get an error, you shouldn't need to do anything else here. -------------------------------------------------------------------------------- /packages/expo-detox-hook/ios/.tbzignore: -------------------------------------------------------------------------------- 1 | build 2 | -------------------------------------------------------------------------------- /packages/expo-detox-hook/ios/ExpoDetoxHook.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 50; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 3480116B21812A0B006B3507 /* ExpoDetoxHook.h in Headers */ = {isa = PBXBuildFile; fileRef = 3480116921812A0B006B3507 /* ExpoDetoxHook.h */; settings = {ATTRIBUTES = (Public, ); }; }; 11 | 3480117221812A77006B3507 /* DetoxOverride.m in Sources */ = {isa = PBXBuildFile; fileRef = 3480117121812A77006B3507 /* DetoxOverride.m */; }; 12 | /* End PBXBuildFile section */ 13 | 14 | /* Begin PBXFileReference section */ 15 | 3480116621812A0B006B3507 /* ExpoDetoxHook.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = ExpoDetoxHook.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 16 | 3480116921812A0B006B3507 /* ExpoDetoxHook.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ExpoDetoxHook.h; sourceTree = ""; }; 17 | 3480116A21812A0B006B3507 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 18 | 3480117121812A77006B3507 /* DetoxOverride.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DetoxOverride.m; sourceTree = ""; }; 19 | 3480119621817EDC006B3507 /* DetoxOverride.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DetoxOverride.h; sourceTree = ""; }; 20 | /* End PBXFileReference section */ 21 | 22 | /* Begin PBXFrameworksBuildPhase section */ 23 | 3480116321812A0B006B3507 /* Frameworks */ = { 24 | isa = PBXFrameworksBuildPhase; 25 | buildActionMask = 2147483647; 26 | files = ( 27 | ); 28 | runOnlyForDeploymentPostprocessing = 0; 29 | }; 30 | /* End PBXFrameworksBuildPhase section */ 31 | 32 | /* Begin PBXGroup section */ 33 | 3480115C21812A0B006B3507 = { 34 | isa = PBXGroup; 35 | children = ( 36 | 3480116821812A0B006B3507 /* ExpoDetoxHook */, 37 | 3480116721812A0B006B3507 /* Products */, 38 | ); 39 | sourceTree = ""; 40 | }; 41 | 3480116721812A0B006B3507 /* Products */ = { 42 | isa = PBXGroup; 43 | children = ( 44 | 3480116621812A0B006B3507 /* ExpoDetoxHook.framework */, 45 | ); 46 | name = Products; 47 | sourceTree = ""; 48 | }; 49 | 3480116821812A0B006B3507 /* ExpoDetoxHook */ = { 50 | isa = PBXGroup; 51 | children = ( 52 | 3480116921812A0B006B3507 /* ExpoDetoxHook.h */, 53 | 3480116A21812A0B006B3507 /* Info.plist */, 54 | 3480119621817EDC006B3507 /* DetoxOverride.h */, 55 | 3480117121812A77006B3507 /* DetoxOverride.m */, 56 | ); 57 | path = ExpoDetoxHook; 58 | sourceTree = ""; 59 | }; 60 | /* End PBXGroup section */ 61 | 62 | /* Begin PBXHeadersBuildPhase section */ 63 | 3480116121812A0B006B3507 /* Headers */ = { 64 | isa = PBXHeadersBuildPhase; 65 | buildActionMask = 2147483647; 66 | files = ( 67 | 3480116B21812A0B006B3507 /* ExpoDetoxHook.h in Headers */, 68 | ); 69 | runOnlyForDeploymentPostprocessing = 0; 70 | }; 71 | /* End PBXHeadersBuildPhase section */ 72 | 73 | /* Begin PBXNativeTarget section */ 74 | 3480116521812A0B006B3507 /* ExpoDetoxHook */ = { 75 | isa = PBXNativeTarget; 76 | buildConfigurationList = 3480116E21812A0B006B3507 /* Build configuration list for PBXNativeTarget "ExpoDetoxHook" */; 77 | buildPhases = ( 78 | 3480116121812A0B006B3507 /* Headers */, 79 | 3480116221812A0B006B3507 /* Sources */, 80 | 3480116321812A0B006B3507 /* Frameworks */, 81 | 3480116421812A0B006B3507 /* Resources */, 82 | ); 83 | buildRules = ( 84 | ); 85 | dependencies = ( 86 | ); 87 | name = ExpoDetoxHook; 88 | productName = Test; 89 | productReference = 3480116621812A0B006B3507 /* ExpoDetoxHook.framework */; 90 | productType = "com.apple.product-type.framework"; 91 | }; 92 | /* End PBXNativeTarget section */ 93 | 94 | /* Begin PBXProject section */ 95 | 3480115D21812A0B006B3507 /* Project object */ = { 96 | isa = PBXProject; 97 | attributes = { 98 | LastUpgradeCheck = 1000; 99 | ORGANIZATIONNAME = "Quinlan Jung"; 100 | TargetAttributes = { 101 | 3480116521812A0B006B3507 = { 102 | CreatedOnToolsVersion = 10.0; 103 | }; 104 | }; 105 | }; 106 | buildConfigurationList = 3480116021812A0B006B3507 /* Build configuration list for PBXProject "ExpoDetoxHook" */; 107 | compatibilityVersion = "Xcode 9.3"; 108 | developmentRegion = en; 109 | hasScannedForEncodings = 0; 110 | knownRegions = ( 111 | en, 112 | ); 113 | mainGroup = 3480115C21812A0B006B3507; 114 | productRefGroup = 3480116721812A0B006B3507 /* Products */; 115 | projectDirPath = ""; 116 | projectRoot = ""; 117 | targets = ( 118 | 3480116521812A0B006B3507 /* ExpoDetoxHook */, 119 | ); 120 | }; 121 | /* End PBXProject section */ 122 | 123 | /* Begin PBXResourcesBuildPhase section */ 124 | 3480116421812A0B006B3507 /* Resources */ = { 125 | isa = PBXResourcesBuildPhase; 126 | buildActionMask = 2147483647; 127 | files = ( 128 | ); 129 | runOnlyForDeploymentPostprocessing = 0; 130 | }; 131 | /* End PBXResourcesBuildPhase section */ 132 | 133 | /* Begin PBXSourcesBuildPhase section */ 134 | 3480116221812A0B006B3507 /* Sources */ = { 135 | isa = PBXSourcesBuildPhase; 136 | buildActionMask = 2147483647; 137 | files = ( 138 | 3480117221812A77006B3507 /* DetoxOverride.m in Sources */, 139 | ); 140 | runOnlyForDeploymentPostprocessing = 0; 141 | }; 142 | /* End PBXSourcesBuildPhase section */ 143 | 144 | /* Begin XCBuildConfiguration section */ 145 | 3480116C21812A0B006B3507 /* Debug */ = { 146 | isa = XCBuildConfiguration; 147 | buildSettings = { 148 | ALWAYS_SEARCH_USER_PATHS = NO; 149 | CLANG_ANALYZER_NONNULL = YES; 150 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 151 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 152 | CLANG_CXX_LIBRARY = "libc++"; 153 | CLANG_ENABLE_MODULES = YES; 154 | CLANG_ENABLE_OBJC_ARC = YES; 155 | CLANG_ENABLE_OBJC_WEAK = YES; 156 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 157 | CLANG_WARN_BOOL_CONVERSION = YES; 158 | CLANG_WARN_COMMA = YES; 159 | CLANG_WARN_CONSTANT_CONVERSION = YES; 160 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 161 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 162 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 163 | CLANG_WARN_EMPTY_BODY = YES; 164 | CLANG_WARN_ENUM_CONVERSION = YES; 165 | CLANG_WARN_INFINITE_RECURSION = YES; 166 | CLANG_WARN_INT_CONVERSION = YES; 167 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 168 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 169 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 170 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 171 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 172 | CLANG_WARN_STRICT_PROTOTYPES = YES; 173 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 174 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 175 | CLANG_WARN_UNREACHABLE_CODE = YES; 176 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 177 | CODE_SIGN_IDENTITY = "iPhone Developer"; 178 | COPY_PHASE_STRIP = NO; 179 | CURRENT_PROJECT_VERSION = 1; 180 | DEBUG_INFORMATION_FORMAT = dwarf; 181 | ENABLE_STRICT_OBJC_MSGSEND = YES; 182 | ENABLE_TESTABILITY = YES; 183 | GCC_C_LANGUAGE_STANDARD = gnu11; 184 | GCC_DYNAMIC_NO_PIC = NO; 185 | GCC_NO_COMMON_BLOCKS = YES; 186 | GCC_OPTIMIZATION_LEVEL = 0; 187 | GCC_PREPROCESSOR_DEFINITIONS = ( 188 | "DEBUG=1", 189 | "$(inherited)", 190 | ); 191 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 192 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 193 | GCC_WARN_UNDECLARED_SELECTOR = YES; 194 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 195 | GCC_WARN_UNUSED_FUNCTION = YES; 196 | GCC_WARN_UNUSED_VARIABLE = YES; 197 | IPHONEOS_DEPLOYMENT_TARGET = 12.0; 198 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 199 | MTL_FAST_MATH = YES; 200 | ONLY_ACTIVE_ARCH = YES; 201 | SDKROOT = iphoneos; 202 | VERSIONING_SYSTEM = "apple-generic"; 203 | VERSION_INFO_PREFIX = ""; 204 | }; 205 | name = Debug; 206 | }; 207 | 3480116D21812A0B006B3507 /* Release */ = { 208 | isa = XCBuildConfiguration; 209 | buildSettings = { 210 | ALWAYS_SEARCH_USER_PATHS = NO; 211 | CLANG_ANALYZER_NONNULL = YES; 212 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 213 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 214 | CLANG_CXX_LIBRARY = "libc++"; 215 | CLANG_ENABLE_MODULES = YES; 216 | CLANG_ENABLE_OBJC_ARC = YES; 217 | CLANG_ENABLE_OBJC_WEAK = YES; 218 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 219 | CLANG_WARN_BOOL_CONVERSION = YES; 220 | CLANG_WARN_COMMA = YES; 221 | CLANG_WARN_CONSTANT_CONVERSION = YES; 222 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 223 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 224 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 225 | CLANG_WARN_EMPTY_BODY = YES; 226 | CLANG_WARN_ENUM_CONVERSION = YES; 227 | CLANG_WARN_INFINITE_RECURSION = YES; 228 | CLANG_WARN_INT_CONVERSION = YES; 229 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 230 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 231 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 232 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 233 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 234 | CLANG_WARN_STRICT_PROTOTYPES = YES; 235 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 236 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 237 | CLANG_WARN_UNREACHABLE_CODE = YES; 238 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 239 | CODE_SIGN_IDENTITY = "iPhone Developer"; 240 | COPY_PHASE_STRIP = NO; 241 | CURRENT_PROJECT_VERSION = 1; 242 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 243 | ENABLE_NS_ASSERTIONS = NO; 244 | ENABLE_STRICT_OBJC_MSGSEND = YES; 245 | GCC_C_LANGUAGE_STANDARD = gnu11; 246 | GCC_NO_COMMON_BLOCKS = YES; 247 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 248 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 249 | GCC_WARN_UNDECLARED_SELECTOR = YES; 250 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 251 | GCC_WARN_UNUSED_FUNCTION = YES; 252 | GCC_WARN_UNUSED_VARIABLE = YES; 253 | IPHONEOS_DEPLOYMENT_TARGET = 12.0; 254 | MTL_ENABLE_DEBUG_INFO = NO; 255 | MTL_FAST_MATH = YES; 256 | SDKROOT = iphoneos; 257 | VALIDATE_PRODUCT = YES; 258 | VERSIONING_SYSTEM = "apple-generic"; 259 | VERSION_INFO_PREFIX = ""; 260 | }; 261 | name = Release; 262 | }; 263 | 3480116F21812A0B006B3507 /* Debug */ = { 264 | isa = XCBuildConfiguration; 265 | buildSettings = { 266 | CODE_SIGN_IDENTITY = ""; 267 | CODE_SIGN_STYLE = Automatic; 268 | DEFINES_MODULE = YES; 269 | DYLIB_COMPATIBILITY_VERSION = 1; 270 | DYLIB_CURRENT_VERSION = 1; 271 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 272 | INFOPLIST_FILE = ExpoDetoxHook/Info.plist; 273 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 274 | LD_RUNPATH_SEARCH_PATHS = ( 275 | "$(inherited)", 276 | "@executable_path/Frameworks", 277 | "@loader_path/Frameworks", 278 | ); 279 | PRODUCT_BUNDLE_IDENTIFIER = quin.Test; 280 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; 281 | SKIP_INSTALL = YES; 282 | TARGETED_DEVICE_FAMILY = "1,2"; 283 | }; 284 | name = Debug; 285 | }; 286 | 3480117021812A0B006B3507 /* Release */ = { 287 | isa = XCBuildConfiguration; 288 | buildSettings = { 289 | CODE_SIGN_IDENTITY = ""; 290 | CODE_SIGN_STYLE = Automatic; 291 | DEFINES_MODULE = YES; 292 | DYLIB_COMPATIBILITY_VERSION = 1; 293 | DYLIB_CURRENT_VERSION = 1; 294 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 295 | INFOPLIST_FILE = ExpoDetoxHook/Info.plist; 296 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 297 | LD_RUNPATH_SEARCH_PATHS = ( 298 | "$(inherited)", 299 | "@executable_path/Frameworks", 300 | "@loader_path/Frameworks", 301 | ); 302 | PRODUCT_BUNDLE_IDENTIFIER = quin.Test; 303 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; 304 | SKIP_INSTALL = YES; 305 | TARGETED_DEVICE_FAMILY = "1,2"; 306 | }; 307 | name = Release; 308 | }; 309 | /* End XCBuildConfiguration section */ 310 | 311 | /* Begin XCConfigurationList section */ 312 | 3480116021812A0B006B3507 /* Build configuration list for PBXProject "ExpoDetoxHook" */ = { 313 | isa = XCConfigurationList; 314 | buildConfigurations = ( 315 | 3480116C21812A0B006B3507 /* Debug */, 316 | 3480116D21812A0B006B3507 /* Release */, 317 | ); 318 | defaultConfigurationIsVisible = 0; 319 | defaultConfigurationName = Release; 320 | }; 321 | 3480116E21812A0B006B3507 /* Build configuration list for PBXNativeTarget "ExpoDetoxHook" */ = { 322 | isa = XCConfigurationList; 323 | buildConfigurations = ( 324 | 3480116F21812A0B006B3507 /* Debug */, 325 | 3480117021812A0B006B3507 /* Release */, 326 | ); 327 | defaultConfigurationIsVisible = 0; 328 | defaultConfigurationName = Release; 329 | }; 330 | /* End XCConfigurationList section */ 331 | }; 332 | rootObject = 3480115D21812A0B006B3507 /* Project object */; 333 | } 334 | -------------------------------------------------------------------------------- /packages/expo-detox-hook/ios/ExpoDetoxHook.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /packages/expo-detox-hook/ios/ExpoDetoxHook.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /packages/expo-detox-hook/ios/ExpoDetoxHook.xcodeproj/xcuserdata/quin.xcuserdatad/xcschemes/ExpoDetoxHook.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 34 | 35 | 45 | 46 | 52 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 70 | 71 | 72 | 73 | 75 | 76 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /packages/expo-detox-hook/ios/ExpoDetoxHook.xcodeproj/xcuserdata/quin.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | ExpoDetoxHook.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | Test.xcscheme 13 | 14 | orderHint 15 | 0 16 | 17 | 18 | SuppressBuildableAutocreation 19 | 20 | 3480116521812A0B006B3507 21 | 22 | primary 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /packages/expo-detox-hook/ios/ExpoDetoxHook/DetoxOverride.h: -------------------------------------------------------------------------------- 1 | // 2 | // DetoxOverride.h 3 | // ExpoDetoxHook 4 | // 5 | // Created by Quinlan Jung on 10/24/18. 6 | // Copyright © 2018 Quinlan Jung. All rights reserved. 7 | // 8 | 9 | #ifndef DetoxOverride_h 10 | #define DetoxOverride_h 11 | #import 12 | 13 | @interface DetoxOverride : NSObject 14 | 15 | + (void)registerOneTimeNotification:(NSNotificationName) name handler:(void (^)(void))handler; 16 | @end 17 | 18 | #endif /* DetoxOverride_h */ 19 | -------------------------------------------------------------------------------- /packages/expo-detox-hook/ios/ExpoDetoxHook/DetoxOverride.m: -------------------------------------------------------------------------------- 1 | // 2 | // DetoxOverride.m 3 | // ExpoDetoxHook 4 | // 5 | // Created by Quinlan Jung on 10/24/18. 6 | // Copyright © 2018 Quinlan Jung. All rights reserved. 7 | // 8 | 9 | #import "DetoxOverride.h" 10 | #import 11 | #import 12 | 13 | // call an arbitrary fn on a target with args 14 | static id call(id target, NSString * selector, NSArray *args){ 15 | SEL sel = NSSelectorFromString(selector); 16 | NSMethodSignature *signature = [target methodSignatureForSelector:sel]; 17 | NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature]; 18 | invocation.target = target; 19 | [invocation setSelector:sel]; 20 | 21 | int argPos = 2; 22 | for (id arg in args){ 23 | [invocation setArgument:&arg atIndex:argPos]; 24 | argPos++; 25 | } 26 | 27 | [invocation invoke]; 28 | id __unsafe_unretained tempResultSet; 29 | [invocation getReturnValue:&tempResultSet]; 30 | return tempResultSet; 31 | } 32 | 33 | static void (*__orig_waitForReactNativeLoadWithCompletionHandler)(id self, SEL _cmd, id handler); 34 | 35 | 36 | // Registers a one-time notification on the Expo versioned RCTJavascriptDidLoadNotifications 37 | static void __EXPO_waitForReactNativeLoadWithCompletionHandler(id self, SEL _cmd, id handler){ 38 | NSString *notification = @"RCTJavaScriptDidLoadNotification"; 39 | 40 | Class exVersions = NSClassFromString(@"EXVersions"); 41 | if(exVersions == nil) 42 | { 43 | return; 44 | } 45 | 46 | id exVersionsInstance = call(exVersions, @"sharedInstance", @[]); 47 | NSDictionary *versions = call(exVersionsInstance, @"valueForKey:", @[@"versions"]); 48 | 49 | NSArray *sdkVersions = versions[@"sdkVersions"]; 50 | for (NSString *supportedVersion in sdkVersions) { 51 | NSString *underscoredVersion = [supportedVersion stringByReplacingOccurrencesOfString:@"." withString:@"_"]; 52 | [DetoxOverride registerOneTimeNotification:[NSString stringWithFormat: @"ABI%@%@", underscoredVersion, notification] handler:handler]; 53 | } 54 | __orig_waitForReactNativeLoadWithCompletionHandler(self, _cmd, handler); 55 | } 56 | 57 | @implementation DetoxOverride 58 | 59 | + (void) registerOneTimeNotification:(NSNotificationName) name handler:(void (^)(void))handler 60 | { 61 | __block __weak id observer; 62 | 63 | observer = [[NSNotificationCenter defaultCenter] addObserverForName:name object:nil queue:nil usingBlock:^(NSNotification * _Nonnull note) { 64 | 65 | if(handler) 66 | { 67 | handler(); 68 | } 69 | 70 | [[NSNotificationCenter defaultCenter] removeObserver:observer]; 71 | }]; 72 | } 73 | @end 74 | 75 | __attribute__((constructor())) 76 | static void __setupOverride() { 77 | Class cls = NSClassFromString(@"ReactNativeSupport"); 78 | if(cls == nil) 79 | { 80 | return; 81 | } 82 | 83 | Method m = class_getClassMethod(cls, NSSelectorFromString(@"waitForReactNativeLoadWithCompletionHandler:")); 84 | if(m == NULL) 85 | { 86 | return; 87 | } 88 | __orig_waitForReactNativeLoadWithCompletionHandler = (void*)method_getImplementation(m); 89 | method_setImplementation(m, (void*)__EXPO_waitForReactNativeLoadWithCompletionHandler); 90 | } 91 | -------------------------------------------------------------------------------- /packages/expo-detox-hook/ios/ExpoDetoxHook/ExpoDetoxHook.h: -------------------------------------------------------------------------------- 1 | // 2 | // ExpoDetoxHook.h 3 | // ExpoDetoxHook 4 | // 5 | // Created by Quinlan Jung on 10/24/18. 6 | // Copyright © 2018 Quinlan Jung. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | //! Project version number for ExpoDetoxHook. 12 | FOUNDATION_EXPORT double ExpoDetoxHookVersionNumber; 13 | 14 | //! Project version string for ExpoDetoxHook. 15 | FOUNDATION_EXPORT const unsigned char ExpoDetoxHookVersionString[]; 16 | 17 | // In this header, you should import all the public headers of your framework using statements like #import 18 | 19 | 20 | -------------------------------------------------------------------------------- /packages/expo-detox-hook/ios/ExpoDetoxHook/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | $(CURRENT_PROJECT_VERSION) 21 | 22 | 23 | -------------------------------------------------------------------------------- /packages/expo-detox-hook/local-cli/expotox-build-framework-cache.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | const path = require('path'); 4 | const cp = require('child_process'); 5 | 6 | cp.execSync(path.join(__dirname, '../scripts/build_framework.ios.sh'), {stdio: 'inherit'}); 7 | -------------------------------------------------------------------------------- /packages/expo-detox-hook/local-cli/expotox-clean-framework-cache.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | const fs = require('fs-extra'); 4 | const path = require('path'); 5 | const os = require('os'); 6 | 7 | async function run() { 8 | if (os.platform() === 'darwin') { 9 | const frameworkPath = path.join(os.homedir(), '/Library/ExpoDetoxHook'); 10 | console.log(`Removing framework binaries from ${frameworkPath}`); 11 | await fs.remove(frameworkPath); 12 | } 13 | } 14 | 15 | run(); 16 | -------------------------------------------------------------------------------- /packages/expo-detox-hook/local-cli/expotox.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | const program = require('commander'); 3 | 4 | program 5 | .arguments('') 6 | .command('clean-framework-cache', `Delete all compiled framework binaries from ~/Library/ExpoDetoxHook, they will be rebuilt on 'npm install' or when running 'expo-build-framework-cache'`) 7 | .command('build-framework-cache', `Build ExpoDetoxHook.framework to ~/Library/ExpoDetoxHook. The framework cache is specific for each combination of Xcode and ExpoDetoxHook versions`) 8 | .parse(process.argv); 9 | -------------------------------------------------------------------------------- /packages/expo-detox-hook/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "expo-detox-hook", 3 | "version": "1.0.2", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "child-process-promise": { 8 | "version": "2.2.1", 9 | "resolved": "https://registry.npmjs.org/child-process-promise/-/child-process-promise-2.2.1.tgz", 10 | "integrity": "sha1-RzChHvYQ+tRQuPIjx50x172tgHQ=", 11 | "requires": { 12 | "cross-spawn": "^4.0.2", 13 | "node-version": "^1.0.0", 14 | "promise-polyfill": "^6.0.1" 15 | } 16 | }, 17 | "cross-spawn": { 18 | "version": "4.0.2", 19 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-4.0.2.tgz", 20 | "integrity": "sha1-e5JHYhwjrf3ThWAEqCPL45dCTUE=", 21 | "requires": { 22 | "lru-cache": "^4.0.1", 23 | "which": "^1.2.9" 24 | } 25 | }, 26 | "fs-extra": { 27 | "version": "7.0.0", 28 | "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.0.tgz", 29 | "integrity": "sha512-EglNDLRpmaTWiD/qraZn6HREAEAHJcJOmxNEYwq6xeMKnVMAy3GUcFB+wXt2C6k4CNvB/mP1y/U3dzvKKj5OtQ==", 30 | "requires": { 31 | "graceful-fs": "^4.1.2", 32 | "jsonfile": "^4.0.0", 33 | "universalify": "^0.1.0" 34 | } 35 | }, 36 | "graceful-fs": { 37 | "version": "4.1.11", 38 | "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", 39 | "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=" 40 | }, 41 | "isexe": { 42 | "version": "2.0.0", 43 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", 44 | "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" 45 | }, 46 | "jsonfile": { 47 | "version": "4.0.0", 48 | "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", 49 | "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", 50 | "requires": { 51 | "graceful-fs": "^4.1.6" 52 | } 53 | }, 54 | "lru-cache": { 55 | "version": "4.1.3", 56 | "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.3.tgz", 57 | "integrity": "sha512-fFEhvcgzuIoJVUF8fYr5KR0YqxD238zgObTps31YdADwPPAp82a4M8TrckkWyx7ekNlf9aBcVn81cFwwXngrJA==", 58 | "requires": { 59 | "pseudomap": "^1.0.2", 60 | "yallist": "^2.1.2" 61 | } 62 | }, 63 | "node-version": { 64 | "version": "1.2.0", 65 | "resolved": "https://registry.npmjs.org/node-version/-/node-version-1.2.0.tgz", 66 | "integrity": "sha512-ma6oU4Sk0qOoKEAymVoTvk8EdXEobdS7m/mAGhDJ8Rouugho48crHBORAmy5BoOcv8wraPM6xumapQp5hl4iIQ==" 67 | }, 68 | "promise-polyfill": { 69 | "version": "6.1.0", 70 | "resolved": "https://registry.npmjs.org/promise-polyfill/-/promise-polyfill-6.1.0.tgz", 71 | "integrity": "sha1-36lpQ+qcEh/KTem1hoyznTRy4Fc=" 72 | }, 73 | "pseudomap": { 74 | "version": "1.0.2", 75 | "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", 76 | "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" 77 | }, 78 | "universalify": { 79 | "version": "0.1.2", 80 | "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", 81 | "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" 82 | }, 83 | "which": { 84 | "version": "1.3.1", 85 | "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", 86 | "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", 87 | "requires": { 88 | "isexe": "^2.0.0" 89 | } 90 | }, 91 | "yallist": { 92 | "version": "2.1.2", 93 | "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", 94 | "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" 95 | } 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /packages/expo-detox-hook/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "expo-detox-hook", 3 | "version": "1.0.10", 4 | "description": "", 5 | "bin": { 6 | "expotox": "local-cli/expotox.js" 7 | }, 8 | "scripts": { 9 | "build": "node scripts/build.js", 10 | "prepublish": "npm run build", 11 | "postinstall": "node scripts/postinstall.js" 12 | }, 13 | "repository": { 14 | "type": "git", 15 | "url": "git+https://github.com/expo/detox-tools.git" 16 | }, 17 | "author": "Quinlan Jung", 18 | "license": "MIT", 19 | "bugs": { 20 | "url": "https://github.com/expo/detox-tools/issues" 21 | }, 22 | "homepage": "https://github.com/expo/detox-tools#readme", 23 | "dependencies": { 24 | "child-process-promise": "^2.2.1", 25 | "commander": "^2.19.0", 26 | "fs-extra": "^7.0.0" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /packages/expo-detox-hook/scripts/build.js: -------------------------------------------------------------------------------- 1 | const childProcess = require('child_process'); 2 | const fs = require('fs-extra'); 3 | 4 | // Just make the usage a little prettier 5 | function sh(cmdline, opts) { 6 | const args = cmdline.split(' '); 7 | const cmd = args.shift(); 8 | return childProcess.execFileSync(cmd, args, opts); 9 | } 10 | 11 | if (process.platform === 'darwin') { 12 | console.log("\nPackaging ExpoDetoxHook iOS sources"); 13 | 14 | fs.removeSync('ExpoDetoxHook-ios-src.tbz'); 15 | 16 | sh("tar --exclude-from=.tbzignore -cjf ../ExpoDetoxHook-ios-src.tbz .", { cwd: "ios" }); 17 | } 18 | -------------------------------------------------------------------------------- /packages/expo-detox-hook/scripts/build_framework.ios.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e -x 2 | 3 | # Ensure Xcode is installed or print a warning message and return. 4 | xcodebuild -version &>/dev/null || { echo "WARNING: Xcode is not installed on this machine. Skipping iOS framework build phase"; exit 0; } 5 | 6 | rootPath="$(dirname "$(dirname "$0")")" 7 | version=`node -p "require('${rootPath}/package.json').version"` 8 | 9 | sha1=`(echo "${version}" && xcodebuild -version) | shasum | awk '{print $1}' #"${2}"` 10 | frameworkDirPath="$HOME/Library/ExpoDetoxHook/ios/${sha1}" 11 | frameworkPath="${frameworkDirPath}/ExpoDetoxHook.framework" 12 | 13 | function prepareAndBuildFramework () { 14 | if [ -d "$rootPath"/ios ]; then 15 | sourcePath="${rootPath}"/ios 16 | echo "Dev mode, will build from ${sourcePath}" 17 | buildFramework "${sourcePath}" 18 | else 19 | sourcePath="${rootPath}"/ios_src 20 | extractSources "${sourcePath}" 21 | buildFramework "${sourcePath}" 22 | rm -fr "${sourcePath}" 23 | fi 24 | } 25 | 26 | function extractSources () { 27 | sourcePath="${1}" 28 | echo "Extracting ExpoDetoxHook sources..." 29 | mkdir -p "${sourcePath}" 30 | tar -xjf "${rootPath}"/ExpoDetoxHook-ios-src.tbz -C "${sourcePath}" 31 | } 32 | 33 | function buildFramework () { 34 | sourcePath="${1}" 35 | echo "Building ExpoDetoxHook.framework from ${sourcePath}..." 36 | mkdir -p "${frameworkDirPath}" 37 | "${rootPath}"/scripts/build_universal_framework.sh "${sourcePath}"/ExpoDetoxHook.xcodeproj "${frameworkDirPath}" &> "${frameworkDirPath}"/expodetoxhook_ios.log 38 | } 39 | 40 | function main () { 41 | if [ -d "${frameworkDirPath}" ]; then 42 | if [ ! -d "${frameworkPath}" ]; then 43 | echo "${frameworkDirPath} was found, but could not find ExpoDetoxHook.framework inside it. This means that the ExpoDetoxHook framework build process was interrupted. 44 | deleting ${frameworkDirPath} and trying to rebuild." 45 | rm -rf "${frameworkDirPath}" 46 | prepareAndBuildFramework 47 | else 48 | echo "ExpoDetoxHook.framework was previously compiled, skipping..." 49 | fi 50 | else 51 | prepareAndBuildFramework 52 | fi 53 | 54 | echo "Done" 55 | } 56 | 57 | main 58 | -------------------------------------------------------------------------------- /packages/expo-detox-hook/scripts/build_universal_framework.sh: -------------------------------------------------------------------------------- 1 | PROJECT=$1 2 | OUTPUT_DIR=$2 3 | CONFIGURATION=Release 4 | PROJECT_NAME=ExpoDetoxHook 5 | 6 | set -e 7 | 8 | function remove_arch() { 9 | lipo -create "${1}" "${2}" -output "${3}" 10 | } 11 | 12 | # Make sure the output directory exists 13 | 14 | mkdir -p "${OUTPUT_DIR}" 15 | rm -fr "${OUTPUT_DIR}/${PROJECT_NAME}.framework" 16 | 17 | TEMP_DIR=$(mktemp -d "$TMPDIR"ExpoDetoxHookBuild.XXXX) 18 | echo TEMP_DIR = "${TEMP_DIR}" 19 | 20 | # Step 1. Build Device and Simulator versions 21 | 22 | BUILD_IOS=`xcodebuild -project "${PROJECT}" -UseNewBuildSystem=NO -scheme ExpoDetoxHook ONLY_ACTIVE_ARCH=NO -configuration "${CONFIGURATION}" -arch arm64 -sdk iphoneos VALID_ARCHS=arm64 -showBuildSettings | awk -F= '/TARGET_BUILD_DIR/{x=$NF; gsub(/^[ \t]+|[ \t]+$/,"",x); print x}'` 23 | BUILD_SIM=`xcodebuild -project "${PROJECT}" -UseNewBuildSystem=NO -scheme ExpoDetoxHook -configuration "${CONFIGURATION}" -arch x86_64 -sdk iphonesimulator ONLY_ACTIVE_ARCH=NO VALID_ARCHS=x86_64 -showBuildSettings | awk -F= '/TARGET_BUILD_DIR/{x=$NF; gsub(/^[ \t]+|[ \t]+$/,"",x); print x}'` 24 | 25 | echo ${BUILD_IOS} 26 | echo ${BUILD_SIM} 27 | 28 | xcodebuild -project "${PROJECT}" -UseNewBuildSystem=NO -scheme ExpoDetoxHook ONLY_ACTIVE_ARCH=NO -configuration "${CONFIGURATION}" -arch arm64 -sdk iphoneos build VALID_ARCHS=arm64 29 | xcodebuild -project "${PROJECT}" -UseNewBuildSystem=NO -scheme ExpoDetoxHook -configuration "${CONFIGURATION}" -arch x86_64 -sdk iphonesimulator ONLY_ACTIVE_ARCH=NO build VALID_ARCHS=x86_64 30 | 31 | # Step 2. Copy the framework structure (from iphoneos build) to the universal folder 32 | 33 | cp -fR "${BUILD_IOS}/${PROJECT_NAME}.framework" "${TEMP_DIR}/" 34 | 35 | echo $TEMP_DIR 36 | 37 | # Step 3. Create universal binary file using lipo and place the combined executable in the copied framework directory 38 | 39 | remove_arch "${BUILD_SIM}/${PROJECT_NAME}.framework/${PROJECT_NAME}" "${BUILD_IOS}/${PROJECT_NAME}.framework/${PROJECT_NAME}" "${TEMP_DIR}/${PROJECT_NAME}.framework/${PROJECT_NAME}" 40 | 41 | mv "${TEMP_DIR}/${PROJECT_NAME}.framework" "${OUTPUT_DIR}"/ 42 | rm -fr "${TEMP_DIR}" 43 | -------------------------------------------------------------------------------- /packages/expo-detox-hook/scripts/postinstall.js: -------------------------------------------------------------------------------- 1 | if (process.platform === "darwin") { 2 | require("child_process").execFileSync(`${__dirname}/build_framework.ios.sh`, { 3 | stdio: "inherit" 4 | }); 5 | } 6 | -------------------------------------------------------------------------------- /scripts/publish.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | 3 | lerna publish --cd-version patch --------------------------------------------------------------------------------