From 94e09899cf4296908caebedec77120e3d246b3f0 Mon Sep 17 00:00:00 2001 From: garyqian Date: Thu, 14 May 2020 03:31:47 -0700 Subject: [PATCH 1/9] Remove locale prepend on iOS --- .../darwin/ios/framework/Source/FlutterEngine.mm | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm b/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm index 6c79449795164..ad00946028224 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm @@ -762,22 +762,6 @@ - (void)onLocaleUpdated:(NSNotification*)notification { NSArray* preferredLocales = [NSLocale preferredLanguages]; NSMutableArray* data = [[NSMutableArray new] autorelease]; - // Force prepend the [NSLocale currentLocale] to the front of the list - // to ensure we are including the full default locale. preferredLocales - // is not guaranteed to include anything beyond the languageCode. - NSLocale* currentLocale = [NSLocale currentLocale]; - NSString* languageCode = [currentLocale objectForKey:NSLocaleLanguageCode]; - NSString* countryCode = [currentLocale objectForKey:NSLocaleCountryCode]; - NSString* scriptCode = [currentLocale objectForKey:NSLocaleScriptCode]; - NSString* variantCode = [currentLocale objectForKey:NSLocaleVariantCode]; - if (languageCode) { - [data addObject:languageCode]; - [data addObject:(countryCode ? countryCode : @"")]; - [data addObject:(scriptCode ? scriptCode : @"")]; - [data addObject:(variantCode ? variantCode : @"")]; - } - - // Add any secondary locales/languages to the list. for (NSString* localeID in preferredLocales) { NSLocale* currentLocale = [[[NSLocale alloc] initWithLocaleIdentifier:localeID] autorelease]; NSString* languageCode = [currentLocale objectForKey:NSLocaleLanguageCode]; From 68da62fb917ef9ea1010a3c8c3946a2becd6931b Mon Sep 17 00:00:00 2001 From: garyqian Date: Sat, 16 May 2020 04:50:58 -0700 Subject: [PATCH 2/9] add test --- .../LocalizationInitializationTest.m | 62 +++++++++++++++++ .../lib/src/locale_initialization.dart | 66 +++++++++++++++++++ testing/scenario_app/lib/src/scenarios.dart | 2 + 3 files changed, 130 insertions(+) create mode 100644 testing/scenario_app/ios/Scenarios/ScenariosTests/LocalizationInitializationTest.m create mode 100644 testing/scenario_app/lib/src/locale_initialization.dart diff --git a/testing/scenario_app/ios/Scenarios/ScenariosTests/LocalizationInitializationTest.m b/testing/scenario_app/ios/Scenarios/ScenariosTests/LocalizationInitializationTest.m new file mode 100644 index 0000000000000..ea4c037e1e9d9 --- /dev/null +++ b/testing/scenario_app/ios/Scenarios/ScenariosTests/LocalizationInitializationTest.m @@ -0,0 +1,62 @@ +// Copyright 2013 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 +#import +#import "AppDelegate.h" + +@interface XCUIElement (ftr_waitForNonExistence) +/// Keeps waiting until the element doesn't exist. Returns NO if the timeout is +/// reached before it doesn't exist. +- (BOOL)ftr_waitForNonExistenceWithTimeout:(NSTimeInterval)timeout; +/// Waits the full duration to ensure something doesn't exist for that duration. +/// Returns NO if at some point the element exists during the duration. +- (BOOL)ftr_waitForNonExistenceForDuration:(NSTimeInterval)duration; +@end + +@implementation XCUIElement (ftr_waitForNonExistence) +- (BOOL)ftr_waitForNonExistenceWithTimeout:(NSTimeInterval)timeout { + NSTimeInterval delta = 0.5; + while (timeout > 0.0) { + if (!self.exists) { + return YES; + } + usleep(delta * 1000000); + timeout -= delta; + } + return NO; +} + +- (BOOL)ftr_waitForNonExistenceForDuration:(NSTimeInterval)duration { + return ![self waitForExistenceWithTimeout:duration]; +} + +@end + +@interface LocalizationInitializationTest : XCTestCase +@property(nonatomic, strong) XCUIApplication* application; +@end + +@implementation LocalizationInitializationTest + +- (void)setUp { + [super setUp]; + self.continueAfterFailure = NO; + + self.application = [[XCUIApplication alloc] init]; + self.application.launchArguments = @[ @"--locale-initialization" ]; + [self.application launch]; +} + +- (void)testNoLocalePrepend { + NSTimeInterval timeout = 10.0; + + // The locales recieved by dart:ui are exposed onBeginFrame via semantics label. + // There should only be one locale, as we have removed the locale prepend on iOS. + XCUIElement* textInputSemanticsObject = + [[[self.application textFields] matchingIdentifier:@"[en_US]"] element]; + XCTAssertTrue([textInputSemanticsObject waitForExistenceWithTimeout:timeout]); +} + +@end diff --git a/testing/scenario_app/lib/src/locale_initialization.dart b/testing/scenario_app/lib/src/locale_initialization.dart new file mode 100644 index 0000000000000..5107813015172 --- /dev/null +++ b/testing/scenario_app/lib/src/locale_initialization.dart @@ -0,0 +1,66 @@ +// Copyright 2020 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 'dart:typed_data'; +import 'dart:ui'; + +import 'scenario.dart'; + +/// A scenario that sends back messages when touches are received. +class LocaleInitialization extends Scenario { + /// Constructor for `SendTextFocusScemantics`. + LocaleInitialization(Window window) + : assert(window != null), + super(window); + + @override + void onBeginFrame(Duration duration) { + // Doesn't matter what we draw. Just paint white. + final SceneBuilder builder = SceneBuilder(); + final PictureRecorder recorder = PictureRecorder(); + final Canvas canvas = Canvas(recorder); + + canvas.drawRect( + Rect.fromLTWH(0, 0, window.physicalSize.width, window.physicalSize.height), + Paint()..color = const Color.fromARGB(255, 255, 255, 255), + ); + final Picture picture = recorder.endRecording(); + + builder.addPicture( + Offset.zero, + picture, + ); + final Scene scene = builder.build(); + window.render(scene); + scene.dispose(); + + // On the first frame, also pretend that it drew a text field. Send the + // corresponding semantics tree comprised of 1 node for the text field. + window.updateSemantics((SemanticsUpdateBuilder() + ..updateNode( + id: 0, + // SemanticsFlag.isTextField. + flags: 16, + // SemanticsAction.tap. + actions: 1, + rect: const Rect.fromLTRB(0.0, 0.0, 414.0, 48.0), + label: window.locales.toString(), + textDirection: TextDirection.ltr, + textSelectionBase: -1, + textSelectionExtent: -1, + platformViewId: -1, + maxValueLength: -1, + currentValueLength: 0, + scrollChildren: 0, + scrollIndex: 0, + // transform: Matrix4.identity().storage, + elevation: 0.0, + thickness: 0.0, + childrenInTraversalOrder: Int32List(0), + childrenInHitTestOrder: Int32List(0), + additionalActions: Int32List(0), + )).build() + ); + } +} diff --git a/testing/scenario_app/lib/src/scenarios.dart b/testing/scenario_app/lib/src/scenarios.dart index dbfe793e1a21f..e7c9a43181a0a 100644 --- a/testing/scenario_app/lib/src/scenarios.dart +++ b/testing/scenario_app/lib/src/scenarios.dart @@ -6,6 +6,7 @@ import 'dart:ui'; import 'animated_color_square.dart'; +import 'src/locale_initialization.dart'; import 'platform_view.dart'; import 'poppable_screen.dart'; import 'scenario.dart'; @@ -14,6 +15,7 @@ import 'touches_scenario.dart'; Map _scenarios = { 'animated_color_square': AnimatedColorSquareScenario(window), + 'locale_initialization': LocaleInitialization(window), 'platform_view': PlatformViewScenario(window, 'Hello from Scenarios (Platform View)', id: 0), 'platform_view_no_overlay_intersection': PlatformViewNoOverlayIntersectionScenario(window, 'Hello from Scenarios (Platform View)', id: 0), 'platform_view_partial_intersection': PlatformViewPartialIntersectionScenario(window, 'Hello from Scenarios (Platform View)', id: 0), From fa514720305265fc8cdae61ca1f6bcfdeddb34ff Mon Sep 17 00:00:00 2001 From: garyqian Date: Sun, 17 May 2020 05:56:43 -0700 Subject: [PATCH 3/9] Fix import --- testing/scenario_app/lib/src/scenarios.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testing/scenario_app/lib/src/scenarios.dart b/testing/scenario_app/lib/src/scenarios.dart index e7c9a43181a0a..861c71a354bfc 100644 --- a/testing/scenario_app/lib/src/scenarios.dart +++ b/testing/scenario_app/lib/src/scenarios.dart @@ -6,7 +6,7 @@ import 'dart:ui'; import 'animated_color_square.dart'; -import 'src/locale_initialization.dart'; +import 'locale_initialization.dart'; import 'platform_view.dart'; import 'poppable_screen.dart'; import 'scenario.dart'; From af241916064c6bad5f6658555feb80b3df7033d8 Mon Sep 17 00:00:00 2001 From: garyqian Date: Mon, 18 May 2020 06:27:03 -0700 Subject: [PATCH 4/9] Add new test to map --- testing/scenario_app/ios/Scenarios/Scenarios/AppDelegate.m | 1 + 1 file changed, 1 insertion(+) diff --git a/testing/scenario_app/ios/Scenarios/Scenarios/AppDelegate.m b/testing/scenario_app/ios/Scenarios/Scenarios/AppDelegate.m index 979887507f9f4..d09cc4db033c4 100644 --- a/testing/scenario_app/ios/Scenarios/Scenarios/AppDelegate.m +++ b/testing/scenario_app/ios/Scenarios/Scenarios/AppDelegate.m @@ -26,6 +26,7 @@ - (BOOL)application:(UIApplication*)application NSDictionary* launchArgsMap = @{ // The Platform view golden test args should match `PlatformViewGoldenTestManager`. + @"--locale-initialization" : @"locale_initialization", @"--platform-view" : @"platform_view", @"--platform-view-no-overlay-intersection" : @"platform_view_no_overlay_intersection", @"--platform-view-two-intersecting-overlays" : @"platform_view_two_intersecting_overlays", From 94a839de3c775ca5cc00fa32601e48bf61ceee62 Mon Sep 17 00:00:00 2001 From: garyqian Date: Mon, 18 May 2020 06:32:22 -0700 Subject: [PATCH 5/9] Cleanup --- .../scenario_app/lib/src/locale_initialization.dart | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/testing/scenario_app/lib/src/locale_initialization.dart b/testing/scenario_app/lib/src/locale_initialization.dart index 5107813015172..4b9a6051e068c 100644 --- a/testing/scenario_app/lib/src/locale_initialization.dart +++ b/testing/scenario_app/lib/src/locale_initialization.dart @@ -7,9 +7,9 @@ import 'dart:ui'; import 'scenario.dart'; -/// A scenario that sends back messages when touches are received. +/// Sends the recieved locale data back as semantics information. class LocaleInitialization extends Scenario { - /// Constructor for `SendTextFocusScemantics`. + /// Constructor LocaleInitialization(Window window) : assert(window != null), super(window); @@ -35,8 +35,9 @@ class LocaleInitialization extends Scenario { window.render(scene); scene.dispose(); - // On the first frame, also pretend that it drew a text field. Send the - // corresponding semantics tree comprised of 1 node for the text field. + // On the first frame, pretend that it drew a text field. Send the + // corresponding semantics tree comprised of 1 node with the locale data + // as the label. window.updateSemantics((SemanticsUpdateBuilder() ..updateNode( id: 0, @@ -54,7 +55,6 @@ class LocaleInitialization extends Scenario { currentValueLength: 0, scrollChildren: 0, scrollIndex: 0, - // transform: Matrix4.identity().storage, elevation: 0.0, thickness: 0.0, childrenInTraversalOrder: Int32List(0), From cff57ba22efd6f56d5e9810cdb4618df31c96246 Mon Sep 17 00:00:00 2001 From: garyqian Date: Mon, 18 May 2020 13:43:34 -0700 Subject: [PATCH 6/9] Fix test targets --- .../Scenarios/Scenarios.xcodeproj/project.pbxproj | 4 ++++ .../ScenariosUITests/LocalizationInitialization.h | 14 ++++++++++++++ .../LocalizationInitializationTest.m | 11 ++++------- 3 files changed, 22 insertions(+), 7 deletions(-) create mode 100644 testing/scenario_app/ios/Scenarios/ScenariosUITests/LocalizationInitialization.h rename testing/scenario_app/ios/Scenarios/{ScenariosTests => ScenariosUITests}/LocalizationInitializationTest.m (90%) diff --git a/testing/scenario_app/ios/Scenarios/Scenarios.xcodeproj/project.pbxproj b/testing/scenario_app/ios/Scenarios/Scenarios.xcodeproj/project.pbxproj index b0c4a579e85f4..f24db6504742a 100644 --- a/testing/scenario_app/ios/Scenarios/Scenarios.xcodeproj/project.pbxproj +++ b/testing/scenario_app/ios/Scenarios/Scenarios.xcodeproj/project.pbxproj @@ -42,6 +42,7 @@ 3DEF491823C3BE6500184216 /* golden_platform_view_opacity_iPhone 8_simulator.png in Resources */ = {isa = PBXBuildFile; fileRef = 3DE09E8F23C010BD006C9851 /* golden_platform_view_opacity_iPhone 8_simulator.png */; }; 3DEF491923C3BE6500184216 /* golden_platform_view_rotate_iPhone 8_simulator.png in Resources */ = {isa = PBXBuildFile; fileRef = 3DE09E8E23C010BD006C9851 /* golden_platform_view_rotate_iPhone 8_simulator.png */; }; 3DEF491A23C3BE6500184216 /* golden_platform_view_transform_iPhone 8_simulator.png in Resources */ = {isa = PBXBuildFile; fileRef = 3DE09E9123C010BD006C9851 /* golden_platform_view_transform_iPhone 8_simulator.png */; }; + 4F06F1B32473296E000AF246 /* LocalizationInitializationTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 4F06F1B124731F66000AF246 /* LocalizationInitializationTest.m */; }; 59A97FD8236A49D300B4C066 /* golden_platform_view_multiple_iPhone SE_simulator.png in Resources */ = {isa = PBXBuildFile; fileRef = 59A97FD7236A49D300B4C066 /* golden_platform_view_multiple_iPhone SE_simulator.png */; }; 59A97FDA236B984300B4C066 /* golden_platform_view_multiple_background_foreground_iPhone SE_simulator.png in Resources */ = {isa = PBXBuildFile; fileRef = 59A97FD9236B984300B4C066 /* golden_platform_view_multiple_background_foreground_iPhone SE_simulator.png */; }; 6402EBD124147BDA00987DCB /* UnobstructedPlatformViewTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 6402EBD024147BDA00987DCB /* UnobstructedPlatformViewTests.m */; }; @@ -151,6 +152,7 @@ 3DE09E9023C010BD006C9851 /* golden_platform_view_iPhone 8_simulator.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "golden_platform_view_iPhone 8_simulator.png"; sourceTree = ""; }; 3DE09E9123C010BD006C9851 /* golden_platform_view_transform_iPhone 8_simulator.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "golden_platform_view_transform_iPhone 8_simulator.png"; sourceTree = ""; }; 3DE09E9223C010BD006C9851 /* golden_platform_view_cliprect_iPhone 8_simulator.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "golden_platform_view_cliprect_iPhone 8_simulator.png"; sourceTree = ""; }; + 4F06F1B124731F66000AF246 /* LocalizationInitializationTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LocalizationInitializationTest.m; sourceTree = ""; }; 59A97FD7236A49D300B4C066 /* golden_platform_view_multiple_iPhone SE_simulator.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "golden_platform_view_multiple_iPhone SE_simulator.png"; sourceTree = ""; }; 59A97FD9236B984300B4C066 /* golden_platform_view_multiple_background_foreground_iPhone SE_simulator.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "golden_platform_view_multiple_background_foreground_iPhone SE_simulator.png"; sourceTree = ""; }; 6402EBD024147BDA00987DCB /* UnobstructedPlatformViewTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = UnobstructedPlatformViewTests.m; sourceTree = ""; }; @@ -250,6 +252,7 @@ 248D76ED22E388380012F0C1 /* ScenariosUITests */ = { isa = PBXGroup; children = ( + 4F06F1B124731F66000AF246 /* LocalizationInitializationTest.m */, 6402EBD024147BDA00987DCB /* UnobstructedPlatformViewTests.m */, 0D14A3FD239743190013D873 /* golden_platform_view_rotate_iPhone SE_simulator.png */, 3DE09E8B23C010BC006C9851 /* golden_platform_view_clippath_iPhone 8_simulator.png */, @@ -503,6 +506,7 @@ 6816DBA42318358200A51400 /* PlatformViewGoldenTestManager.m in Sources */, 248D76EF22E388380012F0C1 /* PlatformViewUITests.m in Sources */, 0D8470A4240F0B1F0030B565 /* StatusBarTest.m in Sources */, + 4F06F1B32473296E000AF246 /* LocalizationInitializationTest.m in Sources */, 0A42BFB42447E179007E212E /* TextSemanticsFocusTest.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/testing/scenario_app/ios/Scenarios/ScenariosUITests/LocalizationInitialization.h b/testing/scenario_app/ios/Scenarios/ScenariosUITests/LocalizationInitialization.h new file mode 100644 index 0000000000000..d97d6453a376a --- /dev/null +++ b/testing/scenario_app/ios/Scenarios/ScenariosUITests/LocalizationInitialization.h @@ -0,0 +1,14 @@ +// Copyright 2020 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 +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface LocalizationInitializationTest : XCTestCase +@property(nonatomic, strong) XCUIApplication* application; +@end + +NS_ASSUME_NONNULL_END diff --git a/testing/scenario_app/ios/Scenarios/ScenariosTests/LocalizationInitializationTest.m b/testing/scenario_app/ios/Scenarios/ScenariosUITests/LocalizationInitializationTest.m similarity index 90% rename from testing/scenario_app/ios/Scenarios/ScenariosTests/LocalizationInitializationTest.m rename to testing/scenario_app/ios/Scenarios/ScenariosUITests/LocalizationInitializationTest.m index ea4c037e1e9d9..c6b6f9c331011 100644 --- a/testing/scenario_app/ios/Scenarios/ScenariosTests/LocalizationInitializationTest.m +++ b/testing/scenario_app/ios/Scenarios/ScenariosUITests/LocalizationInitializationTest.m @@ -2,9 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#import -#import -#import "AppDelegate.h" +#import "LocalizationInitialization.h" + +FLUTTER_ASSERT_ARC @interface XCUIElement (ftr_waitForNonExistence) /// Keeps waiting until the element doesn't exist. Returns NO if the timeout is @@ -34,10 +34,6 @@ - (BOOL)ftr_waitForNonExistenceForDuration:(NSTimeInterval)duration { @end -@interface LocalizationInitializationTest : XCTestCase -@property(nonatomic, strong) XCUIApplication* application; -@end - @implementation LocalizationInitializationTest - (void)setUp { @@ -57,6 +53,7 @@ - (void)testNoLocalePrepend { XCUIElement* textInputSemanticsObject = [[[self.application textFields] matchingIdentifier:@"[en_US]"] element]; XCTAssertTrue([textInputSemanticsObject waitForExistenceWithTimeout:timeout]); + XCTAssertTrue(false); } @end From 8bdd19dc745d2983ee3c4e54e47cc625a5b887c4 Mon Sep 17 00:00:00 2001 From: garyqian Date: Mon, 18 May 2020 21:14:05 -0700 Subject: [PATCH 7/9] Passes tests now --- .../ScenariosUITests/LocalizationInitializationTest.m | 7 ++++--- testing/scenario_app/lib/src/locale_initialization.dart | 3 +++ 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/testing/scenario_app/ios/Scenarios/ScenariosUITests/LocalizationInitializationTest.m b/testing/scenario_app/ios/Scenarios/ScenariosUITests/LocalizationInitializationTest.m index c6b6f9c331011..b254c6d63f3b8 100644 --- a/testing/scenario_app/ios/Scenarios/ScenariosUITests/LocalizationInitializationTest.m +++ b/testing/scenario_app/ios/Scenarios/ScenariosUITests/LocalizationInitializationTest.m @@ -48,12 +48,13 @@ - (void)setUp { - (void)testNoLocalePrepend { NSTimeInterval timeout = 10.0; + XCUIElement* textInputSemanticsObject = + [[[self.application textFields] matchingIdentifier:@"[en]"] element]; + // The locales recieved by dart:ui are exposed onBeginFrame via semantics label. // There should only be one locale, as we have removed the locale prepend on iOS. - XCUIElement* textInputSemanticsObject = - [[[self.application textFields] matchingIdentifier:@"[en_US]"] element]; XCTAssertTrue([textInputSemanticsObject waitForExistenceWithTimeout:timeout]); - XCTAssertTrue(false); + XCTAssertEqualObjects([textInputSemanticsObject valueForKey:@"hasKeyboardFocus"], @(NO)); } @end diff --git a/testing/scenario_app/lib/src/locale_initialization.dart b/testing/scenario_app/lib/src/locale_initialization.dart index 4b9a6051e068c..f20985eb215e8 100644 --- a/testing/scenario_app/lib/src/locale_initialization.dart +++ b/testing/scenario_app/lib/src/locale_initialization.dart @@ -5,6 +5,8 @@ import 'dart:typed_data'; import 'dart:ui'; +import 'package:vector_math/vector_math_64.dart'; + import 'scenario.dart'; /// Sends the recieved locale data back as semantics information. @@ -55,6 +57,7 @@ class LocaleInitialization extends Scenario { currentValueLength: 0, scrollChildren: 0, scrollIndex: 0, + transform: Matrix4.identity().storage, elevation: 0.0, thickness: 0.0, childrenInTraversalOrder: Int32List(0), From 73d2d8d32abdb439b7a5ee72c72da3e906d63dea Mon Sep 17 00:00:00 2001 From: garyqian Date: Tue, 19 May 2020 00:21:18 -0700 Subject: [PATCH 8/9] Remove extra code --- .../LocalizationInitializationTest.m | 28 ------------------- 1 file changed, 28 deletions(-) diff --git a/testing/scenario_app/ios/Scenarios/ScenariosUITests/LocalizationInitializationTest.m b/testing/scenario_app/ios/Scenarios/ScenariosUITests/LocalizationInitializationTest.m index b254c6d63f3b8..4dee566e05feb 100644 --- a/testing/scenario_app/ios/Scenarios/ScenariosUITests/LocalizationInitializationTest.m +++ b/testing/scenario_app/ios/Scenarios/ScenariosUITests/LocalizationInitializationTest.m @@ -6,34 +6,6 @@ FLUTTER_ASSERT_ARC -@interface XCUIElement (ftr_waitForNonExistence) -/// Keeps waiting until the element doesn't exist. Returns NO if the timeout is -/// reached before it doesn't exist. -- (BOOL)ftr_waitForNonExistenceWithTimeout:(NSTimeInterval)timeout; -/// Waits the full duration to ensure something doesn't exist for that duration. -/// Returns NO if at some point the element exists during the duration. -- (BOOL)ftr_waitForNonExistenceForDuration:(NSTimeInterval)duration; -@end - -@implementation XCUIElement (ftr_waitForNonExistence) -- (BOOL)ftr_waitForNonExistenceWithTimeout:(NSTimeInterval)timeout { - NSTimeInterval delta = 0.5; - while (timeout > 0.0) { - if (!self.exists) { - return YES; - } - usleep(delta * 1000000); - timeout -= delta; - } - return NO; -} - -- (BOOL)ftr_waitForNonExistenceForDuration:(NSTimeInterval)duration { - return ![self waitForExistenceWithTimeout:duration]; -} - -@end - @implementation LocalizationInitializationTest - (void)setUp { From a9e37ec1eb469844ea3d5dd0c87403ab768f7335 Mon Sep 17 00:00:00 2001 From: garyqian Date: Tue, 19 May 2020 15:35:19 -0700 Subject: [PATCH 9/9] Address comments --- .../ScenariosUITests/LocalizationInitialization.h | 14 -------------- .../LocalizationInitializationTest.m | 10 +++++++--- 2 files changed, 7 insertions(+), 17 deletions(-) delete mode 100644 testing/scenario_app/ios/Scenarios/ScenariosUITests/LocalizationInitialization.h diff --git a/testing/scenario_app/ios/Scenarios/ScenariosUITests/LocalizationInitialization.h b/testing/scenario_app/ios/Scenarios/ScenariosUITests/LocalizationInitialization.h deleted file mode 100644 index d97d6453a376a..0000000000000 --- a/testing/scenario_app/ios/Scenarios/ScenariosUITests/LocalizationInitialization.h +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright 2020 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 -#import - -NS_ASSUME_NONNULL_BEGIN - -@interface LocalizationInitializationTest : XCTestCase -@property(nonatomic, strong) XCUIApplication* application; -@end - -NS_ASSUME_NONNULL_END diff --git a/testing/scenario_app/ios/Scenarios/ScenariosUITests/LocalizationInitializationTest.m b/testing/scenario_app/ios/Scenarios/ScenariosUITests/LocalizationInitializationTest.m index 4dee566e05feb..974022ef6ff2e 100644 --- a/testing/scenario_app/ios/Scenarios/ScenariosUITests/LocalizationInitializationTest.m +++ b/testing/scenario_app/ios/Scenarios/ScenariosUITests/LocalizationInitializationTest.m @@ -2,10 +2,15 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#import "LocalizationInitialization.h" +#import +#import FLUTTER_ASSERT_ARC +@interface LocalizationInitializationTest : XCTestCase +@property(nonatomic, strong) XCUIApplication* application; +@end + @implementation LocalizationInitializationTest - (void)setUp { @@ -21,12 +26,11 @@ - (void)testNoLocalePrepend { NSTimeInterval timeout = 10.0; XCUIElement* textInputSemanticsObject = - [[[self.application textFields] matchingIdentifier:@"[en]"] element]; + [self.application.textFields matchingIdentifier:@"[en]"].element; // The locales recieved by dart:ui are exposed onBeginFrame via semantics label. // There should only be one locale, as we have removed the locale prepend on iOS. XCTAssertTrue([textInputSemanticsObject waitForExistenceWithTimeout:timeout]); - XCTAssertEqualObjects([textInputSemanticsObject valueForKey:@"hasKeyboardFocus"], @(NO)); } @end