14d5e48afSBen Roth/**
24d5e48afSBen Roth *  This test launches the JS Expo app called `test-suite` and checks whether all the JS tests there pass.
34d5e48afSBen Roth *  `test-suite` runs a bunch of jasmine JS tests against the Expo SDK.
44d5e48afSBen Roth *  The purpose of this file is to provide a native pass/fail hook into the JS sdk tests.
54d5e48afSBen Roth *
64d5e48afSBen Roth *  To configure it, make sure this target contains a file called `EXTestEnvironment.plist`
74d5e48afSBen Roth *  with a key `testSuiteUrl` whose value is the url to load some version of Expo's `test-suite` app.
84d5e48afSBen Roth */
92a38a11eSExponent GitHub Bot
10d5e9e21bSBen Roth#import "ExpoKit.h"
1100fcd3c6SBen Roth#import "EXEnvironment.h"
12652b7dd7SBen Roth#import "EXKernel.h"
13652b7dd7SBen Roth#import "EXKernelLinkingManager.h"
14d5e9e21bSBen Roth#import "EXRootViewController.h"
1566169681SBen Roth#import "EXHomeAppManager.h"
169aa11ec8SBen Roth#import "EXTest.h"
17d5e9e21bSBen Roth
18d5e9e21bSBen Roth#import <React/RCTAssert.h>
19d5e9e21bSBen Roth#import <React/RCTUtils.h>
202a38a11eSExponent GitHub Bot
212a38a11eSExponent GitHub Bot#import <XCTest/XCTest.h>
222a38a11eSExponent GitHub Bot
232a38a11eSExponent GitHub Bot@interface ExponentIntegrationTests : XCTestCase
242a38a11eSExponent GitHub Bot
25d5e9e21bSBen Roth@property (nonatomic, strong) EXRootViewController *rootViewController;
2667a01999SBen Roth@property (nonatomic, strong) NSString *testSuiteUrl;
27d5e9e21bSBen Roth
282a38a11eSExponent GitHub Bot@end
292a38a11eSExponent GitHub Bot
302a38a11eSExponent GitHub Bot@implementation ExponentIntegrationTests
312a38a11eSExponent GitHub Bot
322a38a11eSExponent GitHub Bot- (void)setUp
332a38a11eSExponent GitHub Bot{
342a38a11eSExponent GitHub Bot  [super setUp];
3567a01999SBen Roth  [self _loadConfig];
369aa11ec8SBen Roth
375d8188f5SBen Roth  _rootViewController = (EXRootViewController *)[ExpoKit sharedInstance].rootViewController;
385d8188f5SBen Roth  // if test environment isn't configured for a shell app, override here
395d8188f5SBen Roth  // since clearly we're running tests
4000fcd3c6SBen Roth  if ([EXEnvironment sharedEnvironment].testEnvironment == EXTestEnvironmentNone) {
4100fcd3c6SBen Roth    [EXEnvironment sharedEnvironment].testEnvironment = EXTestEnvironmentLocal;
425d8188f5SBen Roth  }
435d8188f5SBen Roth
445d8188f5SBen Roth  // NOTE(2018-02-20): Without giving the kernel a second to run, it never opens test-suite. With a
455d8188f5SBen Roth  // cursory pass through the code, I didn't see the correct event to wait for. Perhaps after we
465d8188f5SBen Roth  // implement a pure-native kernel, we'll be able to remove this shoddy delay.
475d8188f5SBen Roth  dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
48*4e677961SBen Roth    [[EXKernel sharedInstance].serviceRegistry.linkingManager openUrl:self->_testSuiteUrl isUniversalLink:NO];
495d8188f5SBen Roth  });
50c6e145e8SJames Ide
512a38a11eSExponent GitHub Bot}
522a38a11eSExponent GitHub Bot
53d5e9e21bSBen Roth- (void)testDoesTestSuiteAppPassAllJSTests
542a38a11eSExponent GitHub Bot{
5567a01999SBen Roth  XCTAssert((_testSuiteUrl), @"No url configured for JS test-suite. Make sure EXTestEnvironment.plist exists and contains a url to test-suite.");
56c6e145e8SJames Ide
57c6e145e8SJames Ide  XCTestExpectation *expectation = [[XCTestExpectation alloc] initWithDescription: @"Run all JS integration tests"];
58c6e145e8SJames Ide
59c6e145e8SJames Ide  __block NSDictionary *jsTestSuiteResult = nil;
60c6e145e8SJames Ide  id<NSObject> observer = [NSNotificationCenter.defaultCenter
61c6e145e8SJames Ide                           addObserverForName:EXTestSuiteCompletedNotification
62c6e145e8SJames Ide                           object:nil
63c6e145e8SJames Ide                           queue:NSOperationQueue.currentQueue
64c6e145e8SJames Ide                           usingBlock:^(NSNotification *notification) {
65c6e145e8SJames Ide                             jsTestSuiteResult = notification.userInfo;
66c6e145e8SJames Ide                             [expectation fulfill];
67c6e145e8SJames Ide                           }];
682a38a11eSExponent GitHub Bot
69c6e145e8SJames Ide  [self waitForExpectations:@[expectation] timeout:180];
70c6e145e8SJames Ide  [NSNotificationCenter.defaultCenter removeObserver:observer];
71c6e145e8SJames Ide
72c6e145e8SJames Ide  XCTAssert((jsTestSuiteResult), @"Test suite timed out");
73c6e145e8SJames Ide  XCTAssert(([jsTestSuiteResult[@"failed"] integerValue] == 0), @"Test suite failed: %@", jsTestSuiteResult);
749aa11ec8SBen Roth}
759aa11ec8SBen Roth
769aa11ec8SBen Roth#pragma mark - internal
779aa11ec8SBen Roth
7867a01999SBen Roth- (void)_loadConfig
7967a01999SBen Roth{
8095925a0aSJames Ide  // This plist is generated with `powertools configure-ios-test-suite-url`
8167a01999SBen Roth  NSString *configPath = [[NSBundle bundleForClass:[self class]] pathForResource:@"EXTestEnvironment" ofType:@"plist"];
8267a01999SBen Roth  NSDictionary *testConfig = (configPath) ? [NSDictionary dictionaryWithContentsOfFile:configPath] : [NSDictionary dictionary];
8367a01999SBen Roth  if (testConfig) {
8467a01999SBen Roth    _testSuiteUrl = testConfig[@"testSuiteUrl"];
8567a01999SBen Roth  }
8667a01999SBen Roth}
8767a01999SBen Roth
882a38a11eSExponent GitHub Bot@end
89