12a38a11eSExponent GitHub Bot// Copyright 2015-present 650 Industries. All rights reserved.
22a38a11eSExponent GitHub Bot
3d5e9e21bSBen Roth#import "ExpoKit.h"
4652b7dd7SBen Roth#import "EXKernel.h"
5652b7dd7SBen Roth#import "EXKernelLinkingManager.h"
6d5e9e21bSBen Roth#import "EXRootViewController.h"
7652b7dd7SBen Roth#import "EXShellManager.h"
89aa11ec8SBen Roth#import "EXTest.h"
9d5e9e21bSBen Roth
10d5e9e21bSBen Roth#import <React/RCTAssert.h>
11d5e9e21bSBen Roth#import <React/RCTUtils.h>
122a38a11eSExponent GitHub Bot
132a38a11eSExponent GitHub Bot#import <XCTest/XCTest.h>
142a38a11eSExponent GitHub Bot
152a38a11eSExponent GitHub Bot@interface ExponentIntegrationTests : XCTestCase
162a38a11eSExponent GitHub Bot
17d5e9e21bSBen Roth@property (nonatomic, strong) EXRootViewController *rootViewController;
1867a01999SBen Roth@property (nonatomic, strong) NSString *testSuiteUrl;
19d5e9e21bSBen Roth
202a38a11eSExponent GitHub Bot@end
212a38a11eSExponent GitHub Bot
222a38a11eSExponent GitHub Bot@implementation ExponentIntegrationTests
232a38a11eSExponent GitHub Bot
242a38a11eSExponent GitHub Bot- (void)setUp
252a38a11eSExponent GitHub Bot{
262a38a11eSExponent GitHub Bot  [super setUp];
2767a01999SBen Roth  [self _loadConfig];
289aa11ec8SBen Roth
29d5e9e21bSBen Roth  _rootViewController = (EXRootViewController *)[ExpoKit sharedInstance].rootViewController;
30652b7dd7SBen Roth  [[NSNotificationCenter defaultCenter] addObserver:self
31652b7dd7SBen Roth                                           selector:@selector(_onKernelJSLoaded)
32652b7dd7SBen Roth                                               name:kEXKernelJSIsLoadedNotification
33652b7dd7SBen Roth                                             object:nil];
34*c6e145e8SJames Ide
352a38a11eSExponent GitHub Bot}
362a38a11eSExponent GitHub Bot
37d5e9e21bSBen Roth- (void)testDoesTestSuiteAppPassAllJSTests
382a38a11eSExponent GitHub Bot{
3967a01999SBen Roth  XCTAssert((_testSuiteUrl), @"No url configured for JS test-suite. Make sure EXTestEnvironment.plist exists and contains a url to test-suite.");
40*c6e145e8SJames Ide
41*c6e145e8SJames Ide  XCTestExpectation *expectation = [[XCTestExpectation alloc] initWithDescription: @"Run all JS integration tests"];
42*c6e145e8SJames Ide
43*c6e145e8SJames Ide  __block NSDictionary *jsTestSuiteResult = nil;
44*c6e145e8SJames Ide  id<NSObject> observer = [NSNotificationCenter.defaultCenter
45*c6e145e8SJames Ide                           addObserverForName:EXTestSuiteCompletedNotification
46*c6e145e8SJames Ide                           object:nil
47*c6e145e8SJames Ide                           queue:NSOperationQueue.currentQueue
48*c6e145e8SJames Ide                           usingBlock:^(NSNotification *notification) {
49*c6e145e8SJames Ide                             jsTestSuiteResult = notification.userInfo;
50*c6e145e8SJames Ide                             [expectation fulfill];
51*c6e145e8SJames Ide                           }];
52d5e9e21bSBen Roth  [_rootViewController applicationWillEnterForeground];
532a38a11eSExponent GitHub Bot
54*c6e145e8SJames Ide  [self waitForExpectations:@[expectation] timeout:180];
55*c6e145e8SJames Ide  [NSNotificationCenter.defaultCenter removeObserver:observer];
56*c6e145e8SJames Ide
57*c6e145e8SJames Ide  XCTAssert((jsTestSuiteResult), @"Test suite timed out");
58*c6e145e8SJames Ide  XCTAssert(([jsTestSuiteResult[@"failed"] integerValue] == 0), @"Test suite failed: %@", jsTestSuiteResult);
599aa11ec8SBen Roth}
609aa11ec8SBen Roth
619aa11ec8SBen Roth#pragma mark - internal
629aa11ec8SBen Roth
6367a01999SBen Roth- (void)_loadConfig
6467a01999SBen Roth{
6595925a0aSJames Ide  // This plist is generated with `powertools configure-ios-test-suite-url`
6667a01999SBen Roth  NSString *configPath = [[NSBundle bundleForClass:[self class]] pathForResource:@"EXTestEnvironment" ofType:@"plist"];
6767a01999SBen Roth  NSDictionary *testConfig = (configPath) ? [NSDictionary dictionaryWithContentsOfFile:configPath] : [NSDictionary dictionary];
6867a01999SBen Roth  if (testConfig) {
6967a01999SBen Roth    _testSuiteUrl = testConfig[@"testSuiteUrl"];
7067a01999SBen Roth  }
7167a01999SBen Roth}
7267a01999SBen Roth
73652b7dd7SBen Roth- (void)_onKernelJSLoaded
74652b7dd7SBen Roth{
75652b7dd7SBen Roth  // if test environment isn't configured for a shell app, override here
76652b7dd7SBen Roth  // since clearly we're running tests
77652b7dd7SBen Roth  if ([EXShellManager sharedInstance].testEnvironment == EXTestEnvironmentNone) {
78652b7dd7SBen Roth    [EXShellManager sharedInstance].testEnvironment = EXTestEnvironmentLocal;
79652b7dd7SBen Roth  }
80652b7dd7SBen Roth
81*c6e145e8SJames Ide  // NOTE(2018-02-20): Without giving the kernel a second to run, it never opens test-suite. With a
82*c6e145e8SJames Ide  // cursory pass through the code, I didn't see the correct event to wait for. Perhaps after we
83*c6e145e8SJames Ide  // implement a pure-native kernel, we'll be able to remove this shoddy delay.
84*c6e145e8SJames Ide  dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
85*c6e145e8SJames Ide    [[EXKernel sharedInstance].serviceRegistry.linkingManager openUrl:_testSuiteUrl isUniversalLink:NO];
86*c6e145e8SJames Ide  });
872a38a11eSExponent GitHub Bot}
882a38a11eSExponent GitHub Bot
892a38a11eSExponent GitHub Bot@end
90