diff --git a/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm b/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm index 857ad0e486a4d..ec9b0a34fe8bb 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm @@ -942,10 +942,10 @@ - (FlutterEngine*)spawnWithEntrypoint:(/*nullable*/ NSString*)entrypoint SetEntryPoint(&settings, entrypoint, libraryURI); flutter::Shell::CreateCallback on_create_platform_view = - [self](flutter::Shell& shell) { - [self recreatePlatformViewController]; + [result](flutter::Shell& shell) { + [result recreatePlatformViewController]; return std::make_unique( - shell, self->_renderingApi, self->_platformViewsController, shell.GetTaskRunners()); + shell, result->_renderingApi, result->_platformViewsController, shell.GetTaskRunners()); }; flutter::Shell::CreateCallback on_create_rasterizer = diff --git a/testing/scenario_app/ios/Scenarios/Scenarios.xcodeproj/project.pbxproj b/testing/scenario_app/ios/Scenarios/Scenarios.xcodeproj/project.pbxproj index b86187a454fc4..70a8e0c23ccdb 100644 --- a/testing/scenario_app/ios/Scenarios/Scenarios.xcodeproj/project.pbxproj +++ b/testing/scenario_app/ios/Scenarios/Scenarios.xcodeproj/project.pbxproj @@ -23,6 +23,8 @@ 0DB7820022EA2C9D00E9B371 /* App.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 246B4E4122E3B5F700073EBF /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 0DB7820122EA2CA500E9B371 /* App.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 246B4E4122E3B5F700073EBF /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 0DB7820222EA493B00E9B371 /* FlutterViewControllerTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 0DB781FC22EA2C0300E9B371 /* FlutterViewControllerTest.m */; }; + 0DDEBC89258830B40065D0E8 /* SpawnEngineTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 0DDEBC88258830B40065D0E8 /* SpawnEngineTest.m */; }; + 0DDEBC8B258839760065D0E8 /* golden_spawn_engine_works_iPhone 8_simulator.png in Resources */ = {isa = PBXBuildFile; fileRef = 0DDEBC8A258839760065D0E8 /* golden_spawn_engine_works_iPhone 8_simulator.png */; }; 242F37A222E636DE001E83D4 /* Flutter.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 246B4E4522E3B61000073EBF /* Flutter.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 242F37A322E636DE001E83D4 /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 246B4E4122E3B5F700073EBF /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 244EA6D0230DBE8900B2D26E /* golden_platform_view_D21AP.png in Resources */ = {isa = PBXBuildFile; fileRef = 244EA6CF230DBE8900B2D26E /* golden_platform_view_D21AP.png */; }; @@ -124,6 +126,9 @@ 0D8470A2240F0B1F0030B565 /* StatusBarTest.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = StatusBarTest.h; sourceTree = ""; }; 0D8470A3240F0B1F0030B565 /* StatusBarTest.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = StatusBarTest.m; sourceTree = ""; }; 0DB781FC22EA2C0300E9B371 /* FlutterViewControllerTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FlutterViewControllerTest.m; sourceTree = ""; }; + 0DDEBC87258830B40065D0E8 /* SpawnEngineTest.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SpawnEngineTest.h; sourceTree = ""; }; + 0DDEBC88258830B40065D0E8 /* SpawnEngineTest.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SpawnEngineTest.m; sourceTree = ""; }; + 0DDEBC8A258839760065D0E8 /* golden_spawn_engine_works_iPhone 8_simulator.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "golden_spawn_engine_works_iPhone 8_simulator.png"; sourceTree = ""; }; 244EA6CF230DBE8900B2D26E /* golden_platform_view_D21AP.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = golden_platform_view_D21AP.png; sourceTree = ""; }; 246A6610252E693A00EAB0F3 /* RenderingSelectionTest.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RenderingSelectionTest.m; sourceTree = ""; }; 246B4E4122E3B5F700073EBF /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = App.framework; sourceTree = ""; }; @@ -252,6 +257,7 @@ 248D76ED22E388380012F0C1 /* ScenariosUITests */ = { isa = PBXGroup; children = ( + 0DDEBC8A258839760065D0E8 /* golden_spawn_engine_works_iPhone 8_simulator.png */, 4F06F1B124731F66000AF246 /* LocalizationInitializationTest.m */, 6402EBD024147BDA00987DCB /* UnobstructedPlatformViewTests.m */, 0AC83145256E534E00DAE6BE /* golden_bogus_font_text_iPhone 8_simulator.png */, @@ -284,6 +290,8 @@ 0A42BFB32447E179007E212E /* TextSemanticsFocusTest.m */, 0A42BFB52447E19F007E212E /* TextSemanticsFocusTest.h */, 246A6610252E693A00EAB0F3 /* RenderingSelectionTest.m */, + 0DDEBC87258830B40065D0E8 /* SpawnEngineTest.h */, + 0DDEBC88258830B40065D0E8 /* SpawnEngineTest.m */, ); path = ScenariosUITests; sourceTree = ""; @@ -433,6 +441,7 @@ 59A97FDA236B984300B4C066 /* golden_platform_view_multiple_background_foreground_iPhone SE_simulator.png in Resources */, 3DEF491923C3BE6500184216 /* golden_platform_view_rotate_iPhone 8_simulator.png in Resources */, 24D47D1B230C79840069DD5E /* golden_platform_view_D211AP.png in Resources */, + 0DDEBC8B258839760065D0E8 /* golden_spawn_engine_works_iPhone 8_simulator.png in Resources */, 244EA6D0230DBE8900B2D26E /* golden_platform_view_D21AP.png in Resources */, 3DEF491A23C3BE6500184216 /* golden_platform_view_transform_iPhone 8_simulator.png in Resources */, ); @@ -480,6 +489,7 @@ 246A6611252E693A00EAB0F3 /* RenderingSelectionTest.m in Sources */, 4F06F1B32473296E000AF246 /* LocalizationInitializationTest.m in Sources */, 0A42BFB42447E179007E212E /* TextSemanticsFocusTest.m in Sources */, + 0DDEBC89258830B40065D0E8 /* SpawnEngineTest.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/testing/scenario_app/ios/Scenarios/Scenarios/AppDelegate.m b/testing/scenario_app/ios/Scenarios/Scenarios/AppDelegate.m index 4a73ada21e119..a093d12ee574f 100644 --- a/testing/scenario_app/ios/Scenarios/Scenarios/AppDelegate.m +++ b/testing/scenario_app/ios/Scenarios/Scenarios/AppDelegate.m @@ -54,7 +54,8 @@ - (BOOL)application:(UIApplication*)application @"--text-semantics-focus" : @"text_semantics_focus", @"--animated-color-square" : @"animated_color_square", @"--platform-view-with-continuous-texture" : @"platform_view_with_continuous_texture", - @"--bogus-font-text" : @"bogus_font_text" + @"--bogus-font-text" : @"bogus_font_text", + @"--spawn-engine-works" : @"spawn_engine_works", }; __block NSString* flutterViewControllerTestName = nil; [launchArgsMap @@ -80,6 +81,20 @@ - (BOOL)application:(UIApplication*)application return [super application:application didFinishLaunchingWithOptions:launchOptions]; } +- (FlutterEngine*)engineForTest:(NSString*)scenarioIdentifier { + if ([scenarioIdentifier isEqualToString:@"spawn_engine_works"]) { + FlutterEngine* spawner = [[FlutterEngine alloc] initWithName:@"FlutterControllerTest" + project:nil]; + [spawner run]; + return [spawner spawnWithEntrypoint:nil libraryURI:nil]; + } else { + FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"FlutterControllerTest" + project:nil]; + [engine run]; + return engine; + } +} + - (FlutterViewController*)flutterViewControllerForTest:(NSString*)scenarioIdentifier withEngine:(FlutterEngine*)engine { if ([scenarioIdentifier isEqualToString:@"tap_status_bar"]) { @@ -90,9 +105,7 @@ - (FlutterViewController*)flutterViewControllerForTest:(NSString*)scenarioIdenti } - (void)setupFlutterViewControllerTest:(NSString*)scenarioIdentifier { - FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"FlutterControllerTest" project:nil]; - [engine run]; - + FlutterEngine* engine = [self engineForTest:scenarioIdentifier]; FlutterViewController* flutterViewController = [self flutterViewControllerForTest:scenarioIdentifier withEngine:engine]; diff --git a/testing/scenario_app/ios/Scenarios/Scenarios/FlutterEngine+ScenariosTest.h b/testing/scenario_app/ios/Scenarios/Scenarios/FlutterEngine+ScenariosTest.h index 8b04f666f2676..aef6bae0aa5d6 100644 --- a/testing/scenario_app/ios/Scenarios/Scenarios/FlutterEngine+ScenariosTest.h +++ b/testing/scenario_app/ios/Scenarios/Scenarios/FlutterEngine+ScenariosTest.h @@ -8,5 +8,7 @@ NS_ASSUME_NONNULL_BEGIN @interface FlutterEngine (ScenariosTest) - (instancetype)initWithScenario:(NSString*)scenario withCompletion:(nullable void (^)(void))engineRunCompletion; +- (FlutterEngine*)spawnWithEntrypoint:(nullable NSString*)entrypoint + libraryURI:(nullable NSString*)libraryURI; @end NS_ASSUME_NONNULL_END diff --git a/testing/scenario_app/ios/Scenarios/ScenariosUITests/SpawnEngineTest.h b/testing/scenario_app/ios/Scenarios/ScenariosUITests/SpawnEngineTest.h new file mode 100644 index 0000000000000..8d8e0fd5ab0f8 --- /dev/null +++ b/testing/scenario_app/ios/Scenarios/ScenariosUITests/SpawnEngineTest.h @@ -0,0 +1,13 @@ +// 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 + +NS_ASSUME_NONNULL_BEGIN + +@interface SpawnEngineTest : XCTestCase +@property(nonatomic, strong) XCUIApplication* application; +@end + +NS_ASSUME_NONNULL_END diff --git a/testing/scenario_app/ios/Scenarios/ScenariosUITests/SpawnEngineTest.m b/testing/scenario_app/ios/Scenarios/ScenariosUITests/SpawnEngineTest.m new file mode 100644 index 0000000000000..968d55d776e90 --- /dev/null +++ b/testing/scenario_app/ios/Scenarios/ScenariosUITests/SpawnEngineTest.m @@ -0,0 +1,38 @@ +// 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 "SpawnEngineTest.h" +#import "GoldenImage.h" + +@implementation SpawnEngineTest + +- (void)setUp { + [super setUp]; + self.continueAfterFailure = NO; + + self.application = [[XCUIApplication alloc] init]; + self.application.launchArguments = @[ @"--spawn-engine-works", @"--enable-software-rendering" ]; + [self.application launch]; +} + +- (void)testSpawnEngineWorks { + NSString* prefix = @"golden_spawn_engine_works_"; + GoldenImage* golden = [[GoldenImage alloc] initWithGoldenNamePrefix:prefix]; + if (!golden.image) { + XCTFail(@"unable to find golden image for: %@", prefix); + } + XCUIScreenshot* screenshot = [[XCUIScreen mainScreen] screenshot]; + if (![golden compareGoldenToImage:screenshot.image]) { + XCTAttachment* screenshotAttachment = [XCTAttachment attachmentWithImage:screenshot.image]; + screenshotAttachment.name = [golden.goldenName stringByAppendingString:@"_actual"]; + screenshotAttachment.lifetime = XCTAttachmentLifetimeKeepAlways; + [self addAttachment:screenshotAttachment]; + + XCTFail(@"Goldens do not match. Follow the steps in the " + @"README to update golden named %@ if needed.", + golden.goldenName); + } +} + +@end diff --git a/testing/scenario_app/ios/Scenarios/ScenariosUITests/golden_spawn_engine_works_iPhone 8_simulator.png b/testing/scenario_app/ios/Scenarios/ScenariosUITests/golden_spawn_engine_works_iPhone 8_simulator.png new file mode 100644 index 0000000000000..ee124e0089ca8 Binary files /dev/null and b/testing/scenario_app/ios/Scenarios/ScenariosUITests/golden_spawn_engine_works_iPhone 8_simulator.png differ diff --git a/testing/scenario_app/lib/src/scenarios.dart b/testing/scenario_app/lib/src/scenarios.dart index ea3ff807d49da..8f8413e0b5e05 100644 --- a/testing/scenario_app/lib/src/scenarios.dart +++ b/testing/scenario_app/lib/src/scenarios.dart @@ -46,6 +46,7 @@ Map _scenarios = { 'initial_route_reply': () => InitialRouteReply(PlatformDispatcher.instance), 'platform_view_with_continuous_texture': () => PlatformViewWithContinuousTexture(PlatformDispatcher.instance, 'Platform View', id: _viewId++), 'bogus_font_text': () => BogusFontText(PlatformDispatcher.instance), + 'spawn_engine_works' : () => BogusFontText(PlatformDispatcher.instance), }; Map _currentScenarioParams = {}; diff --git a/testing/scenario_app/run_ios_tests.sh b/testing/scenario_app/run_ios_tests.sh index 225f88e977f2e..13a8e3cd60ac6 100755 --- a/testing/scenario_app/run_ios_tests.sh +++ b/testing/scenario_app/run_ios_tests.sh @@ -36,6 +36,6 @@ fi cd ios/Scenarios set -o pipefail && xcodebuild -sdk iphonesimulator \ -scheme Scenarios \ - -destination 'platform=iOS Simulator,name=iPhone 8' \ + -destination 'platform=iOS Simulator,OS=13.0,name=iPhone 8' \ test \ FLUTTER_ENGINE="$FLUTTER_ENGINE"