Flutter Engine
 
Loading...
Searching...
No Matches
UnobstructedPlatformViewTests.m
Go to the documentation of this file.
1// Copyright 2013 The Flutter Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#import <XCTest/XCTest.h>
6
7static const CGFloat kCompareAccuracy = 0.001;
8
9@interface UnobstructedPlatformViewTests : XCTestCase
10
11@end
12
14
15- (void)setUp {
16 self.continueAfterFailure = NO;
17}
18
19// A is the layer, which z index is higher than the platform view.
20// +--------+
21// | PV | +---+
22// +--------+ | A |
23// +---+
24- (void)testNoOverlay {
25 XCUIApplication* app = [[XCUIApplication alloc] init];
26 app.launchArguments = @[ @"--platform-view-no-overlay-intersection" ];
27 [app launch];
28
29 XCUIElement* platform_view = app.otherElements[@"platform_view[0]"];
30 XCTAssertTrue([platform_view waitForExistenceWithTimeout:1.0]);
31 XCTAssertEqual(platform_view.frame.origin.x, 0);
32 XCTAssertEqual(platform_view.frame.origin.y, 0);
33 XCTAssertEqual(platform_view.frame.size.width, 250);
34 XCTAssertEqual(platform_view.frame.size.height, 250);
35
36 XCUIElement* overlay = app.otherElements[@"platform_view[0].overlay[0]"];
37 XCTAssertFalse(overlay.exists);
38}
39
40// A is the layer above the platform view.
41// +-----------------+
42// | PV +---+ |
43// | | A | |
44// | +---+ |
45// +-----------------+
46- (void)testOneOverlay {
47 XCUIApplication* app = [[XCUIApplication alloc] init];
48 app.launchArguments = @[ @"--platform-view" ];
49 [app launch];
50
51 XCUIElement* platform_view = app.otherElements[@"platform_view[0]"];
52 XCTAssertTrue([platform_view waitForExistenceWithTimeout:1.0]);
53 XCTAssertEqual(platform_view.frame.origin.x, 0);
54 XCTAssertEqual(platform_view.frame.origin.y, 0);
55 XCTAssertEqual(platform_view.frame.size.width, 250);
56 XCTAssertEqual(platform_view.frame.size.height, 250);
57
58 XCUIElement* overlay = app.otherElements[@"platform_view[0].overlay[0]"];
59 XCTAssertTrue(overlay.exists);
60 XCTAssertEqual(overlay.frame.origin.x, 150);
61 XCTAssertEqual(overlay.frame.origin.y, 150);
62 XCTAssertEqual(overlay.frame.size.width, 50);
63 XCTAssertEqual(overlay.frame.size.height, 50);
64
65 XCUIElement* overlayView = app.otherElements[@"platform_view[0].overlay_view[0]"];
66 XCTAssertTrue(overlayView.exists);
67 // Overlay should always be the same frame as the app.
68 XCTAssertEqualWithAccuracy(overlayView.frame.origin.x, app.frame.origin.x, kCompareAccuracy);
69 XCTAssertEqualWithAccuracy(overlayView.frame.origin.y, app.frame.origin.x, kCompareAccuracy);
70 XCTAssertEqualWithAccuracy(overlayView.frame.size.width, app.frame.size.width, kCompareAccuracy);
71 XCTAssertEqualWithAccuracy(overlayView.frame.size.height, app.frame.size.height,
73}
74
75// A is the layer above the platform view.
76// +-----------------+
77// | PV +---+ |
78// +-----------| A |-+
79// +---+
80- (void)testOneOverlayPartialIntersection {
81 XCUIApplication* app = [[XCUIApplication alloc] init];
82 app.launchArguments = @[ @"--platform-view-partial-intersection" ];
83 [app launch];
84
85 XCUIElement* platform_view = app.otherElements[@"platform_view[0]"];
86 XCTAssertTrue([platform_view waitForExistenceWithTimeout:1.0]);
87 XCTAssertEqual(platform_view.frame.origin.x, 0);
88 XCTAssertEqual(platform_view.frame.origin.y, 0);
89 XCTAssertEqual(platform_view.frame.size.width, 250);
90 XCTAssertEqual(platform_view.frame.size.height, 250);
91
92 XCUIElement* overlay = app.otherElements[@"platform_view[0].overlay[0]"];
93 XCTAssertTrue(overlay.exists);
94 XCTAssertEqual(overlay.frame.origin.x, 200);
95 XCTAssertEqual(overlay.frame.origin.y, 245);
96 XCTAssertEqual(overlay.frame.size.width, 50);
97 // Half the height of the overlay.
98 XCTAssertEqual(overlay.frame.size.height, 5);
99
100 XCUIElement* overlayView = app.otherElements[@"platform_view[0].overlay_view[0]"];
101 XCTAssertTrue(overlayView.exists);
102 // Overlay should always be the same frame as the app.
103 XCTAssertEqualWithAccuracy(overlayView.frame.origin.x, app.frame.origin.x, kCompareAccuracy);
104 XCTAssertEqualWithAccuracy(overlayView.frame.origin.y, app.frame.origin.x, kCompareAccuracy);
105 XCTAssertEqualWithAccuracy(overlayView.frame.size.width, app.frame.size.width, kCompareAccuracy);
106 XCTAssertEqualWithAccuracy(overlayView.frame.size.height, app.frame.size.height,
108}
109
110// A and B are the layers above the platform view.
111// +--------------------+
112// | PV +------------+ |
113// | | B +-----+ | |
114// | +---| A |-+ |
115// +----------| |---+
116// +-----+
117- (void)testTwoIntersectingOverlays {
118 XCUIApplication* app = [[XCUIApplication alloc] init];
119 app.launchArguments = @[ @"--platform-view-two-intersecting-overlays" ];
120 [app launch];
121
122 XCUIElement* platform_view = app.otherElements[@"platform_view[0]"];
123 XCTAssertTrue([platform_view waitForExistenceWithTimeout:1.0]);
124 XCTAssertEqual(platform_view.frame.origin.x, 0);
125 XCTAssertEqual(platform_view.frame.origin.y, 0);
126 XCTAssertEqual(platform_view.frame.size.width, 250);
127 XCTAssertEqual(platform_view.frame.size.height, 250);
128
129 XCUIElement* overlay = app.otherElements[@"platform_view[0].overlay[0]"];
130 XCTAssertTrue(overlay.exists);
131 XCTAssertEqual(overlay.frame.origin.x, 150);
132 XCTAssertEqual(overlay.frame.origin.y, 150);
133 XCTAssertEqual(overlay.frame.size.width, 75);
134 XCTAssertEqual(overlay.frame.size.height, 75);
135
136 XCTAssertFalse(app.otherElements[@"platform_view[0].overlay[1]"].exists);
137}
138
139// A, B, and C are the layers above the platform view.
140// +-------------------------+
141// | PV +-----------+ |
142// | +---+ | B +-----+ | |
143// | | C | +---| A |-+ |
144// | +---+ +-----+ |
145// +-------------------------+
146- (void)testOneOverlayAndTwoIntersectingOverlays {
147 XCUIApplication* app = [[XCUIApplication alloc] init];
148 app.launchArguments = @[ @"--platform-view-one-overlay-two-intersecting-overlays" ];
149 [app launch];
150
151 XCUIElement* platform_view = app.otherElements[@"platform_view[0]"];
152 XCTAssertTrue([platform_view waitForExistenceWithTimeout:1.0]);
153 XCTAssertEqual(platform_view.frame.origin.x, 0);
154 XCTAssertEqual(platform_view.frame.origin.y, 0);
155 XCTAssertEqual(platform_view.frame.size.width, 250);
156 XCTAssertEqual(platform_view.frame.size.height, 250);
157
158 XCUIElement* overlay1 = app.otherElements[@"platform_view[0].overlay[0]"];
159 XCTAssertTrue(overlay1.exists);
160 XCTAssertEqual(overlay1.frame.origin.x, 75);
161 XCTAssertEqual(overlay1.frame.origin.y, 150);
162 XCTAssertEqual(overlay1.frame.size.width, 150);
163 XCTAssertEqual(overlay1.frame.size.height, 100);
164
165 // There are three non overlapping rects above platform view, which
166 // FlutterPlatformViewsController merges into one.
167 XCTAssertFalse(app.otherElements[@"platform_view[0].overlay[1]"].exists);
168
169 XCUIElement* overlayView0 = app.otherElements[@"platform_view[0].overlay_view[0]"];
170 XCTAssertTrue(overlayView0.exists);
171 // Overlay should always be the same frame as the app.
172 XCTAssertEqualWithAccuracy(overlayView0.frame.origin.x, app.frame.origin.x, kCompareAccuracy);
173 XCTAssertEqualWithAccuracy(overlayView0.frame.origin.y, app.frame.origin.x, kCompareAccuracy);
174 XCTAssertEqualWithAccuracy(overlayView0.frame.size.width, app.frame.size.width, kCompareAccuracy);
175 XCTAssertEqualWithAccuracy(overlayView0.frame.size.height, app.frame.size.height,
177}
178
179// A is the layer, which z index is higher than the platform view.
180// +--------+
181// | PV | +---+
182// +--------+ | A |
183// +--------+ +---+
184// | PV |
185// +--------+
186- (void)testMultiplePlatformViewsWithoutOverlays {
187 XCUIApplication* app = [[XCUIApplication alloc] init];
188 app.launchArguments = @[ @"--platform-view-multiple-without-overlays" ];
189 [app launch];
190
191 XCUIElement* platform_view1 = app.otherElements[@"platform_view[0]"];
192 XCTAssertTrue([platform_view1 waitForExistenceWithTimeout:1.0]);
193 XCTAssertEqual(platform_view1.frame.origin.x, 0);
194 XCTAssertEqual(platform_view1.frame.origin.y, 300);
195 XCTAssertEqual(platform_view1.frame.size.width, 250);
196 XCTAssertEqual(platform_view1.frame.size.height, 250);
197
198 XCUIElement* platform_view2 = app.otherElements[@"platform_view[1]"];
199 XCTAssertTrue(platform_view2.exists);
200 XCTAssertEqual(platform_view2.frame.origin.x, 0);
201 XCTAssertEqual(platform_view2.frame.origin.y, 0);
202 XCTAssertEqual(platform_view2.frame.size.width, 250);
203 XCTAssertEqual(platform_view2.frame.size.height, 250);
204
205 XCTAssertFalse(app.otherElements[@"platform_view[0].overlay[0]"].exists);
206 XCTAssertFalse(app.otherElements[@"platform_view[1].overlay[0]"].exists);
207 XCTAssertFalse(app.otherElements[@"platform_view[0].overlay_view[0]"].exists);
208 XCTAssertFalse(app.otherElements[@"platform_view[1].overlay_view[0]"].exists);
209}
210
211// A is the layer above both platform view.
212// +------------+
213// | PV +----+ |
214// +-----| A |-+
215// +-----| |-+
216// | PV +----+ |
217// +------------+
218- (void)testMultiplePlatformViewsWithOverlays {
219 XCUIApplication* app = [[XCUIApplication alloc] init];
220 app.launchArguments = @[ @"--platform-view-multiple-background-foreground" ];
221 [app launch];
222
223 XCUIElement* platform_view1 = app.otherElements[@"platform_view[0]"];
224 XCTAssertTrue([platform_view1 waitForExistenceWithTimeout:1.0]);
225 XCTAssertEqual(platform_view1.frame.origin.x, 25);
226 XCTAssertEqual(platform_view1.frame.origin.y, 300);
227 XCTAssertEqual(platform_view1.frame.size.width, 250);
228 XCTAssertEqual(platform_view1.frame.size.height, 250);
229
230 XCUIElement* platform_view2 = app.otherElements[@"platform_view[1]"];
231 XCTAssertTrue(platform_view2.exists);
232 XCTAssertEqual(platform_view2.frame.origin.x, 25);
233 XCTAssertEqual(platform_view2.frame.origin.y, 0);
234 XCTAssertEqual(platform_view2.frame.size.width, 250);
235 XCTAssertEqual(platform_view2.frame.size.height, 250);
236
237 XCUIElement* overlay1 = app.otherElements[@"platform_view[1].overlay[0]"];
238 XCTAssertTrue(overlay1.exists);
239 XCTAssertEqual(overlay1.frame.origin.x, 25);
240 XCTAssertEqual(overlay1.frame.origin.y, 0);
241 XCTAssertEqual(overlay1.frame.size.width, 225);
242 XCTAssertEqual(overlay1.frame.size.height, 500);
243
244 XCUIElement* overlayView0 = app.otherElements[@"platform_view[1].overlay_view[0]"];
245 XCTAssertTrue(overlayView0.exists);
246 // Overlay should always be the same frame as the app.
247 XCTAssertEqualWithAccuracy(overlayView0.frame.origin.x, app.frame.origin.x, kCompareAccuracy);
248 XCTAssertEqualWithAccuracy(overlayView0.frame.origin.y, app.frame.origin.x, kCompareAccuracy);
249 XCTAssertEqualWithAccuracy(overlayView0.frame.size.width, app.frame.size.width, kCompareAccuracy);
250 XCTAssertEqualWithAccuracy(overlayView0.frame.size.height, app.frame.size.height,
252}
253
254// More then two overlays are merged into a single layer.
255// +---------------------+
256// | +---+ +---+ +---+ |
257// | | A | | B | | C | |
258// | +---+ +---+ +---+ |
259// | +-------+ |
260// +-| D |-----------+
261// +-------+
262- (void)testPlatformViewsMaxOverlays {
263 XCUIApplication* app = [[XCUIApplication alloc] init];
264 app.launchArguments = @[ @"--platform-view-max-overlays" ];
265 [app launch];
266
267 XCUIElement* platform_view = app.otherElements[@"platform_view[0]"];
268 XCTAssertTrue([platform_view waitForExistenceWithTimeout:1.0]);
269 XCTAssertEqual(platform_view.frame.origin.x, 0);
270 XCTAssertEqual(platform_view.frame.origin.y, 0);
271 XCTAssertEqual(platform_view.frame.size.width, 250);
272 XCTAssertEqual(platform_view.frame.size.height, 250);
273
274 XCUIElement* overlay = app.otherElements[@"platform_view[0].overlay[0]"];
275 XCTAssertTrue(overlay.exists);
276 XCTAssertFalse(app.otherElements[@"platform_view[0].overlay[1]"].exists);
277 XCTAssertTrue(CGRectContainsRect(platform_view.frame, overlay.frame));
278
279 XCUIElement* overlayView0 = app.otherElements[@"platform_view[0].overlay_view[0]"];
280 XCTAssertTrue(overlayView0.exists);
281 // Overlay should always be the same frame as the app.
282 XCTAssertEqualWithAccuracy(overlayView0.frame.origin.x, app.frame.origin.x, kCompareAccuracy);
283 XCTAssertEqualWithAccuracy(overlayView0.frame.origin.y, app.frame.origin.x, kCompareAccuracy);
284 XCTAssertEqualWithAccuracy(overlayView0.frame.size.width, app.frame.size.width, kCompareAccuracy);
285 XCTAssertEqualWithAccuracy(overlayView0.frame.size.height, app.frame.size.height,
287
288 XCUIElement* overlayView1 = app.otherElements[@"platform_view[0].overlay_view[1]"];
289 XCTAssertFalse(overlayView1.exists);
290}
291
292// Platform view surrounded by adjacent layers on each side should not create any overlays.
293// +----+
294// | B |
295// +---+----+---+
296// | A | PV | C |
297// +---+----+---+
298// | D |
299// +----+
300- (void)testPlatformViewsWithAdjacentSurroundingLayersAndFractionalCoordinate {
301 XCUIApplication* app = [[XCUIApplication alloc] init];
302 app.launchArguments = @[ @"--platform-view-surrounding-layers-fractional-coordinate" ];
303 [app launch];
304
305 XCUIElement* platform_view = app.otherElements[@"platform_view[0]"];
306 XCTAssertTrue([platform_view waitForExistenceWithTimeout:1.0]);
307
308 CGFloat scale = [UIScreen mainScreen].scale;
309 XCTAssertEqual(platform_view.frame.origin.x * scale, 100.5);
310 XCTAssertEqual(platform_view.frame.origin.y * scale, 100.5);
311 XCTAssertEqual(platform_view.frame.size.width * scale, 100);
312 XCTAssertEqual(platform_view.frame.size.height * scale, 100);
313
314 XCUIElement* overlay = app.otherElements[@"platform_view[0].overlay[0]"];
315 XCTAssertFalse(overlay.exists);
316}
317
318// Platform view partially intersect with a layer in fractional coordinate.
319// +-------+
320// | |
321// | PV +--+--+
322// | | |
323// +----+ A |
324// | |
325// +-----+
326- (void)testPlatformViewsWithPartialIntersectionAndFractionalCoordinate {
327 XCUIApplication* app = [[XCUIApplication alloc] init];
328 app.launchArguments = @[ @"--platform-view-partial-intersection-fractional-coordinate" ];
329 [app launch];
330
331 XCUIElement* platform_view = app.otherElements[@"platform_view[0]"];
332 XCTAssertTrue([platform_view waitForExistenceWithTimeout:1.0]);
333
334 CGFloat scale = [UIScreen mainScreen].scale;
335 XCTAssertEqual(platform_view.frame.origin.x * scale, 0.5);
336 XCTAssertEqual(platform_view.frame.origin.y * scale, 0.5);
337 XCTAssertEqual(platform_view.frame.size.width * scale, 100);
338 XCTAssertEqual(platform_view.frame.size.height * scale, 100);
339
340 XCUIElement* overlay = app.otherElements[@"platform_view[0].overlay[0]"];
341 XCTAssert(overlay.exists);
342
343 // We want to make sure the overlay covers the edge (which is at 100.5).
344 XCTAssertEqual(CGRectGetMaxX(overlay.frame) * scale, 101);
345 XCTAssertEqual(CGRectGetMaxY(overlay.frame) * scale, 101);
346}
347@end
std::unique_ptr< flutter::PlatformViewIOS > platform_view
static const CGFloat kCompareAccuracy