blob: a452a2aba57a77f02410c8087a9b3f7e10118754 [file] [log] [blame]
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#import <EarlGrey/EarlGrey.h>
#import <XCTest/XCTest.h>
#import "../ios_add2app/AppDelegate.h"
#import "../ios_add2app/DualFlutterViewController.h"
#import "../ios_add2app/FullScreenViewController.h"
#import "../ios_add2app/MainViewController.h"
#import "../ios_add2app/HybridViewController.h"
@interface FlutterTests : XCTestCase
@end
@implementation FlutterTests {
int _flutterWarmEngineTaps;
}
- (instancetype)init {
self = [super init];
if (self) {
_flutterWarmEngineTaps = 0;
}
return self;
}
- (void)expectSemanticsNotification:(FlutterViewController*)viewController {
[self expectationForNotification:FlutterSemanticsUpdateNotification object:viewController handler:nil];
[viewController.engine ensureSemanticsEnabled];
[self waitForExpectationsWithTimeout:30.0 handler:nil];
}
- (void)testFullScreenCanPop {
[[EarlGrey selectElementWithMatcher:grey_keyWindow()]
assertWithMatcher:grey_sufficientlyVisible()];
[[EarlGrey selectElementWithMatcher:grey_buttonTitle(@"Full Screen (Cold)")]
performAction:grey_tap()];
__weak FlutterViewController *weakViewController;
@autoreleasepool {
UINavigationController *navController =
(UINavigationController *)((AppDelegate *)
[[UIApplication sharedApplication]
delegate])
.window.rootViewController;
weakViewController =
(FullScreenViewController *)navController.visibleViewController;
[self expectSemanticsNotification:weakViewController];
GREYAssertNotNil(weakViewController,
@"Expected non-nil FullScreenViewController.");
}
[[EarlGrey selectElementWithMatcher:grey_accessibilityLabel(@"POP")]
performAction:grey_tap()];
// EarlGrey v1 isn't good at detecting this yet - 2.0 will be able to do it
int tries = 10;
double delay = 1.0;
while (weakViewController != nil && tries != 0) {
CFRunLoopRunInMode(kCFRunLoopDefaultMode, delay, false);
tries--;
}
[[EarlGrey selectElementWithMatcher:grey_buttonTitle(@"Native iOS View")]
assertWithMatcher:grey_sufficientlyVisible()];
GREYAssertNil(weakViewController,
@"Expected FullScreenViewController to be deallocated.");
}
- (void)testDualFlutterView {
[[EarlGrey selectElementWithMatcher:grey_keyWindow()]
assertWithMatcher:grey_sufficientlyVisible()];
[[EarlGrey
selectElementWithMatcher:grey_buttonTitle(@"Dual Flutter View (Cold)")]
performAction:grey_tap()];
@autoreleasepool {
UINavigationController *navController =
(UINavigationController *)((AppDelegate *)
[[UIApplication sharedApplication]
delegate])
.window.rootViewController;
DualFlutterViewController *viewController =
(DualFlutterViewController *)navController.visibleViewController;
GREYAssertNotNil(viewController,
@"Expected non-nil DualFlutterViewController.");
[self expectSemanticsNotification:viewController.topFlutterViewController];
[self expectSemanticsNotification:viewController.bottomFlutterViewController];
}
// Verify that there are two Flutter views with the expected marquee text.
[[[EarlGrey
selectElementWithMatcher:grey_accessibilityLabel(@"This is Marquee")]
atIndex:0] assertWithMatcher:grey_notNil()];
[[[EarlGrey
selectElementWithMatcher:grey_accessibilityLabel(@"This is Marquee")]
atIndex:1] assertWithMatcher:grey_notNil()];
[[EarlGrey selectElementWithMatcher:grey_buttonTitle(@"Back")]
performAction:grey_tap()];
[[EarlGrey selectElementWithMatcher:grey_buttonTitle(@"Native iOS View")]
assertWithMatcher:grey_sufficientlyVisible()];
}
- (void)testHybridView {
[[EarlGrey selectElementWithMatcher:grey_keyWindow()]
assertWithMatcher:grey_sufficientlyVisible()];
[[EarlGrey selectElementWithMatcher:grey_buttonTitle(@"Hybrid View (Warm)")]
performAction:grey_tap()];
@autoreleasepool {
UINavigationController *navController =
(UINavigationController *)((AppDelegate *)
[[UIApplication sharedApplication]
delegate])
.window.rootViewController;
HybridViewController *viewController =
(HybridViewController *)navController.visibleViewController;
GREYAssertNotNil(viewController.flutterViewController,
@"Expected non-nil FlutterViewController.");
[self expectSemanticsNotification:viewController.flutterViewController];
}
[self validateCountsFlutter:@"Platform" count:0];
[self validateCountsPlatform:@"Flutter" count:_flutterWarmEngineTaps];
static const int platformTapCount = 4;
static const int flutterTapCount = 6;
for (int i = _flutterWarmEngineTaps; i < flutterTapCount;
i++, _flutterWarmEngineTaps++) {
[[EarlGrey selectElementWithMatcher:grey_accessibilityLabel(
@"Increment via Flutter")]
performAction:grey_tap()];
}
[self validateCountsFlutter:@"Platform" count:0];
[self validateCountsPlatform:@"Flutter" count:_flutterWarmEngineTaps];
for (int i = 0; i < platformTapCount; i++) {
[[EarlGrey
selectElementWithMatcher:grey_accessibilityLabel(@"Increment via iOS")]
performAction:grey_tap()];
}
[self validateCountsFlutter:@"Platform" count:platformTapCount];
[self validateCountsPlatform:@"Flutter" count:_flutterWarmEngineTaps];
[[EarlGrey selectElementWithMatcher:grey_buttonTitle(@"Back")]
performAction:grey_tap()];
[[EarlGrey selectElementWithMatcher:grey_buttonTitle(@"Native iOS View")]
assertWithMatcher:grey_sufficientlyVisible()];
}
/** Validates that the text labels showing the number of button taps match the
* expected counts. */
- (void)validateCountsFlutter:(NSString *)labelPrefix count:(int)flutterCount {
NSString *flutterCountStr =
[NSString stringWithFormat:@"%@ button tapped %d times.", labelPrefix,
flutterCount];
// TODO(https://github.com/flutter/flutter/issues/17988): Flutter doesn't
// expose accessibility IDs, so the best we can do is to search for an element
// with the text we expect.
[[EarlGrey selectElementWithMatcher:grey_accessibilityLabel(flutterCountStr)]
assertWithMatcher:grey_sufficientlyVisible()];
}
- (void)validateCountsPlatform:(NSString *)labelPrefix
count:(int)platformCount {
NSString *platformCountStr =
[NSString stringWithFormat:@"%@ button tapped %d times.", labelPrefix,
platformCount];
[[[EarlGrey selectElementWithMatcher:grey_accessibilityID(@"counter_on_iOS")]
assertWithMatcher:grey_text(platformCountStr)]
assertWithMatcher:grey_sufficientlyVisible()];
}
@end