Skip to content

Commit b22388e

Browse files
authored
Add a flutter app that can resize itself as integration test app. (#112297)
1 parent 34407cc commit b22388e

File tree

6 files changed

+191
-2
lines changed

6 files changed

+191
-2
lines changed

.ci.yaml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2642,6 +2642,16 @@ targets:
26422642
["devicelab", "hostonly"]
26432643
task_name: hello_world_macos__compile
26442644

2645+
- name: Mac integration_ui_test_test_macos
2646+
bringup: true
2647+
recipe: devicelab/devicelab_drone
2648+
presubmit: false
2649+
timeout: 60
2650+
properties:
2651+
tags: >
2652+
["devicelab", "mac"]
2653+
task_name: integration_ui_test_test_macos
2654+
26452655
- name: Mac module_custom_host_app_name_test
26462656
recipe: devicelab/devicelab_drone
26472657
timeout: 60

TESTOWNERS

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -219,10 +219,10 @@
219219
/dev/devicelab/bin/tasks/flutter_gallery_macos__start_up.dart @a-wallen @flutter/desktop
220220
/dev/devicelab/bin/tasks/flutter_gallery_win_desktop__compile.dart @yaakovschectman @flutter/desktop
221221
/dev/devicelab/bin/tasks/flutter_gallery_win_desktop__start_up.dart @yaakovschectman @flutter/desktop
222-
/dev/devicelab/bin/tasks/flutter_view_macos__start_up.dart @a-wallen @flutter/desktop
223-
/dev/devicelab/bin/tasks/flutter_tool_startup__windows.dart @jensjoha @flutter/tool
224222
/dev/devicelab/bin/tasks/flutter_tool_startup__linux.dart @jensjoha @flutter/tool
225223
/dev/devicelab/bin/tasks/flutter_tool_startup__macos.dart @jensjoha @flutter/tool
224+
/dev/devicelab/bin/tasks/flutter_tool_startup__windows.dart @jensjoha @flutter/tool
225+
/dev/devicelab/bin/tasks/flutter_view_macos__start_up.dart @a-wallen @flutter/desktop
226226
/dev/devicelab/bin/tasks/flutter_view_win_desktop__start_up.dart @yaakovschectman @flutter/desktop
227227
/dev/devicelab/bin/tasks/gradle_desugar_classes_test.dart @zanderso @flutter/tool
228228
/dev/devicelab/bin/tasks/gradle_non_android_plugin_test.dart @stuartmorgan @flutter/plugin
@@ -236,6 +236,7 @@
236236
/dev/devicelab/bin/tasks/hello_world_macos__compile.dart @a-wallen @flutter/desktop
237237
/dev/devicelab/bin/tasks/hello_world_win_desktop__compile.dart @yaakovschectman @flutter/desktop
238238
/dev/devicelab/bin/tasks/hot_mode_dev_cycle_win_target__benchmark.dart @cbracken @flutter/desktop
239+
/dev/devicelab/bin/tasks/integration_ui_test_test_macos.dart @a-wallen @flutter/desktop
239240
/dev/devicelab/bin/tasks/module_custom_host_app_name_test.dart @zanderso @flutter/tool
240241
/dev/devicelab/bin/tasks/module_host_with_custom_build_test.dart @zanderso @flutter/tool
241242
/dev/devicelab/bin/tasks/module_test_ios.dart @jmagman @flutter/tool
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// Copyright 2014 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 'package:flutter_devicelab/framework/devices.dart';
6+
import 'package:flutter_devicelab/framework/framework.dart';
7+
import 'package:flutter_devicelab/tasks/integration_tests.dart';
8+
9+
Future<void> main() async {
10+
deviceOperatingSystem = DeviceOperatingSystem.macos;
11+
await task(createEndToEndIntegrationTest());
12+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
// Copyright 2014 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 'package:flutter/widgets.dart' as widgets show Container, Size, runApp;
6+
import 'package:flutter_test/flutter_test.dart';
7+
import 'package:integration_test/integration_test.dart';
8+
import 'package:integration_ui/resize.dart' as app;
9+
10+
void main() {
11+
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
12+
13+
group('end-to-end test', () {
14+
testWidgets('Use button to resize window',
15+
timeout: const Timeout(Duration(seconds: 5)),
16+
(WidgetTester tester) async {
17+
const app.ResizeApp resizeApp = app.ResizeApp();
18+
19+
widgets.runApp(resizeApp);
20+
await tester.pumpAndSettle();
21+
22+
final Finder fab = find.byKey(app.ResizeApp.extendedFab);
23+
expect(fab, findsOneWidget);
24+
25+
final Finder root = find.byWidget(resizeApp);
26+
final widgets.Size sizeBefore = tester.getSize(root);
27+
28+
await tester.tap(fab);
29+
await tester.pumpAndSettle();
30+
31+
final widgets.Size sizeAfter = tester.getSize(root);
32+
expect(sizeAfter.width, equals(sizeBefore.width + app.ResizeApp.resizeBy));
33+
expect(sizeAfter.height, equals(sizeBefore.height + app.ResizeApp.resizeBy));
34+
35+
final Finder widthLabel = find.byKey(app.ResizeApp.widthLabel);
36+
expect(widthLabel, findsOneWidget);
37+
expect(find.text('width: ${sizeAfter.width}'), findsOneWidget);
38+
39+
final Finder heightLabel = find.byKey(app.ResizeApp.heightLabel);
40+
expect(heightLabel, findsOneWidget);
41+
expect(find.text('height: ${sizeAfter.height}'), findsOneWidget);
42+
});
43+
});
44+
45+
testWidgets('resize window after calling runApp twice, the second with no content',
46+
timeout: const Timeout(Duration(seconds: 5)),
47+
(WidgetTester tester) async {
48+
const app.ResizeApp root = app.ResizeApp();
49+
widgets.runApp(root);
50+
widgets.runApp(widgets.Container());
51+
52+
await tester.pumpAndSettle();
53+
54+
const widgets.Size expectedSize = widgets.Size(100, 100);
55+
await app.ResizeApp.resize(expectedSize);
56+
});
57+
}
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
// Copyright 2014 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 'package:flutter/material.dart';
6+
import 'package:flutter/services.dart';
7+
8+
void main() async {
9+
runApp(const ResizeApp());
10+
}
11+
12+
class ResizeApp extends StatefulWidget {
13+
const ResizeApp({super.key});
14+
15+
static const double resizeBy = 10.0;
16+
static const Key heightLabel = Key('height label');
17+
static const Key widthLabel = Key('width label');
18+
static const Key extendedFab = Key('extended FAB');
19+
20+
static const MethodChannel platform =
21+
MethodChannel('samples.flutter.dev/resize');
22+
23+
static Future<void> resize(Size size) async {
24+
await ResizeApp.platform.invokeMethod<void>(
25+
'resize',
26+
<String, dynamic>{
27+
'width': size.width,
28+
'height': size.height,
29+
}
30+
);
31+
}
32+
33+
@override
34+
State<ResizeApp> createState() => _ResizeAppState();
35+
}
36+
37+
class _ResizeAppState extends State<ResizeApp> {
38+
@override
39+
Widget build(BuildContext context) {
40+
return MaterialApp(
41+
home: Builder(
42+
builder: (BuildContext context) {
43+
final Size currentSize = MediaQuery.of(context).size;
44+
return Scaffold(
45+
floatingActionButton: FloatingActionButton.extended(
46+
key: ResizeApp.extendedFab,
47+
label: const Text('Resize'),
48+
onPressed: () {
49+
final Size nextSize = Size(
50+
currentSize.width + ResizeApp.resizeBy,
51+
currentSize.height + ResizeApp.resizeBy,
52+
);
53+
ResizeApp.resize(nextSize);
54+
},
55+
),
56+
body: Center(
57+
child: Column(
58+
mainAxisAlignment: MainAxisAlignment.center,
59+
children: <Widget>[
60+
Text(
61+
key: ResizeApp.widthLabel,
62+
'width: ${currentSize.width}'
63+
),
64+
Text(
65+
key: ResizeApp.heightLabel,
66+
'height: ${currentSize.height}',
67+
),
68+
],
69+
),
70+
),
71+
);
72+
}
73+
),
74+
);
75+
}
76+
}

dev/integration_tests/ui/macos/Runner/MainFlutterWindow.swift

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,48 @@
55
import Cocoa
66
import FlutterMacOS
77

8+
extension NSWindow {
9+
var titlebarHeight: CGFloat {
10+
frame.height - contentRect(forFrameRect: frame).height
11+
}
12+
}
13+
814
class MainFlutterWindow: NSWindow {
915
override func awakeFromNib() {
1016
let flutterViewController = FlutterViewController.init()
1117
let windowFrame = self.frame
1218
self.contentViewController = flutterViewController
1319
self.setFrame(windowFrame, display: true)
1420

21+
RegisterMethodChannel(registry: flutterViewController)
1522
RegisterGeneratedPlugins(registry: flutterViewController)
1623

1724
super.awakeFromNib()
1825
}
26+
27+
func RegisterMethodChannel(registry: FlutterPluginRegistry) {
28+
let registrar = registry.registrar(forPlugin: "resize")
29+
let channel = FlutterMethodChannel(name: "samples.flutter.dev/resize",
30+
binaryMessenger: registrar.messenger)
31+
channel.setMethodCallHandler({ (call, result) in
32+
if call.method == "resize" {
33+
if let args = call.arguments as? Dictionary<String, Any>,
34+
let width = args["width"] as? Double,
35+
var height = args["height"] as? Double {
36+
height += self.titlebarHeight
37+
let currentFrame: NSRect = self.frame
38+
let nextFrame: NSRect = NSMakeRect(
39+
currentFrame.minX - (width - currentFrame.width) / 2,
40+
currentFrame.minY - (height - currentFrame.height) / 2,
41+
width,
42+
height
43+
)
44+
self.setFrame(nextFrame, display: true, animate: false)
45+
result(true)
46+
} else {
47+
result(FlutterError.init(code: "bad args", message: nil, details: nil))
48+
}
49+
}
50+
})
51+
}
1952
}

0 commit comments

Comments
 (0)