Dan Field | 7678465 | 2020-11-05 17:28:47 -0800 | [diff] [blame] | 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 'dart:convert'; |
| 6 | |
| 7 | import 'package:flutter/material.dart'; |
Dan Field | 7678465 | 2020-11-05 17:28:47 -0800 | [diff] [blame] | 8 | import 'package:flutter_test/flutter_test.dart'; |
Phil Quitslund | 61c30c4 | 2021-04-21 13:49:03 -0700 | [diff] [blame] | 9 | import 'package:integration_test/common.dart'; |
| 10 | import 'package:integration_test/integration_test.dart'; |
Dan Field | 7678465 | 2020-11-05 17:28:47 -0800 | [diff] [blame] | 11 | import 'package:vm_service/vm_service.dart' as vm; |
| 12 | |
| 13 | vm.Timeline _kTimelines = vm.Timeline( |
| 14 | traceEvents: <vm.TimelineEvent>[], |
| 15 | timeOriginMicros: 100, |
| 16 | timeExtentMicros: 200, |
| 17 | ); |
| 18 | |
| 19 | Future<void> main() async { |
Dan Field | d309254 | 2021-02-01 10:19:14 -0800 | [diff] [blame] | 20 | Future<Map<String, dynamic>>? request; |
Dan Field | 7678465 | 2020-11-05 17:28:47 -0800 | [diff] [blame] | 21 | |
| 22 | group('Test Integration binding', () { |
Ian Hickson | ab89ce2 | 2022-02-03 14:55:15 -0800 | [diff] [blame] | 23 | final IntegrationTestWidgetsFlutterBinding binding = IntegrationTestWidgetsFlutterBinding.ensureInitialized(); |
Dan Field | 7678465 | 2020-11-05 17:28:47 -0800 | [diff] [blame] | 24 | |
Dan Field | d309254 | 2021-02-01 10:19:14 -0800 | [diff] [blame] | 25 | FakeVM? fakeVM; |
Dan Field | 7678465 | 2020-11-05 17:28:47 -0800 | [diff] [blame] | 26 | |
| 27 | setUp(() { |
Ian Hickson | ab89ce2 | 2022-02-03 14:55:15 -0800 | [diff] [blame] | 28 | request = binding.callback(<String, String>{ |
Dan Field | 7678465 | 2020-11-05 17:28:47 -0800 | [diff] [blame] | 29 | 'command': 'request_data', |
| 30 | }); |
Dan Field | 9eacc9e | 2021-01-26 18:24:03 -0800 | [diff] [blame] | 31 | fakeVM = FakeVM( |
| 32 | timeline: _kTimelines, |
Dan Field | 7678465 | 2020-11-05 17:28:47 -0800 | [diff] [blame] | 33 | ); |
| 34 | }); |
| 35 | |
| 36 | testWidgets('Run Integration app', (WidgetTester tester) async { |
| 37 | runApp(const MaterialApp( |
| 38 | home: Text('Test'), |
| 39 | )); |
Ian Hickson | ab89ce2 | 2022-02-03 14:55:15 -0800 | [diff] [blame] | 40 | expect(tester.binding, binding); |
| 41 | binding.reportData = <String, dynamic>{'answer': 42}; |
Kaushik Iska | d5f372b | 2022-09-07 12:54:06 -0400 | [diff] [blame] | 42 | await tester.pump(); |
Dan Field | 7678465 | 2020-11-05 17:28:47 -0800 | [diff] [blame] | 43 | }); |
| 44 | |
Cody Goldberg | ab6ce71 | 2021-07-30 16:47:20 -0400 | [diff] [blame] | 45 | testWidgets('hitTesting works when using setSurfaceSize', (WidgetTester tester) async { |
| 46 | int invocations = 0; |
| 47 | await tester.pumpWidget( |
| 48 | MaterialApp( |
| 49 | home: Center( |
| 50 | child: GestureDetector( |
| 51 | onTap: () { |
| 52 | invocations++; |
| 53 | }, |
| 54 | child: const Text('Test'), |
| 55 | ), |
| 56 | ), |
| 57 | ), |
| 58 | ); |
| 59 | |
| 60 | await tester.tap(find.byType(Text)); |
| 61 | await tester.pump(); |
| 62 | expect(invocations, 1); |
| 63 | |
| 64 | await tester.binding.setSurfaceSize(const Size(200, 300)); |
| 65 | await tester.pump(); |
| 66 | await tester.tap(find.byType(Text)); |
| 67 | await tester.pump(); |
| 68 | expect(invocations, 2); |
| 69 | |
| 70 | await tester.binding.setSurfaceSize(null); |
| 71 | await tester.pump(); |
| 72 | await tester.tap(find.byType(Text)); |
| 73 | await tester.pump(); |
| 74 | expect(invocations, 3); |
| 75 | }); |
| 76 | |
Dan Field | 7678465 | 2020-11-05 17:28:47 -0800 | [diff] [blame] | 77 | testWidgets('setSurfaceSize works', (WidgetTester tester) async { |
| 78 | await tester.pumpWidget(const MaterialApp(home: Center(child: Text('Test')))); |
| 79 | |
pdblasi-google | e22e8f2 | 2023-03-14 11:19:20 -0700 | [diff] [blame] | 80 | final Size viewCenter = tester.view.physicalSize / |
| 81 | tester.view.devicePixelRatio / |
Dan Field | 7678465 | 2020-11-05 17:28:47 -0800 | [diff] [blame] | 82 | 2; |
pdblasi-google | e22e8f2 | 2023-03-14 11:19:20 -0700 | [diff] [blame] | 83 | final double viewCenterX = viewCenter.width; |
| 84 | final double viewCenterY = viewCenter.height; |
Dan Field | 7678465 | 2020-11-05 17:28:47 -0800 | [diff] [blame] | 85 | |
| 86 | Offset widgetCenter = tester.getRect(find.byType(Text)).center; |
pdblasi-google | e22e8f2 | 2023-03-14 11:19:20 -0700 | [diff] [blame] | 87 | expect(widgetCenter.dx, viewCenterX); |
| 88 | expect(widgetCenter.dy, viewCenterY); |
Dan Field | 7678465 | 2020-11-05 17:28:47 -0800 | [diff] [blame] | 89 | |
| 90 | await tester.binding.setSurfaceSize(const Size(200, 300)); |
| 91 | await tester.pump(); |
| 92 | widgetCenter = tester.getRect(find.byType(Text)).center; |
| 93 | expect(widgetCenter.dx, 100); |
| 94 | expect(widgetCenter.dy, 150); |
| 95 | |
| 96 | await tester.binding.setSurfaceSize(null); |
| 97 | await tester.pump(); |
| 98 | widgetCenter = tester.getRect(find.byType(Text)).center; |
pdblasi-google | e22e8f2 | 2023-03-14 11:19:20 -0700 | [diff] [blame] | 99 | expect(widgetCenter.dx, viewCenterX); |
| 100 | expect(widgetCenter.dy, viewCenterY); |
Dan Field | 7678465 | 2020-11-05 17:28:47 -0800 | [diff] [blame] | 101 | }); |
| 102 | |
| 103 | testWidgets('Test traceAction', (WidgetTester tester) async { |
Ian Hickson | ab89ce2 | 2022-02-03 14:55:15 -0800 | [diff] [blame] | 104 | await binding.enableTimeline(vmService: fakeVM); |
| 105 | await binding.traceAction(() async {}); |
| 106 | expect(binding.reportData, isNotNull); |
| 107 | expect(binding.reportData!.containsKey('timeline'), true); |
Dan Field | 7678465 | 2020-11-05 17:28:47 -0800 | [diff] [blame] | 108 | expect( |
Ian Hickson | ab89ce2 | 2022-02-03 14:55:15 -0800 | [diff] [blame] | 109 | json.encode(binding.reportData!['timeline']), |
Dan Field | 7678465 | 2020-11-05 17:28:47 -0800 | [diff] [blame] | 110 | json.encode(_kTimelines), |
| 111 | ); |
| 112 | }); |
Jia Hao | f5933db | 2020-11-10 00:39:05 +0800 | [diff] [blame] | 113 | |
| 114 | group('defaultTestTimeout', () { |
Ian Hickson | ab89ce2 | 2022-02-03 14:55:15 -0800 | [diff] [blame] | 115 | final Timeout originalTimeout = binding.defaultTestTimeout; |
Jia Hao | f5933db | 2020-11-10 00:39:05 +0800 | [diff] [blame] | 116 | tearDown(() { |
Ian Hickson | ab89ce2 | 2022-02-03 14:55:15 -0800 | [diff] [blame] | 117 | binding.defaultTestTimeout = originalTimeout; |
Jia Hao | f5933db | 2020-11-10 00:39:05 +0800 | [diff] [blame] | 118 | }); |
| 119 | |
| 120 | test('can be configured', () { |
| 121 | const Timeout newTimeout = Timeout(Duration(seconds: 17)); |
Ian Hickson | ab89ce2 | 2022-02-03 14:55:15 -0800 | [diff] [blame] | 122 | binding.defaultTestTimeout = newTimeout; |
| 123 | expect(binding.defaultTestTimeout, newTimeout); |
Jia Hao | f5933db | 2020-11-10 00:39:05 +0800 | [diff] [blame] | 124 | }); |
| 125 | }); |
Jia Hao | c2bfb7b | 2020-12-10 08:33:04 +0800 | [diff] [blame] | 126 | |
Dan Field | c5861cf | 2021-08-25 10:09:03 -0700 | [diff] [blame] | 127 | // TODO(jiahaog): Remove when https://github.com/flutter/flutter/issues/66006 is fixed. |
| 128 | testWidgets('root widgets are wrapped with a RepaintBoundary', (WidgetTester tester) async { |
Jia Hao | c2bfb7b | 2020-12-10 08:33:04 +0800 | [diff] [blame] | 129 | await tester.pumpWidget(const Placeholder()); |
| 130 | |
Dan Field | c5861cf | 2021-08-25 10:09:03 -0700 | [diff] [blame] | 131 | expect(find.byType(RepaintBoundary), findsOneWidget); |
Jia Hao | c2bfb7b | 2020-12-10 08:33:04 +0800 | [diff] [blame] | 132 | }); |
Dan Field | 7678465 | 2020-11-05 17:28:47 -0800 | [diff] [blame] | 133 | }); |
| 134 | |
| 135 | tearDownAll(() async { |
Anis Alibegić | c99ed37 | 2021-06-02 19:14:06 +0200 | [diff] [blame] | 136 | // This part is outside the group so that `request` has been completed as |
Chris Bracken | 3e7e065 | 2021-04-01 10:04:03 -0700 | [diff] [blame] | 137 | // part of the `tearDownAll` registered in the group during |
Dan Field | 7678465 | 2020-11-05 17:28:47 -0800 | [diff] [blame] | 138 | // `IntegrationTestWidgetsFlutterBinding` initialization. |
| 139 | final Map<String, dynamic> response = |
Dan Field | d309254 | 2021-02-01 10:19:14 -0800 | [diff] [blame] | 140 | (await request)!['response'] as Map<String, dynamic>; |
Dan Field | 7678465 | 2020-11-05 17:28:47 -0800 | [diff] [blame] | 141 | final String message = response['message'] as String; |
| 142 | final Response result = Response.fromJson(message); |
Dan Field | d309254 | 2021-02-01 10:19:14 -0800 | [diff] [blame] | 143 | assert(result.data!['answer'] == 42); |
Dan Field | 7678465 | 2020-11-05 17:28:47 -0800 | [diff] [blame] | 144 | }); |
| 145 | } |
| 146 | |
Dan Field | 9eacc9e | 2021-01-26 18:24:03 -0800 | [diff] [blame] | 147 | class FakeVM extends Fake implements vm.VmService { |
Dan Field | d309254 | 2021-02-01 10:19:14 -0800 | [diff] [blame] | 148 | FakeVM({required this.timeline}); |
Dan Field | 9eacc9e | 2021-01-26 18:24:03 -0800 | [diff] [blame] | 149 | |
| 150 | vm.Timeline timeline; |
| 151 | |
| 152 | @override |
Dan Field | d309254 | 2021-02-01 10:19:14 -0800 | [diff] [blame] | 153 | Future<vm.Timeline> getVMTimeline({int? timeOriginMicros, int? timeExtentMicros}) async { |
Dan Field | 9eacc9e | 2021-01-26 18:24:03 -0800 | [diff] [blame] | 154 | return timeline; |
| 155 | } |
| 156 | |
| 157 | int lastTimeStamp = 0; |
| 158 | @override |
| 159 | Future<vm.Timestamp> getVMTimelineMicros() async { |
| 160 | lastTimeStamp += 100; |
| 161 | return vm.Timestamp(timestamp: lastTimeStamp); |
| 162 | } |
| 163 | |
Dan Field | 9eacc9e | 2021-01-26 18:24:03 -0800 | [diff] [blame] | 164 | @override |
| 165 | Future<vm.Success> setVMTimelineFlags(List<String> recordedStreams) async { |
Dan Field | 9eacc9e | 2021-01-26 18:24:03 -0800 | [diff] [blame] | 166 | return vm.Success(); |
| 167 | } |
| 168 | |
| 169 | @override |
| 170 | Future<vm.Success> clearVMTimeline() async { |
| 171 | return vm.Success(); |
| 172 | } |
| 173 | } |