diff --git a/dev/integration_tests/ios_host_app/FlutterUITests/FlutterUITests.m b/dev/integration_tests/ios_host_app/FlutterUITests/FlutterUITests.m index cb7ecf36b1..9fcf73d5bf 100644 --- a/dev/integration_tests/ios_host_app/FlutterUITests/FlutterUITests.m +++ b/dev/integration_tests/ios_host_app/FlutterUITests/FlutterUITests.m @@ -4,6 +4,8 @@ @import XCTest; +static const CGFloat kStandardTimeOut = 60.0; + @interface FlutterUITests : XCTestCase @property (strong) XCUIApplication *app; @end @@ -22,42 +24,56 @@ - (void)testFullScreenColdPop { XCUIApplication *app = self.app; [self waitForAndTapElement:app.buttons[@"Full Screen (Cold)"]]; - XCTAssertTrue([app.staticTexts[@"Button tapped 0 times."] waitForExistenceWithTimeout:60.0]); + XCTAssertTrue([app.staticTexts[@"Button tapped 0 times."] waitForExistenceWithTimeout:kStandardTimeOut]); [self waitForAndTapElement:app.otherElements[@"Increment via Flutter"]]; - XCTAssertTrue([app.staticTexts[@"Button tapped 1 time."] waitForExistenceWithTimeout:60.0]); + XCTAssertTrue([app.staticTexts[@"Button tapped 1 time."] waitForExistenceWithTimeout:kStandardTimeOut]); // Back navigation. [app.buttons[@"POP"] tap]; - XCTAssertTrue([app.navigationBars[@"Flutter iOS Demos Home"] waitForExistenceWithTimeout:60.0]); + XCTAssertTrue([app.navigationBars[@"Flutter iOS Demos Home"] waitForExistenceWithTimeout:kStandardTimeOut]); } - (void)testFullScreenWarm { XCUIApplication *app = self.app; [self waitForAndTapElement:app.buttons[@"Full Screen (Warm)"]]; - XCTAssertTrue([app.staticTexts[@"Button tapped 0 times."] waitForExistenceWithTimeout:60.0]); + BOOL newPageAppeared = [app.staticTexts[@"Button tapped 0 times."] waitForExistenceWithTimeout:kStandardTimeOut]; + if (!newPageAppeared) { + // Sometimes, the element doesn't respond to the tap, it seems an XCUITest race condition where the tap happened + // too soon. Trying to tap the element again. + [self waitForAndTapElement:app.buttons[@"Full Screen (Warm))"]]; + newPageAppeared = [app.staticTexts[@"Button tapped 0 times."] waitForExistenceWithTimeout:kStandardTimeOut]; + } + XCTAssertTrue(newPageAppeared); [self waitForAndTapElement:app.otherElements[@"Increment via Flutter"]]; - XCTAssertTrue([app.staticTexts[@"Button tapped 1 time."] waitForExistenceWithTimeout:60.0]); + XCTAssertTrue([app.staticTexts[@"Button tapped 1 time."] waitForExistenceWithTimeout:kStandardTimeOut]); // Back navigation. [app.buttons[@"POP"] tap]; - XCTAssertTrue([app.navigationBars[@"Flutter iOS Demos Home"] waitForExistenceWithTimeout:60.0]); + XCTAssertTrue([app.navigationBars[@"Flutter iOS Demos Home"] waitForExistenceWithTimeout:kStandardTimeOut]); } - (void)testFlutterViewWarm { XCUIApplication *app = self.app; [self waitForAndTapElement:app.buttons[@"Flutter View (Warm)"]]; - XCTAssertTrue([app.staticTexts[@"Button tapped 0 times."] waitForExistenceWithTimeout:60.0]); + BOOL newPageAppeared = [app.staticTexts[@"Button tapped 0 times."] waitForExistenceWithTimeout:kStandardTimeOut]; + if (!newPageAppeared) { + // Sometimes, the element doesn't respond to the tap, it seems an XCUITest race condition where the tap happened + // too soon. Trying to tap the element again. + [self waitForAndTapElement:app.buttons[@"Flutter View (Warm)"]]; + newPageAppeared = [app.staticTexts[@"Button tapped 0 times."] waitForExistenceWithTimeout:kStandardTimeOut]; + } + XCTAssertTrue(newPageAppeared); [self waitForAndTapElement:app.otherElements[@"Increment via Flutter"]]; - XCTAssertTrue([app.staticTexts[@"Button tapped 1 time."] waitForExistenceWithTimeout:60.0]); + XCTAssertTrue([app.staticTexts[@"Button tapped 1 time."] waitForExistenceWithTimeout:kStandardTimeOut]); // Back navigation. [app.buttons[@"POP"] tap]; - XCTAssertTrue([app.navigationBars[@"Flutter iOS Demos Home"] waitForExistenceWithTimeout:60.0]); + XCTAssertTrue([app.navigationBars[@"Flutter iOS Demos Home"] waitForExistenceWithTimeout:kStandardTimeOut]); } - (void)testHybridViewWarm { @@ -65,20 +81,20 @@ [self waitForAndTapElement:app.buttons[@"Hybrid View (Warm)"]]; - XCTAssertTrue([app.staticTexts[@"Flutter button tapped 0 times."] waitForExistenceWithTimeout:60.0]); + XCTAssertTrue([app.staticTexts[@"Flutter button tapped 0 times."] waitForExistenceWithTimeout:kStandardTimeOut]); XCTAssertTrue(app.staticTexts[@"Platform button tapped 0 times."].exists); [self waitForAndTapElement:app.otherElements[@"Increment via Flutter"]]; - XCTAssertTrue([app.staticTexts[@"Flutter button tapped 1 time."] waitForExistenceWithTimeout:60.0]); + XCTAssertTrue([app.staticTexts[@"Flutter button tapped 1 time."] waitForExistenceWithTimeout:kStandardTimeOut]); XCTAssertTrue(app.staticTexts[@"Platform button tapped 0 times."].exists); [app.buttons[@"Increment via iOS"] tap]; - XCTAssertTrue([app.staticTexts[@"Flutter button tapped 1 time."] waitForExistenceWithTimeout:60.0]); + XCTAssertTrue([app.staticTexts[@"Flutter button tapped 1 time."] waitForExistenceWithTimeout:kStandardTimeOut]); XCTAssertTrue(app.staticTexts[@"Platform button tapped 1 time."].exists); // Back navigation. [app.navigationBars[@"Hybrid Flutter/Native"].buttons[@"Flutter iOS Demos Home"] tap]; - XCTAssertTrue([app.navigationBars[@"Flutter iOS Demos Home"] waitForExistenceWithTimeout:60.0]); + XCTAssertTrue([app.navigationBars[@"Flutter iOS Demos Home"] waitForExistenceWithTimeout:kStandardTimeOut]); } - (void)testDualCold { @@ -93,16 +109,13 @@ // Back navigation. [app.navigationBars[@"Dual Flutter Views"].buttons[@"Flutter iOS Demos Home"] tap]; - XCTAssertTrue([app.navigationBars[@"Flutter iOS Demos Home"] waitForExistenceWithTimeout:60.0]); + XCTAssertTrue([app.navigationBars[@"Flutter iOS Demos Home"] waitForExistenceWithTimeout:kStandardTimeOut]); } - (void)waitForAndTapElement:(XCUIElement *)element { NSPredicate *hittable = [NSPredicate predicateWithFormat:@"exists == YES AND hittable == YES"]; [self expectationForPredicate:hittable evaluatedWithObject:element handler:nil]; [self waitForExpectationsWithTimeout:30.0 handler:nil]; - // Sometimes, the element doesn't respond to the tap, it seems an XCUITest bug. Trying tap - // the app first to fix it. - [self.app tap]; [element tap]; }