@@ -41,17 +41,34 @@ - (void)setUp {
41
41
self.continueAfterFailure = NO ;
42
42
}
43
43
44
- // TODO(cbracken): re-enable this test by removing the skip_ prefix once the source of its flakiness
45
- // has been identified. https://github.com/flutter/flutter/issues/61620
46
- - (void )skip_testDismissedFlutterViewControllerNotRespondingToApplicationLifecycle {
47
- XCTestExpectation* engineStartedExpectation = [self expectationWithDescription: @" Engine started" ];
44
+ - (NSArray *)initialPresentLifecycles {
45
+ NSMutableArray * expectations =
46
+ [NSMutableArray arrayWithObject: [[XCAppLifecycleTestExpectation alloc ]
47
+ initForLifecycle: @" AppLifecycleState.inactive"
48
+ forStep: @" showing a FlutterViewController" ]];
49
+
50
+ // If the test is the very first test to run in the test target, the UIApplication may
51
+ // be in inactive state. Haven't found a good way to force it to go to active state.
52
+ // So just account for it in the initial lifecycle events with an extra resumed since
53
+ // the FlutterViewController tracks all view controller and application lifecycle events.
54
+ if ([UIApplication sharedApplication ].applicationState != UIApplicationStateActive) {
55
+ [expectations addObject: [[XCAppLifecycleTestExpectation alloc ]
56
+ initForLifecycle: @" AppLifecycleState.resumed"
57
+ forStep: @" showing a FlutterViewController" ]];
58
+ }
59
+ [expectations addObject: [[XCAppLifecycleTestExpectation alloc ]
60
+ initForLifecycle: @" AppLifecycleState.resumed"
61
+ forStep: @" showing a FlutterViewController" ]];
62
+ return expectations;
63
+ }
48
64
65
+ - (void )testDismissedFlutterViewControllerNotRespondingToApplicationLifecycle {
66
+ XCTestExpectation* engineStartedExpectation = [self expectationWithDescription: @" Engine started" ];
49
67
// Let the engine finish booting (at the end of which the channels are properly set-up) before
50
68
// moving onto the next step of showing the next view controller.
51
69
ScreenBeforeFlutter* rootVC = [[ScreenBeforeFlutter alloc ] initWithEngineRunCompletion: ^void () {
52
70
[engineStartedExpectation fulfill ];
53
71
}];
54
-
55
72
[self waitForExpectationsWithTimeout: 5 handler: nil ];
56
73
57
74
UIApplication* application = UIApplication.sharedApplication ;
@@ -61,36 +78,34 @@ - (void)skip_testDismissedFlutterViewControllerNotRespondingToApplicationLifecyc
61
78
NSMutableArray * lifecycleExpectations = [NSMutableArray arrayWithCapacity: 10 ];
62
79
63
80
// Expected sequence from showing the FlutterViewController is inactive and resumed.
64
- [lifecycleExpectations addObjectsFromArray: @[
65
- [[XCAppLifecycleTestExpectation alloc ] initForLifecycle: @" AppLifecycleState.inactive"
66
- forStep: @" showing a FlutterViewController" ],
67
- [[XCAppLifecycleTestExpectation alloc ] initForLifecycle: @" AppLifecycleState.resumed"
68
- forStep: @" showing a FlutterViewController" ]
69
- ]];
81
+ [lifecycleExpectations addObjectsFromArray: [self initialPresentLifecycles ]];
82
+
83
+ [engine.lifecycleChannel setMessageHandler: ^(id message, FlutterReply callback) {
84
+ if (lifecycleExpectations.count == 0 ) {
85
+ XCTFail (@" Unexpected lifecycle transition: %@ " , message);
86
+ return ;
87
+ }
88
+ XCAppLifecycleTestExpectation* nextExpectation = [lifecycleExpectations objectAtIndex: 0 ];
89
+ if (![[nextExpectation expectedLifecycle ] isEqualToString: message]) {
90
+ XCTFail (@" Expected lifecycle %@ but instead received %@ " , [nextExpectation expectedLifecycle ],
91
+ message);
92
+ return ;
93
+ }
94
+
95
+ [nextExpectation fulfill ];
96
+ [lifecycleExpectations removeObjectAtIndex: 0 ];
97
+ }];
70
98
71
99
FlutterViewController* flutterVC;
72
100
@autoreleasepool {
73
101
// Holding onto this FlutterViewController is consequential here. Since a released
74
102
// FlutterViewController wouldn't keep listening to the application lifecycle events and produce
75
103
// false positives for the application lifecycle tests further below.
76
- flutterVC = [rootVC showFlutter ];
77
- NSLog (@" FlutterViewController instance %@ created" , flutterVC);
78
- [engine.lifecycleChannel setMessageHandler: ^(id message, FlutterReply callback) {
79
- if (lifecycleExpectations.count == 0 ) {
80
- XCTFail (@" Unexpected lifecycle transition: %@ " , message);
81
- return ;
82
- }
83
- XCAppLifecycleTestExpectation* nextExpectation = [lifecycleExpectations objectAtIndex: 0 ];
84
- if (![[nextExpectation expectedLifecycle ] isEqualToString: message]) {
85
- XCTFail (@" Expected lifecycle %@ but instead received %@ " ,
86
- [nextExpectation expectedLifecycle ], message);
87
- return ;
88
- }
89
-
90
- [nextExpectation fulfill ];
91
- [lifecycleExpectations removeObjectAtIndex: 0 ];
104
+ XCTestExpectation* vcShown = [self expectationWithDescription: @" present" ];
105
+ flutterVC = [rootVC showFlutter: ^{
106
+ [vcShown fulfill ];
92
107
}];
93
-
108
+ [ self waitForExpectationsWithTimeout: 5.0 handler: nil ];
94
109
// The expectations list isn't dequeued by the message handler yet.
95
110
[self waitForExpectations: lifecycleExpectations timeout: 5 enforceOrder: YES ];
96
111
@@ -150,7 +165,11 @@ - (void)skip_testDismissedFlutterViewControllerNotRespondingToApplicationLifecyc
150
165
]];
151
166
152
167
@autoreleasepool {
153
- flutterVC = [rootVC showFlutter ];
168
+ XCTestExpectation* vcShown = [self expectationWithDescription: @" present" ];
169
+ flutterVC = [rootVC showFlutter: ^{
170
+ [vcShown fulfill ];
171
+ }];
172
+ [self waitForExpectationsWithTimeout: 5.0 handler: nil ];
154
173
NSLog (@" FlutterViewController instance %@ created" , flutterVC);
155
174
[self waitForExpectations: lifecycleExpectations timeout: 5 enforceOrder: YES ];
156
175
@@ -178,9 +197,7 @@ - (void)skip_testDismissedFlutterViewControllerNotRespondingToApplicationLifecyc
178
197
[engine destroyContext ];
179
198
}
180
199
181
- // TODO(cbracken): re-enable this test by removing the skip_ prefix once the source of its flakiness
182
- // has been identified. https://github.com/flutter/flutter/issues/61620
183
- - (void )skip_testVisibleFlutterViewControllerRespondsToApplicationLifecycle {
200
+ - (void )testVisibleFlutterViewControllerRespondsToApplicationLifecycle {
184
201
XCTestExpectation* engineStartedExpectation = [self expectationWithDescription: @" Engine started" ];
185
202
186
203
// Let the engine finish booting (at the end of which the channels are properly set-up) before
@@ -198,33 +215,31 @@ - (void)skip_testVisibleFlutterViewControllerRespondsToApplicationLifecycle {
198
215
NSMutableArray * lifecycleExpectations = [NSMutableArray arrayWithCapacity: 10 ];
199
216
200
217
// Expected sequence from showing the FlutterViewController is inactive and resumed.
201
- [lifecycleExpectations addObjectsFromArray: @[
202
- [[XCAppLifecycleTestExpectation alloc ] initForLifecycle: @" AppLifecycleState.inactive"
203
- forStep: @" showing a FlutterViewController" ],
204
- [[XCAppLifecycleTestExpectation alloc ] initForLifecycle: @" AppLifecycleState.resumed"
205
- forStep: @" showing a FlutterViewController" ]
206
- ]];
218
+ [lifecycleExpectations addObjectsFromArray: [self initialPresentLifecycles ]];
219
+
220
+ [engine.lifecycleChannel setMessageHandler: ^(id message, FlutterReply callback) {
221
+ if (lifecycleExpectations.count == 0 ) {
222
+ XCTFail (@" Unexpected lifecycle transition: %@ " , message);
223
+ return ;
224
+ }
225
+ XCAppLifecycleTestExpectation* nextExpectation = [lifecycleExpectations objectAtIndex: 0 ];
226
+ if (![[nextExpectation expectedLifecycle ] isEqualToString: message]) {
227
+ XCTFail (@" Expected lifecycle %@ but instead received %@ " , [nextExpectation expectedLifecycle ],
228
+ message);
229
+ return ;
230
+ }
231
+
232
+ [nextExpectation fulfill ];
233
+ [lifecycleExpectations removeObjectAtIndex: 0 ];
234
+ }];
207
235
208
236
FlutterViewController* flutterVC;
209
237
@autoreleasepool {
210
- flutterVC = [rootVC showFlutter ];
211
- NSLog (@" FlutterViewController instance %@ created" , flutterVC);
212
- [engine.lifecycleChannel setMessageHandler: ^(id message, FlutterReply callback) {
213
- if (lifecycleExpectations.count == 0 ) {
214
- XCTFail (@" Unexpected lifecycle transition: %@ " , message);
215
- return ;
216
- }
217
- XCAppLifecycleTestExpectation* nextExpectation = [lifecycleExpectations objectAtIndex: 0 ];
218
- if (![[nextExpectation expectedLifecycle ] isEqualToString: message]) {
219
- XCTFail (@" Expected lifecycle %@ but instead received %@ " ,
220
- [nextExpectation expectedLifecycle ], message);
221
- return ;
222
- }
223
-
224
- [nextExpectation fulfill ];
225
- [lifecycleExpectations removeObjectAtIndex: 0 ];
238
+ XCTestExpectation* vcShown = [self expectationWithDescription: @" present" ];
239
+ flutterVC = [rootVC showFlutter: ^{
240
+ [vcShown fulfill ];
226
241
}];
227
-
242
+ [ self waitForExpectationsWithTimeout: 5.0 handler: nil ];
228
243
[self waitForExpectations: lifecycleExpectations timeout: 5 ];
229
244
230
245
// Now put the FlutterViewController into background.
@@ -285,9 +300,7 @@ - (void)skip_testVisibleFlutterViewControllerRespondsToApplicationLifecycle {
285
300
[engine destroyContext ];
286
301
}
287
302
288
- // TODO(cbracken): re-enable this test by removing the skip_ prefix once the source of its flakiness
289
- // has been identified. https://github.com/flutter/flutter/issues/61620
290
- - (void )skip_testFlutterViewControllerDetachingSendsApplicationLifecycle {
303
+ - (void )testFlutterViewControllerDetachingSendsApplicationLifecycle {
291
304
XCTestExpectation* engineStartedExpectation = [self expectationWithDescription: @" Engine started" ];
292
305
293
306
// Let the engine finish booting (at the end of which the channels are properly set-up) before
@@ -305,34 +318,33 @@ - (void)skip_testFlutterViewControllerDetachingSendsApplicationLifecycle {
305
318
NSMutableArray * lifecycleExpectations = [NSMutableArray arrayWithCapacity: 10 ];
306
319
307
320
// Expected sequence from showing the FlutterViewController is inactive and resumed.
308
- [lifecycleExpectations addObjectsFromArray: @[
309
- [[XCAppLifecycleTestExpectation alloc ] initForLifecycle: @" AppLifecycleState.inactive"
310
- forStep: @" showing a FlutterViewController" ],
311
- [[XCAppLifecycleTestExpectation alloc ] initForLifecycle: @" AppLifecycleState.resumed"
312
- forStep: @" showing a FlutterViewController" ]
313
- ]];
321
+ [lifecycleExpectations addObjectsFromArray: [self initialPresentLifecycles ]];
322
+
323
+ [engine.lifecycleChannel setMessageHandler: ^(id message, FlutterReply callback) {
324
+ if (lifecycleExpectations.count == 0 ) {
325
+ XCTFail (@" Unexpected lifecycle transition: %@ " , message);
326
+ return ;
327
+ }
328
+ XCAppLifecycleTestExpectation* nextExpectation = [lifecycleExpectations objectAtIndex: 0 ];
329
+ if (![[nextExpectation expectedLifecycle ] isEqualToString: message]) {
330
+ XCTFail (@" Expected lifecycle %@ but instead received %@ " , [nextExpectation expectedLifecycle ],
331
+ message);
332
+ return ;
333
+ }
334
+
335
+ [nextExpectation fulfill ];
336
+ [lifecycleExpectations removeObjectAtIndex: 0 ];
337
+ }];
338
+
314
339
// At the end of Flutter VC, we want to make sure it deallocs and sends detached signal.
315
340
// Using autoreleasepool will guarantee that.
316
341
FlutterViewController* flutterVC;
317
342
@autoreleasepool {
318
- flutterVC = [rootVC showFlutter ];
319
- NSLog (@" FlutterViewController instance %@ created" , flutterVC);
320
- [engine.lifecycleChannel setMessageHandler: ^(id message, FlutterReply callback) {
321
- if (lifecycleExpectations.count == 0 ) {
322
- XCTFail (@" Unexpected lifecycle transition: %@ " , message);
323
- return ;
324
- }
325
- XCAppLifecycleTestExpectation* nextExpectation = [lifecycleExpectations objectAtIndex: 0 ];
326
- if (![[nextExpectation expectedLifecycle ] isEqualToString: message]) {
327
- XCTFail (@" Expected lifecycle %@ but instead received %@ " ,
328
- [nextExpectation expectedLifecycle ], message);
329
- return ;
330
- }
331
-
332
- [nextExpectation fulfill ];
333
- [lifecycleExpectations removeObjectAtIndex: 0 ];
343
+ XCTestExpectation* vcShown = [self expectationWithDescription: @" present" ];
344
+ flutterVC = [rootVC showFlutter: ^{
345
+ [vcShown fulfill ];
334
346
}];
335
-
347
+ [ self waitForExpectationsWithTimeout: 5.0 handler: nil ];
336
348
[self waitForExpectations: lifecycleExpectations timeout: 5 ];
337
349
338
350
// Starts dealloc flutter VC.
0 commit comments