Skip to content

Commit

Permalink
Merge branch 'master' into CrashHandling
Browse files Browse the repository at this point in the history
# Conflicts:
#	detox/ios/Detox/DetoxManager.h
#	detox/ios/Detox/DetoxManager.m
#	detox/ios/Detox/TestRunner.m
  • Loading branch information
rotemmiz committed Feb 7, 2018
2 parents fb9fea8 + f3b7694 commit f8d69a0
Show file tree
Hide file tree
Showing 16 changed files with 146 additions and 364 deletions.
8 changes: 1 addition & 7 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,7 @@ matrix:
- NAME='Website - master'
node_js: 8
script:
- git config --global user.email "$GIT_USER@users.noreply.github.com"
- git config --global user.name "Wix"
- echo "machine github.com login $GIT_USER password $GIT_TOKEN" > ~/.netrc
- cd website && npm install && GIT_USER=$GIT_USER CURRENT_BRANCH=master npm run publish-gh-pages
branches:
only:
- master
- scripts/publish-website.sh

branches:
only:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.wix.detox;

/**
* Created by rotemm on 07/02/2018.
*/

public class DetoxExceptionHandler {
}
246 changes: 2 additions & 244 deletions detox/ios/Detox.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

9 changes: 5 additions & 4 deletions detox/ios/Detox/DetoxManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,13 @@
//

#import <Foundation/Foundation.h>
#import "WebSocket.h"
#import "TestRunner.h"
#import "ReactNativeSupport.h"

@interface DetoxManager : NSObject
@interface DetoxManager : NSObject<WebSocketDelegate, TestRunnerDelegate>

+ (instancetype)sharedManager;
+ (instancetype)sharedInstance;
- (void)connectToServer:(NSString*)url withSessionId:(NSString*)sessionId;

- (void)notifyOnCrashWithDetails:(NSDictionary*)details;

@end
108 changes: 55 additions & 53 deletions detox/ios/Detox/DetoxManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -7,29 +7,23 @@
//

#import "DetoxManager.h"

#import "WebSocket.h"
#import "TestRunner.h"
#import "ReactNativeSupport.h"

#import <Detox/Detox-Swift.h>
#import "DetoxAppDelegateProxy.h"
#import "EarlGreyExtensions.h"
#import "EarlGreyStatistics.h"

DTX_CREATE_LOG(DetoxManager)

@interface DetoxManager() <WebSocketDelegate, TestRunnerDelegate>
@interface DetoxManager()

@property (nonatomic) BOOL isReady;
@property (nonatomic, strong) WebSocket *webSocket;
@property (nonatomic, strong) TestRunner *testRunner;
@property (nonatomic, retain) WebSocket *websocket;
@property (nonatomic, retain) TestRunner *testRunner;

@end

@implementation DetoxManager

+ (void)load
__attribute__((constructor))
static void detoxConditionalInit()
{
//This forces accessibility support in the application.
[[[NSUserDefaults alloc] initWithSuiteName:@"com.apple.Accessibility"] setBool:YES forKey:@"ApplicationAccessibilityEnabled"];
Expand All @@ -47,11 +41,14 @@ + (void)load
// if these args were not provided as part of options, don't start Detox at all!
return;
}
[[DetoxManager sharedManager] connectToServer:detoxServer withSessionId:detoxSessionId];

[[DetoxManager sharedInstance] connectToServer:detoxServer withSessionId:detoxSessionId];
}

+ (instancetype)sharedManager

@implementation DetoxManager

+ (instancetype)sharedInstance
{
static DetoxManager *sharedInstance = nil;
static dispatch_once_t onceToken;
Expand All @@ -66,8 +63,8 @@ - (instancetype)init
self = [super init];
if (self == nil) return nil;

self.webSocket = [[WebSocket alloc] init];
self.webSocket.delegate = self;
self.websocket = [[WebSocket alloc] init];
self.websocket.delegate = self;
self.testRunner = [[TestRunner alloc] init];
self.testRunner.delegate = self;

Expand All @@ -81,15 +78,15 @@ - (instancetype)init

- (void)connectToServer:(NSString*)url withSessionId:(NSString*)sessionId
{
[self.webSocket connectToServer:url withSessionId:sessionId];
[self.websocket connectToServer:url withSessionId:sessionId];
}

- (void)websocketDidConnect
{
if (![ReactNativeSupport isReactNativeApp])
{
_isReady = YES;
[self.webSocket sendAction:@"ready" withParams:@{} withMessageId:@-1000];
[self.websocket sendAction:@"ready" withParams:@{} withMessageId: @-1000];
}
}

Expand All @@ -99,55 +96,65 @@ - (void)websocketDidReceiveAction:(NSString *)type withParams:(NSDictionary *)pa

if([type isEqualToString:@"invoke"])
{
[self.testRunner invoke:params withMessageId:messageId];
[self.testRunner invoke:params withMessageId: messageId];
return;
}
else if([type isEqualToString:@"isReady"])
{
if(_isReady)
{
[self.webSocket sendAction:@"ready" withParams:@{} withMessageId:@-1000];
[self.websocket sendAction:@"ready" withParams:@{} withMessageId: @-1000];
}
return;
}
else if([type isEqualToString:@"cleanup"])
{
[self.testRunner cleanup];
[self.webSocket sendAction:@"cleanupDone" withParams:@{} withMessageId:messageId];
[self.websocket sendAction:@"cleanupDone" withParams:@{} withMessageId: messageId];
return;
}
else if([type isEqualToString:@"userNotification"])
{
NSURL* userNotificationDataURL = [NSURL fileURLWithPath:params[@"detoxUserNotificationDataURL"]];
DetoxUserNotificationDispatcher* dispatcher = [[DetoxUserNotificationDispatcher alloc] initWithUserNotificationDataURL:userNotificationDataURL];
[dispatcher dispatchOnAppDelegate:DetoxAppDelegateProxy.currentAppDelegateProxy simulateDuringLaunch:NO];
[self.webSocket sendAction:@"userNotificationDone" withParams:@{} withMessageId:messageId];
[EarlGrey detox_safeExecuteSync:^{
NSURL* userNotificationDataURL = [NSURL fileURLWithPath:params[@"detoxUserNotificationDataURL"]];
DetoxUserNotificationDispatcher* dispatcher = [[DetoxUserNotificationDispatcher alloc] initWithUserNotificationDataURL:userNotificationDataURL];
[dispatcher dispatchOnAppDelegate:DetoxAppDelegateProxy.currentAppDelegateProxy simulateDuringLaunch:NO];
[self.websocket sendAction:@"userNotificationDone" withParams:@{} withMessageId: messageId];
}];
}
else if([type isEqualToString:@"openURL"])
{
NSURL* URLToOpen = [NSURL URLWithString:params[@"url"]];

NSParameterAssert(URLToOpen != nil);

NSString* sourceApp = params[@"sourceApp"];

NSMutableDictionary* options = [@{UIApplicationLaunchOptionsURLKey: URLToOpen} mutableCopy];
if(sourceApp != nil)
{
options[UIApplicationLaunchOptionsSourceApplicationKey] = sourceApp;
}

if([[UIApplication sharedApplication].delegate respondsToSelector:@selector(application:openURL:options:)])
{
[[UIApplication sharedApplication].delegate application:[UIApplication sharedApplication] openURL:URLToOpen options:options];
}
[EarlGrey detox_safeExecuteSync:^{
NSURL* URLToOpen = [NSURL URLWithString:params[@"url"]];

NSParameterAssert(URLToOpen != nil);

NSString* sourceApp = params[@"sourceApp"];

NSMutableDictionary* options = [@{UIApplicationLaunchOptionsURLKey: URLToOpen} mutableCopy];
if(sourceApp != nil)
{
options[UIApplicationLaunchOptionsSourceApplicationKey] = sourceApp;
}

if([[UIApplication sharedApplication].delegate respondsToSelector:@selector(application:openURL:options:)])
{
[[UIApplication sharedApplication].delegate application:[UIApplication sharedApplication] openURL:URLToOpen options:options];
}

[self.websocket sendAction:@"openURLDone" withParams:@{} withMessageId: messageId];
}];
}
else if([type isEqualToString:@"shakeDevice"])
{

[self.webSocket sendAction:@"openURLDone" withParams:@{} withMessageId:messageId];
}
else if([type isEqualToString:@"reactNativeReload"])
{
_isReady = NO;
[ReactNativeSupport reloadApp];
[EarlGrey detox_safeExecuteSync:^{
[ReactNativeSupport reloadApp];
}];

[self _waitForRNLoadWithId:messageId];

Expand All @@ -158,7 +165,7 @@ - (void)websocketDidReceiveAction:(NSString *)type withParams:(NSDictionary *)pa
NSMutableDictionary* statsStatus = [[[EarlGreyStatistics sharedInstance] currentStatus] mutableCopy];
statsStatus[@"messageId"] = messageId;

[self.webSocket sendAction:@"currentStatusResult" withParams:statsStatus withMessageId:messageId];
[self.websocket sendAction:@"currentStatusResult" withParams:statsStatus withMessageId: messageId];
}
}

Expand All @@ -167,7 +174,7 @@ - (void)_waitForRNLoadWithId:(id)messageId
__weak __typeof(self) weakSelf = self;
[ReactNativeSupport waitForReactNativeLoadWithCompletionHandler:^{
weakSelf.isReady = YES;
[weakSelf.webSocket sendAction:@"ready" withParams:@{} withMessageId:@-1000];
[weakSelf.websocket sendAction:@"ready" withParams:@{} withMessageId: @-1000];
}];
}

Expand All @@ -178,24 +185,19 @@ - (void)testRunnerOnInvokeResult:(id)res withMessageId:(NSNumber *)messageId
{
res = [NSString stringWithFormat:@"(%@)", NSStringFromClass([res class])];
}
[self.webSocket sendAction:@"invokeResult" withParams:@{@"result": res} withMessageId:messageId];
[self.websocket sendAction:@"invokeResult" withParams:@{@"result": res} withMessageId: messageId];
}

- (void)testRunnerOnTestFailed:(NSString *)details withMessageId:(NSNumber *) messageId
{
if (details == nil) details = @"";
[self.webSocket sendAction:@"testFailed" withParams:@{@"details": details} withMessageId:messageId];
[self.websocket sendAction:@"testFailed" withParams:@{@"details": details} withMessageId: messageId];
}

- (void)testRunnerOnError:(NSString *)error withMessageId:(NSNumber *) messageId
{
if (error == nil) error = @"";
[self.webSocket sendAction:@"error" withParams:@{@"error": error} withMessageId:messageId];
}

- (void)notifyOnCrashWithDetails:(NSDictionary*)details
{
[self.webSocket sendAction:@"AppWillTerminateWithError" withParams:details withMessageId:@-10000];
[self.websocket sendAction:@"error" withParams:@{@"error": error} withMessageId: messageId];
}

@end
1 change: 1 addition & 0 deletions detox/ios/Detox/EarlGrey+Detox.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

@interface EarlGreyImpl (Detox)

- (void)detox_safeExecuteSync:(void(^)(void))block;
- (GREYElementInteraction *)detox_selectElementWithMatcher:(id<GREYMatcher>)elementMatcher;

@end
9 changes: 9 additions & 0 deletions detox/ios/Detox/EarlGrey+Detox.m
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,15 @@

@implementation EarlGreyImpl (Detox)

- (void)detox_safeExecuteSync:(void(^)(void))block
{
grey_execute_async(^{
[[GREYUIThreadExecutor sharedInstance] executeSync:^{
block();
} error:NULL];
});
}

- (GREYElementInteraction *)detox_selectElementWithMatcher:(id<GREYMatcher>)elementMatcher
{
return [self selectElementWithMatcher:[GREYMatchers detoxMatcherAvoidingProblematicReactNativeElements:elementMatcher]];
Expand Down
1 change: 1 addition & 0 deletions detox/ios/Detox/EarlGreyExtensions.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
//

#import <EarlGrey/EarlGrey.h>
#import "EarlGrey+Detox.h"

/**
Expose provate Earl Grey methods
Expand Down
2 changes: 1 addition & 1 deletion detox/ios/Detox/TestRunner.m
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ - (void)onTestFailed:(NSString *)details {
}
}

- (void)invoke:(NSDictionary*)params withMessageId:(NSNumber *)messageId
- (void)invoke:(NSDictionary*)params withMessageId: (NSNumber *)messageId
{
self.currentMessageId = messageId;
grey_execute_async(^{
Expand Down
2 changes: 1 addition & 1 deletion detox/src/devices/IosDriver.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class IosDriver extends DeviceDriverBase {
}

async openURL(deviceId, params) {
this.client.openURL(params);
await this.client.openURL(params);
}

async setURLBlacklist(urlList) {
Expand Down
12 changes: 12 additions & 0 deletions detox/test/ios/example.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,8 @@
399B4E061ED587120098D2AC /* example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = example.app; sourceTree = BUILT_PRODUCTS_DIR; };
39A077861E5450E700A53A07 /* RCTPushNotification.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTPushNotification.xcodeproj; path = "../node_modules/react-native/Libraries/PushNotificationIOS/RCTPushNotification.xcodeproj"; sourceTree = "<group>"; };
39B0445B1DAED76400431EC5 /* Detox.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Detox.xcodeproj; path = ../../ios/Detox.xcodeproj; sourceTree = "<group>"; };
39FC9D23202899F90033C11A /* e2e */ = {isa = PBXFileReference; lastKnownFileType = folder; name = e2e; path = ../e2e; sourceTree = "<group>"; };
39FC9D24202899F90033C11A /* src */ = {isa = PBXFileReference; lastKnownFileType = folder; name = src; path = ../src; sourceTree = "<group>"; };
78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTLinking.xcodeproj; path = "../node_modules/react-native/Libraries/LinkingIOS/RCTLinking.xcodeproj"; sourceTree = "<group>"; };
832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTText.xcodeproj; path = "../node_modules/react-native/Libraries/Text/RCTText.xcodeproj"; sourceTree = "<group>"; };
CC17D3301D60A24300267B0C /* NativeModule.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NativeModule.h; path = example/NativeModule.h; sourceTree = "<group>"; };
Expand Down Expand Up @@ -524,6 +526,15 @@
name = Products;
sourceTree = "<group>";
};
39FC9CFD202899D10033C11A /* JS */ = {
isa = PBXGroup;
children = (
39FC9D23202899F90033C11A /* e2e */,
39FC9D24202899F90033C11A /* src */,
);
name = JS;
sourceTree = "<group>";
};
78C398B11ACF4ADC00677621 /* Products */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -565,6 +576,7 @@
isa = PBXGroup;
children = (
13B07FAE1A68108700A75B9A /* example */,
39FC9CFD202899D10033C11A /* JS */,
CCFA7DE41D11D22600E15EDF /* Frameworks */,
832341AE1AAA6A7D00B99B32 /* Libraries */,
83CBBA001A601CBA00E9B192 /* Products */,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
Expand All @@ -61,7 +60,6 @@
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
disableMainThreadChecker = "YES"
language = ""
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
Expand Down
2 changes: 1 addition & 1 deletion docs/APIRef.DetoxCLI.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ Initiating your test suite
| -h, --help | output usage information |
| -o, --runner-config \<config\> | Test runner config file, defaults to 'e2e/mocha.opts' for mocha and 'e2e/config.json' for jest |
| -l, --loglevel [value] | info, debug, verbose, silly, wss |
| -c, -configuration \<device config\> | Select a device configuration from your defined figurations,if not supplied, and there's only one configuration, detox will default to it |
| -c, -configuration \<device config\> | Select a device configuration from your defined configurations,if not supplied, and there's only one configuration, detox will default to it |
| -r, --reuse | Reuse existing installed app (do not delete and re-tall) for a faster run. |
| -u, --cleanup | Shutdown simulator when test is over, useful for CI ipts, to make sure detox exists cleanly with no residue |
| -d, --debug-synchronization \<value\> | When an action/expectation takes a significant amount time use this option to print device synchronization status. The status will be printed if the ion takes more than [value]ms to complete |
Expand Down
Loading

0 comments on commit f8d69a0

Please sign in to comment.