diff --git a/dev/benchmarks/test_apps/stocks/test/icon_color_test.dart b/dev/benchmarks/test_apps/stocks/test/icon_color_test.dart index 3a8b8f71ab..6d52faeeca 100644 --- a/dev/benchmarks/test_apps/stocks/test/icon_color_test.dart +++ b/dev/benchmarks/test_apps/stocks/test/icon_color_test.dart @@ -58,8 +58,8 @@ void main() { expect(find.text('Account Balance'), findsNothing); // drag the drawer out - final Offset left = Offset(0.0, (WidgetsBinding.instance.window.physicalSize / WidgetsBinding.instance.window.devicePixelRatio).height / 2.0); - final Offset right = Offset((WidgetsBinding.instance.window.physicalSize / WidgetsBinding.instance.window.devicePixelRatio).width, left.dy); + final Offset left = Offset(0.0, (tester.view.physicalSize / tester.view.devicePixelRatio).height / 2.0); + final Offset right = Offset((tester.view.physicalSize / tester.view.devicePixelRatio).width, left.dy); final TestGesture gesture = await tester.startGesture(left); await tester.pump(); await gesture.moveTo(right); diff --git a/packages/flutter/test/cupertino/route_test.dart b/packages/flutter/test/cupertino/route_test.dart index 01e997c7fa..0c2dc3108e 100644 --- a/packages/flutter/test/cupertino/route_test.dart +++ b/packages/flutter/test/cupertino/route_test.dart @@ -1702,6 +1702,7 @@ void main() { ]; await tester.pumpWidget( buildNavigator( + view: tester.view, pages: myPages, onPopPage: (Route route, dynamic result) { assert(false); // The test shouldn't call this. @@ -1728,6 +1729,7 @@ void main() { await tester.pumpWidget( buildNavigator( + view: tester.view, pages: myPages, onPopPage: (Route route, dynamic result) { assert(false); // The test shouldn't call this. @@ -1756,6 +1758,7 @@ void main() { ]; await tester.pumpWidget( buildNavigator( + view: tester.view, pages: myPages, onPopPage: (Route route, dynamic result) { assert(false); // The test shouldn't call this. @@ -1777,6 +1780,7 @@ void main() { await tester.pumpWidget( buildNavigator( + view: tester.view, pages: myPages, onPopPage: (Route route, dynamic result) { assert(false); // The test shouldn't call this. @@ -2213,12 +2217,13 @@ class TransitionDetector extends DefaultTransitionDelegate { Widget buildNavigator({ required List> pages, + required FlutterView view, PopPageCallback? onPopPage, GlobalKey? key, TransitionDelegate? transitionDelegate, }) { return MediaQuery( - data: MediaQueryData.fromView(WidgetsBinding.instance.window), + data: MediaQueryData.fromView(view), child: Localizations( locale: const Locale('en', 'US'), delegates: const >[ diff --git a/packages/flutter/test/gestures/gesture_binding_resample_event_on_widget_test.dart b/packages/flutter/test/gestures/gesture_binding_resample_event_on_widget_test.dart index 8c007f2eaa..c31c59f9c2 100644 --- a/packages/flutter/test/gestures/gesture_binding_resample_event_on_widget_test.dart +++ b/packages/flutter/test/gestures/gesture_binding_resample_event_on_widget_test.dart @@ -101,7 +101,7 @@ void main() { expect(events.length, 1); expect(events[0], isA()); expect(events[0].timeStamp, currentTestFrameTime() + kSamplingOffset); - expect(events[0].position, Offset(7.5 / GestureBinding.instance.window.devicePixelRatio, 0.0)); + expect(events[0].position, Offset(7.5 / tester.view.devicePixelRatio, 0.0)); // Now the system time is epoch + 20ms requestFrame(); @@ -109,8 +109,8 @@ void main() { expect(events.length, 2); expect(events[1].timeStamp, currentTestFrameTime() + kSamplingOffset); expect(events[1], isA()); - expect(events[1].position, Offset(22.5 / GestureBinding.instance.window.devicePixelRatio, 0.0)); - expect(events[1].delta, Offset(15.0 / GestureBinding.instance.window.devicePixelRatio, 0.0)); + expect(events[1].position, Offset(22.5 / tester.view.devicePixelRatio, 0.0)); + expect(events[1].delta, Offset(15.0 / tester.view.devicePixelRatio, 0.0)); // Now the system time is epoch + 30ms requestFrame(); @@ -118,8 +118,8 @@ void main() { expect(events.length, 4); expect(events[2].timeStamp, currentTestFrameTime() + kSamplingOffset); expect(events[2], isA()); - expect(events[2].position, Offset(37.5 / GestureBinding.instance.window.devicePixelRatio, 0.0)); - expect(events[2].delta, Offset(15.0 / GestureBinding.instance.window.devicePixelRatio, 0.0)); + expect(events[2].position, Offset(37.5 / tester.view.devicePixelRatio, 0.0)); + expect(events[2].delta, Offset(15.0 / tester.view.devicePixelRatio, 0.0)); expect(events[3].timeStamp, currentTestFrameTime() + kSamplingOffset); expect(events[3], isA()); }); diff --git a/packages/flutter/test/gestures/gesture_binding_test.dart b/packages/flutter/test/gestures/gesture_binding_test.dart index 328dd4bbd7..76e3b1d7f6 100644 --- a/packages/flutter/test/gestures/gesture_binding_test.dart +++ b/packages/flutter/test/gestures/gesture_binding_test.dart @@ -162,6 +162,8 @@ void main() { expect(events[1], isA()); }); + const double devicePixelRatio = 2.5; + test('Can expand add and hover pointers', () { const ui.PointerDataPacket packet = ui.PointerDataPacket( data: [ @@ -173,7 +175,7 @@ void main() { ], ); - final List events = PointerEventConverter.expand(packet.data, GestureBinding.instance.window.devicePixelRatio).toList(); + final List events = PointerEventConverter.expand(packet.data, devicePixelRatio).toList(); expect(events.length, 5); expect(events[0], isA()); @@ -189,7 +191,7 @@ void main() { ui.PointerData(change: ui.PointerChange.add, device: 24), ], ); - List events = PointerEventConverter.expand(packet.data, GestureBinding.instance.window.devicePixelRatio).toList(); + List events = PointerEventConverter.expand(packet.data, devicePixelRatio).toList(); expect(events.length, 1); expect(events[0], isA()); @@ -205,7 +207,7 @@ void main() { ui.PointerData(signalKind: ui.PointerSignalKind.scroll, device: 24, scrollDeltaY: double.negativeInfinity, scrollDeltaX: 10), ], ); - events = PointerEventConverter.expand(packet.data, GestureBinding.instance.window.devicePixelRatio).toList(); + events = PointerEventConverter.expand(packet.data, devicePixelRatio).toList(); expect(events.length, 0); // Send packet with a valid scroll event. @@ -215,7 +217,7 @@ void main() { ], ); // Make sure PointerEventConverter can expand when device pixel ratio is valid. - events = PointerEventConverter.expand(packet.data, GestureBinding.instance.window.devicePixelRatio).toList(); + events = PointerEventConverter.expand(packet.data, devicePixelRatio).toList(); expect(events.length, 1); expect(events[0], isA()); @@ -232,7 +234,7 @@ void main() { ], ); - final List events = PointerEventConverter.expand(packet.data, GestureBinding.instance.window.devicePixelRatio).toList(); + final List events = PointerEventConverter.expand(packet.data, devicePixelRatio).toList(); expect(events.length, 2); expect(events[0], isA()); @@ -240,7 +242,7 @@ void main() { }); test('Should synthesize kPrimaryButton for touch when no button is set', () { - final Offset location = const Offset(10.0, 10.0) * GestureBinding.instance.window.devicePixelRatio; + final Offset location = const Offset(10.0, 10.0) * devicePixelRatio; final ui.PointerDataPacket packet = ui.PointerDataPacket( data: [ ui.PointerData(change: ui.PointerChange.add, physicalX: location.dx, physicalY: location.dy), @@ -251,7 +253,7 @@ void main() { ], ); - final List events = PointerEventConverter.expand(packet.data, GestureBinding.instance.window.devicePixelRatio).toList(); + final List events = PointerEventConverter.expand(packet.data, devicePixelRatio).toList(); expect(events.length, 5); expect(events[0], isA()); @@ -267,7 +269,7 @@ void main() { }); test('Should not synthesize kPrimaryButton for touch when a button is set', () { - final Offset location = const Offset(10.0, 10.0) * GestureBinding.instance.window.devicePixelRatio; + final Offset location = const Offset(10.0, 10.0) * devicePixelRatio; final ui.PointerDataPacket packet = ui.PointerDataPacket( data: [ ui.PointerData(change: ui.PointerChange.add, physicalX: location.dx, physicalY: location.dy), @@ -278,7 +280,7 @@ void main() { ], ); - final List events = PointerEventConverter.expand(packet.data, GestureBinding.instance.window.devicePixelRatio).toList(); + final List events = PointerEventConverter.expand(packet.data, devicePixelRatio).toList(); expect(events.length, 5); expect(events[0], isA()); @@ -294,7 +296,7 @@ void main() { }); test('Should synthesize kPrimaryButton for stylus when no button is set', () { - final Offset location = const Offset(10.0, 10.0) * GestureBinding.instance.window.devicePixelRatio; + final Offset location = const Offset(10.0, 10.0) * devicePixelRatio; for (final PointerDeviceKind kind in [ PointerDeviceKind.stylus, PointerDeviceKind.invertedStylus, @@ -310,7 +312,7 @@ void main() { ], ); - final List events = PointerEventConverter.expand(packet.data, GestureBinding.instance.window.devicePixelRatio).toList(); + final List events = PointerEventConverter.expand(packet.data, devicePixelRatio).toList(); expect(events.length, 5); expect(events[0], isA()); @@ -327,7 +329,7 @@ void main() { }); test('Should synthesize kPrimaryButton for unknown devices when no button is set', () { - final Offset location = const Offset(10.0, 10.0) * GestureBinding.instance.window.devicePixelRatio; + final Offset location = const Offset(10.0, 10.0) * devicePixelRatio; const PointerDeviceKind kind = PointerDeviceKind.unknown; final ui.PointerDataPacket packet = ui.PointerDataPacket( data: [ @@ -339,7 +341,7 @@ void main() { ], ); - final List events = PointerEventConverter.expand(packet.data, GestureBinding.instance.window.devicePixelRatio).toList(); + final List events = PointerEventConverter.expand(packet.data, devicePixelRatio).toList(); expect(events.length, 5); expect(events[0], isA()); @@ -355,7 +357,7 @@ void main() { }); test('Should not synthesize kPrimaryButton for mouse', () { - final Offset location = const Offset(10.0, 10.0) * GestureBinding.instance.window.devicePixelRatio; + final Offset location = const Offset(10.0, 10.0) * devicePixelRatio; for (final PointerDeviceKind kind in [ PointerDeviceKind.mouse, ]) { @@ -369,7 +371,7 @@ void main() { ], ); - final List events = PointerEventConverter.expand(packet.data, GestureBinding.instance.window.devicePixelRatio).toList(); + final List events = PointerEventConverter.expand(packet.data, devicePixelRatio).toList(); expect(events.length, 5); expect(events[0], isA()); diff --git a/packages/flutter/test/material/page_test.dart b/packages/flutter/test/material/page_test.dart index 16d002108e..f55e07b7ff 100644 --- a/packages/flutter/test/material/page_test.dart +++ b/packages/flutter/test/material/page_test.dart @@ -1042,6 +1042,7 @@ void main() { ]; await tester.pumpWidget( buildNavigator( + view: tester.view, pages: myPages, onPopPage: (Route route, dynamic result) { assert(false); // The test should never execute this. @@ -1060,6 +1061,7 @@ void main() { await tester.pumpWidget( buildNavigator( + view: tester.view, pages: myPages, onPopPage: (Route route, dynamic result) { assert(false); // The test should never execute this. @@ -1085,6 +1087,7 @@ void main() { ]; await tester.pumpWidget( buildNavigator( + view: tester.view, pages: myPages, onPopPage: (Route route, dynamic result) { assert(false); // The test should never execute this. @@ -1106,6 +1109,7 @@ void main() { await tester.pumpWidget( buildNavigator( + view: tester.view, pages: myPages, onPopPage: (Route route, dynamic result) { assert(false); // The test should never execute this. @@ -1214,11 +1218,12 @@ class TransitionDetector extends DefaultTransitionDelegate { Widget buildNavigator({ required List> pages, required PopPageCallback onPopPage, + required ui.FlutterView view, GlobalKey? key, TransitionDelegate? transitionDelegate, }) { return MediaQuery( - data: MediaQueryData.fromView(WidgetsBinding.instance.window), + data: MediaQueryData.fromView(view), child: Localizations( locale: const Locale('en', 'US'), delegates: const >[ diff --git a/packages/flutter/test/painting/paint_image_test.dart b/packages/flutter/test/painting/paint_image_test.dart index f4787d8eb6..bc83e465c4 100644 --- a/packages/flutter/test/painting/paint_image_test.dart +++ b/packages/flutter/test/painting/paint_image_test.dart @@ -52,7 +52,7 @@ void main() { test('debugInvertOversizedImages', () async { debugInvertOversizedImages = true; - expect(PaintingBinding.instance.window.devicePixelRatio != 1.0, true); + expect(PaintingBinding.instance.platformDispatcher.views.any((ui. FlutterView view) => view.devicePixelRatio > 1.0), isTrue); final FlutterExceptionHandler? oldFlutterError = FlutterError.onError; final List messages = []; @@ -180,7 +180,7 @@ void main() { expect(imageSizeInfo, isNotNull); expect(imageSizeInfo.source, 'test.png'); expect(imageSizeInfo.imageSize, const Size(300, 300)); - expect(imageSizeInfo.displaySize, const Size(200, 100) * PaintingBinding.instance.window.devicePixelRatio); + expect(imageSizeInfo.displaySize, const Size(200, 100) * tester.view.devicePixelRatio); // Make sure that we don't report an identical image size info if we // redraw in the next frame. @@ -219,7 +219,7 @@ void main() { expect(imageSizeInfo, isNotNull); expect(imageSizeInfo.source, 'test.png'); expect(imageSizeInfo.imageSize, const Size(300, 300)); - expect(imageSizeInfo.displaySize, const Size(200, 100) * PaintingBinding.instance.window.devicePixelRatio); + expect(imageSizeInfo.displaySize, const Size(200, 100) * tester.view.devicePixelRatio); // Make sure that we don't report an identical image size info if we // redraw in the next frame. @@ -237,7 +237,7 @@ void main() { expect(imageSizeInfo, isNotNull); expect(imageSizeInfo.source, 'test.png'); expect(imageSizeInfo.imageSize, const Size(300, 300)); - expect(imageSizeInfo.displaySize, const Size(200, 150) * PaintingBinding.instance.window.devicePixelRatio); + expect(imageSizeInfo.displaySize, const Size(200, 150) * tester.view.devicePixelRatio); debugOnPaintImage = null; }); @@ -261,7 +261,7 @@ void main() { expect(imageSizeInfo, isNotNull); expect(imageSizeInfo.source, ''); expect(imageSizeInfo.imageSize, const Size(300, 200)); - expect(imageSizeInfo.displaySize, const Size(200, 100) * PaintingBinding.instance.window.devicePixelRatio); + expect(imageSizeInfo.displaySize, const Size(200, 100) * tester.view.devicePixelRatio); debugOnPaintImage = null; }); diff --git a/packages/flutter/test/rendering/independent_layout_test.dart b/packages/flutter/test/rendering/independent_layout_test.dart index a9ec271ec4..64cb9465b5 100644 --- a/packages/flutter/test/rendering/independent_layout_test.dart +++ b/packages/flutter/test/rendering/independent_layout_test.dart @@ -44,7 +44,7 @@ void main() { expect(offscreen.child.hasSize, isFalse); expect(offscreen.painted, isFalse); // Attach the offscreen to a custom render view and owner - final RenderView renderView = RenderView(configuration: testConfiguration, window: RendererBinding.instance.window); + final RenderView renderView = RenderView(configuration: testConfiguration, window: RendererBinding.instance.platformDispatcher.views.single); final PipelineOwner pipelineOwner = PipelineOwner(); renderView.attach(pipelineOwner); renderView.child = offscreen.root; @@ -66,6 +66,7 @@ void main() { pipelineOwner.flushPaint(); expect(offscreen.painted, isTrue); }); + test('offscreen layout does not affect onscreen', () { final TestLayout onscreen = TestLayout(); final TestLayout offscreen = TestLayout(); @@ -74,7 +75,7 @@ void main() { expect(offscreen.child.hasSize, isFalse); expect(offscreen.painted, isFalse); // Attach the offscreen to a custom render view and owner - final RenderView renderView = RenderView(configuration: testConfiguration, window: RendererBinding.instance.window); + final RenderView renderView = RenderView(configuration: testConfiguration, window: RendererBinding.instance.platformDispatcher.views.single); final PipelineOwner pipelineOwner = PipelineOwner(); renderView.attach(pipelineOwner); renderView.child = offscreen.root; diff --git a/packages/flutter/test/rendering/layers_test.dart b/packages/flutter/test/rendering/layers_test.dart index f8c4bf58e1..ef89f0e0e4 100644 --- a/packages/flutter/test/rendering/layers_test.dart +++ b/packages/flutter/test/rendering/layers_test.dart @@ -169,7 +169,7 @@ void main() { test('switching layer link of an attached leader layer should not crash', () { final LayerLink link = LayerLink(); final LeaderLayer leaderLayer = LeaderLayer(link: link); - final RenderView view = RenderView(configuration: const ViewConfiguration(), window: RendererBinding.instance.window); + final RenderView view = RenderView(configuration: const ViewConfiguration(), window: RendererBinding.instance.platformDispatcher.views.single); leaderLayer.attach(view); final LayerLink link2 = LayerLink(); leaderLayer.link = link2; @@ -182,7 +182,7 @@ void main() { final LayerLink link = LayerLink(); final LeaderLayer leaderLayer1 = LeaderLayer(link: link); final LeaderLayer leaderLayer2 = LeaderLayer(link: link); - final RenderView view = RenderView(configuration: const ViewConfiguration(), window: RendererBinding.instance.window); + final RenderView view = RenderView(configuration: const ViewConfiguration(), window: RendererBinding.instance.platformDispatcher.views.single); leaderLayer1.attach(view); leaderLayer2.attach(view); leaderLayer2.detach(); diff --git a/packages/flutter/test/rendering/view_test.dart b/packages/flutter/test/rendering/view_test.dart index 52e3de57f5..01853ffbae 100644 --- a/packages/flutter/test/rendering/view_test.dart +++ b/packages/flutter/test/rendering/view_test.dart @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'dart:ui' as ui; - import 'package:flutter/rendering.dart'; import 'package:flutter_test/flutter_test.dart'; @@ -32,10 +30,9 @@ void main() { }); test('does not replace the root layer unnecessarily', () { - final ui.FlutterView window = TestWindow(window: RendererBinding.instance.window); final RenderView view = RenderView( configuration: createViewConfiguration(), - window: window, + window: RendererBinding.instance.platformDispatcher.views.single, ); final PipelineOwner owner = PipelineOwner(); view.attach(owner); @@ -49,10 +46,9 @@ void main() { }); test('does not replace the root layer unnecessarily when window resize', () { - final ui.FlutterView window = TestWindow(window: RendererBinding.instance.window); final RenderView view = RenderView( configuration: createViewConfiguration(size: const Size(100.0, 100.0)), - window: window, + window: RendererBinding.instance.platformDispatcher.views.single, ); final PipelineOwner owner = PipelineOwner(); view.attach(owner); diff --git a/packages/flutter/test/widgets/annotated_region_test.dart b/packages/flutter/test/widgets/annotated_region_test.dart index e91a39dd50..ec159c90a1 100644 --- a/packages/flutter/test/widgets/annotated_region_test.dart +++ b/packages/flutter/test/widgets/annotated_region_test.dart @@ -29,13 +29,13 @@ void main() { ), ); int? result = RendererBinding.instance.renderView.debugLayer!.find(Offset( - 10.0 * RendererBinding.instance.window.devicePixelRatio, - 10.0 * RendererBinding.instance.window.devicePixelRatio, + 10.0 * tester.view.devicePixelRatio, + 10.0 * tester.view.devicePixelRatio, )); expect(result, null); result = RendererBinding.instance.renderView.debugLayer!.find(Offset( - 50.0 * RendererBinding.instance.window.devicePixelRatio, - 50.0 * RendererBinding.instance.window.devicePixelRatio, + 50.0 * tester.view.devicePixelRatio, + 50.0 * tester.view.devicePixelRatio, )); expect(result, 1); }); diff --git a/packages/flutter/test/widgets/display_feature_sub_screen_test.dart b/packages/flutter/test/widgets/display_feature_sub_screen_test.dart index f7045132a9..926a459a81 100644 --- a/packages/flutter/test/widgets/display_feature_sub_screen_test.dart +++ b/packages/flutter/test/widgets/display_feature_sub_screen_test.dart @@ -11,7 +11,7 @@ void main() { group('DisplayFeatureSubScreen', () { testWidgets('without Directionality or anchor', (WidgetTester tester) async { const Key childKey = Key('childKey'); - final MediaQueryData mediaQuery = MediaQueryData.fromView(WidgetsBinding.instance.window).copyWith( + final MediaQueryData mediaQuery = MediaQueryData.fromView(tester.view).copyWith( displayFeatures: [ const DisplayFeature( bounds: Rect.fromLTRB(390, 0, 410, 600), @@ -39,7 +39,7 @@ void main() { testWidgets('with anchorPoint', (WidgetTester tester) async { const Key childKey = Key('childKey'); - final MediaQueryData mediaQuery = MediaQueryData.fromView(WidgetsBinding.instance.window).copyWith( + final MediaQueryData mediaQuery = MediaQueryData.fromView(tester.view).copyWith( displayFeatures: [ const DisplayFeature( bounds: Rect.fromLTRB(390, 0, 410, 600), @@ -70,7 +70,7 @@ void main() { testWidgets('with infinity anchorpoint', (WidgetTester tester) async { const Key childKey = Key('childKey'); - final MediaQueryData mediaQuery = MediaQueryData.fromView(WidgetsBinding.instance.window).copyWith( + final MediaQueryData mediaQuery = MediaQueryData.fromView(tester.view).copyWith( displayFeatures: [ const DisplayFeature( bounds: Rect.fromLTRB(390, 0, 410, 600), @@ -101,7 +101,7 @@ void main() { testWidgets('with horizontal hinge and anchorPoint', (WidgetTester tester) async { const Key childKey = Key('childKey'); - final MediaQueryData mediaQuery = MediaQueryData.fromView(WidgetsBinding.instance.window).copyWith( + final MediaQueryData mediaQuery = MediaQueryData.fromView(tester.view).copyWith( displayFeatures: [ const DisplayFeature( bounds: Rect.fromLTRB(0, 290, 800, 310), @@ -131,7 +131,7 @@ void main() { testWidgets('with multiple display features and anchorPoint', (WidgetTester tester) async { const Key childKey = Key('childKey'); - final MediaQueryData mediaQuery = MediaQueryData.fromView(WidgetsBinding.instance.window).copyWith( + final MediaQueryData mediaQuery = MediaQueryData.fromView(tester.view).copyWith( displayFeatures: [ const DisplayFeature( bounds: Rect.fromLTRB(0, 290, 800, 310), @@ -166,7 +166,7 @@ void main() { testWidgets('with non-splitting display features and anchorPoint', (WidgetTester tester) async { const Key childKey = Key('childKey'); - final MediaQueryData mediaQuery = MediaQueryData.fromView(WidgetsBinding.instance.window).copyWith( + final MediaQueryData mediaQuery = MediaQueryData.fromView(tester.view).copyWith( displayFeatures: [ // Top notch const DisplayFeature( @@ -211,7 +211,7 @@ void main() { testWidgets('with size 0 display feature in half-opened posture and anchorPoint', (WidgetTester tester) async { const Key childKey = Key('childKey'); - final MediaQueryData mediaQuery = MediaQueryData.fromView(WidgetsBinding.instance.window).copyWith( + final MediaQueryData mediaQuery = MediaQueryData.fromView(tester.view).copyWith( displayFeatures: [ const DisplayFeature( bounds: Rect.fromLTRB(0, 300, 800, 300), diff --git a/packages/flutter/test/widgets/independent_widget_layout_test.dart b/packages/flutter/test/widgets/independent_widget_layout_test.dart index 90d8881b48..558e7fd481 100644 --- a/packages/flutter/test/widgets/independent_widget_layout_test.dart +++ b/packages/flutter/test/widgets/independent_widget_layout_test.dart @@ -2,14 +2,16 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import 'dart:ui' show FlutterView; + import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter_test/flutter_test.dart'; const Size _kTestViewSize = Size(800.0, 600.0); -class ScheduledFrameTrackingWindow extends TestWindow { - ScheduledFrameTrackingWindow({ required super.window }); +class ScheduledFrameTrackingPlatformDispatcher extends TestPlatformDispatcher { + ScheduledFrameTrackingPlatformDispatcher({ required super.platformDispatcher }); int _scheduledFrameCount = 0; int get scheduledFrameCount => _scheduledFrameCount; @@ -26,16 +28,16 @@ class ScheduledFrameTrackingWindow extends TestWindow { } class ScheduledFrameTrackingBindings extends AutomatedTestWidgetsFlutterBinding { - late final ScheduledFrameTrackingWindow _window = ScheduledFrameTrackingWindow(window: super.window); + late final ScheduledFrameTrackingPlatformDispatcher _platformDispatcher = ScheduledFrameTrackingPlatformDispatcher(platformDispatcher: super.platformDispatcher); @override - ScheduledFrameTrackingWindow get window => _window; + ScheduledFrameTrackingPlatformDispatcher get platformDispatcher => _platformDispatcher; } class OffscreenRenderView extends RenderView { - OffscreenRenderView() : super( + OffscreenRenderView({required FlutterView view}) : super( configuration: const ViewConfiguration(size: _kTestViewSize), - window: WidgetsBinding.instance.window, + window: view, ); @override @@ -45,13 +47,14 @@ class OffscreenRenderView extends RenderView { } class OffscreenWidgetTree { - OffscreenWidgetTree() { + OffscreenWidgetTree(this.view) { renderView.attach(pipelineOwner); renderView.prepareInitialFrame(); pipelineOwner.requestVisualUpdate(); } - final RenderView renderView = OffscreenRenderView(); + final FlutterView view; + late final RenderView renderView = OffscreenRenderView(view: view); final BuildOwner buildOwner = BuildOwner(focusManager: FocusManager()); final PipelineOwner pipelineOwner = PipelineOwner(); RenderObjectToWidgetElement? root; @@ -168,12 +171,12 @@ void main() { testWidgets('RenderObjectToWidgetAdapter.attachToRenderTree does not schedule frame', (WidgetTester tester) async { expect(WidgetsBinding.instance, isA()); - final ScheduledFrameTrackingWindow window = WidgetsBinding.instance.window as ScheduledFrameTrackingWindow; - window.resetScheduledFrameCount(); - expect(window.scheduledFrameCount, isZero); - final OffscreenWidgetTree tree = OffscreenWidgetTree(); + final ScheduledFrameTrackingPlatformDispatcher platformDispatcher = tester.platformDispatcher as ScheduledFrameTrackingPlatformDispatcher; + platformDispatcher.resetScheduledFrameCount(); + expect(platformDispatcher.scheduledFrameCount, isZero); + final OffscreenWidgetTree tree = OffscreenWidgetTree(tester.view); tree.pumpWidget(const SizedBox.shrink()); - expect(window.scheduledFrameCount, isZero); + expect(platformDispatcher.scheduledFrameCount, isZero); }); testWidgets('no crosstalk between widget build owners', (WidgetTester tester) async { @@ -181,7 +184,7 @@ void main() { final Counter counter1 = Counter(); final Trigger trigger2 = Trigger(); final Counter counter2 = Counter(); - final OffscreenWidgetTree tree = OffscreenWidgetTree(); + final OffscreenWidgetTree tree = OffscreenWidgetTree(tester.view); // Both counts should start at zero expect(counter1.count, equals(0)); expect(counter2.count, equals(0)); @@ -227,7 +230,7 @@ void main() { }); testWidgets('no crosstalk between focus nodes', (WidgetTester tester) async { - final OffscreenWidgetTree tree = OffscreenWidgetTree(); + final OffscreenWidgetTree tree = OffscreenWidgetTree(tester.view); final FocusNode onscreenFocus = FocusNode(); final FocusNode offscreenFocus = FocusNode(); await tester.pumpWidget( @@ -250,7 +253,7 @@ void main() { }); testWidgets('able to tear down offscreen tree', (WidgetTester tester) async { - final OffscreenWidgetTree tree = OffscreenWidgetTree(); + final OffscreenWidgetTree tree = OffscreenWidgetTree(tester.view); final List states = []; tree.pumpWidget(SizedBox(child: TestStates(states: states))); expect(states, [WidgetState.initialized]); diff --git a/packages/flutter/test/widgets/navigator_test.dart b/packages/flutter/test/widgets/navigator_test.dart index f982d60581..857a549efd 100644 --- a/packages/flutter/test/widgets/navigator_test.dart +++ b/packages/flutter/test/widgets/navigator_test.dart @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import 'dart:ui' show FlutterView; + import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/scheduler.dart'; @@ -2677,6 +2679,7 @@ void main() { group('Page api', () { Widget buildNavigator({ + required FlutterView view, required List> pages, required PopPageCallback onPopPage, GlobalKey? key, @@ -2684,7 +2687,7 @@ void main() { List observers = const [], }) { return MediaQuery( - data: MediaQueryData.fromView(WidgetsBinding.instance.window), + data: MediaQueryData.fromView(view), child: Localizations( locale: const Locale('en', 'US'), delegates: const >[ @@ -2718,7 +2721,12 @@ void main() { } await tester.pumpWidget( - buildNavigator(pages: myPages, onPopPage: onPopPage, key: navigator), + buildNavigator( + view: tester.view, + pages: myPages, + onPopPage: onPopPage, + key: navigator, + ), ); expect(find.text('third'), findsOneWidget); expect(find.text('second'), findsNothing); @@ -2750,22 +2758,42 @@ void main() { bool onPopPage(Route route, dynamic result) => false; await tester.pumpWidget( - buildNavigator(pages: myPages1, onPopPage: onPopPage, key: navigator), + buildNavigator( + view: tester.view, + pages: myPages1, + onPopPage: onPopPage, + key: navigator, + ), ); await tester.pump(); expect(find.text('initial'), findsOneWidget); // Update multiple times without waiting for pop to finish to leave // multiple popping route entries in route stack with the same page key. await tester.pumpWidget( - buildNavigator(pages: myPages2, onPopPage: onPopPage, key: navigator), + buildNavigator( + view: tester.view, + pages: myPages2, + onPopPage: onPopPage, + key: navigator, + ), ); await tester.pump(); await tester.pumpWidget( - buildNavigator(pages: myPages1, onPopPage: onPopPage, key: navigator), + buildNavigator( + view: tester.view, + pages: myPages1, + onPopPage: onPopPage, + key: navigator, + ), ); await tester.pump(); await tester.pumpWidget( - buildNavigator(pages: myPages2, onPopPage: onPopPage, key: navigator), + buildNavigator( + view: tester.view, + pages: myPages2, + onPopPage: onPopPage, + key: navigator, + ), ); await tester.pumpAndSettle(); @@ -2869,7 +2897,12 @@ void main() { } await tester.pumpWidget( - buildNavigator(pages: myPages, onPopPage: onPopPage, key: navigator), + buildNavigator( + view: tester.view, + pages: myPages, + onPopPage: onPopPage, + key: navigator, + ), ); expect(find.text('initial'), findsOneWidget); @@ -2904,7 +2937,12 @@ void main() { ]; await tester.pumpWidget( - buildNavigator(pages: myPages, onPopPage: onPopPage, key: navigator), + buildNavigator( + view: tester.view, + pages: myPages, + onPopPage: onPopPage, + key: navigator, + ), ); // The third page is transitioning, and the secondary animation of first // page should chain with the third page. The animation of second page @@ -2959,7 +2997,12 @@ void main() { ]; await tester.pumpWidget( - buildNavigator(pages: myPages, onPopPage: onPopPage, key: navigator), + buildNavigator( + view: tester.view, + pages: myPages, + onPopPage: onPopPage, + key: navigator, + ), ); await tester.pump(const Duration(milliseconds: 30)); expect(secondaryAnimationOfRouteOne.value, primaryAnimationOfRouteTwo.value); @@ -3019,7 +3062,12 @@ void main() { return route.didPop(result); } await tester.pumpWidget( - buildNavigator(pages: myPages, onPopPage: onPopPage, key: navigator), + buildNavigator( + view: tester.view, + pages: myPages, + onPopPage: onPopPage, + key: navigator, + ), ); expect(find.text('third'), findsOneWidget); expect(find.text('second'), findsNothing); @@ -3033,7 +3081,12 @@ void main() { myPages = myPages.reversed.toList(); await tester.pumpWidget( - buildNavigator(pages: myPages, onPopPage: onPopPage, key: navigator), + buildNavigator( + view: tester.view, + pages: myPages, + onPopPage: onPopPage, + key: navigator, + ), ); // Reversed routes are still chained up correctly. expect(secondaryAnimationOfRouteThree.value, primaryAnimationOfRouteTwo.value); @@ -3116,7 +3169,12 @@ void main() { } await tester.pumpWidget( - buildNavigator(pages: myPages, onPopPage: onPopPage, key: navigator), + buildNavigator( + view: tester.view, + pages: myPages, + onPopPage: onPopPage, + key: navigator, + ), ); expect(find.text('second'), findsOneWidget); expect(find.text('initial'), findsNothing); @@ -3145,7 +3203,12 @@ void main() { const TestPage(key: ValueKey('3'), name:'third'), ]; await tester.pumpWidget( - buildNavigator(pages: myPages, onPopPage: onPopPage, key: navigator), + buildNavigator( + view: tester.view, + pages: myPages, + onPopPage: onPopPage, + key: navigator, + ), ); await tester.pumpAndSettle(); expect(find.text('initial'), findsNothing); @@ -3176,7 +3239,12 @@ void main() { const TestPage(key: ValueKey('2'), name:'second'), ]; await tester.pumpWidget( - buildNavigator(pages: myPages, onPopPage: onPopPage, key: navigator), + buildNavigator( + view: tester.view, + pages: myPages, + onPopPage: onPopPage, + key: navigator, + ), ); // Swaps the order without any adding or removing should not trigger any // transition. The routes should update without a pumpAndSettle @@ -3248,7 +3316,12 @@ void main() { // Add initial page route with one pageless route. await tester.pumpWidget( - buildNavigator(pages: myPages, onPopPage: onPopPage, key: navigator), + buildNavigator( + view: tester.view, + pages: myPages, + onPopPage: onPopPage, + key: navigator, + ), ); bool initialPageless1Completed = false; navigator.currentState!.push( @@ -3264,7 +3337,12 @@ void main() { const TestPage(key: ValueKey('2'), name: 'second'), ]; await tester.pumpWidget( - buildNavigator(pages: myPages, onPopPage: onPopPage, key: navigator), + buildNavigator( + view: tester.view, + pages: myPages, + onPopPage: onPopPage, + key: navigator, + ), ); await tester.pumpAndSettle(); bool secondPageless1Completed = false; @@ -3289,7 +3367,12 @@ void main() { const TestPage(key: ValueKey('3'), name: 'third'), ]; await tester.pumpWidget( - buildNavigator(pages: myPages, onPopPage: onPopPage, key: navigator), + buildNavigator( + view: tester.view, + pages: myPages, + onPopPage: onPopPage, + key: navigator, + ), ); await tester.pumpAndSettle(); bool thirdPageless1Completed = false; @@ -3312,7 +3395,12 @@ void main() { const TestPage(key: ValueKey('2'), name: 'second'), ]; await tester.pumpWidget( - buildNavigator(pages: myPages, onPopPage: onPopPage, key: navigator), + buildNavigator( + view: tester.view, + pages: myPages, + onPopPage: onPopPage, + key: navigator, + ), ); // The pageless route of initial page route should be completed. expect(initialPageless1Completed, true); @@ -3324,7 +3412,12 @@ void main() { const TestPage(key: ValueKey('3'), name: 'third'), ]; await tester.pumpWidget( - buildNavigator(pages: myPages, onPopPage: onPopPage, key: navigator), + buildNavigator( + view: tester.view, + pages: myPages, + onPopPage: onPopPage, + key: navigator, + ), ); await tester.pumpAndSettle(); expect(secondPageless1Completed, true); @@ -3335,7 +3428,12 @@ void main() { const TestPage(key: ValueKey('4'), name: 'forth'), ]; await tester.pumpWidget( - buildNavigator(pages: myPages, onPopPage: onPopPage, key: navigator), + buildNavigator( + view: tester.view, + pages: myPages, + onPopPage: onPopPage, + key: navigator, + ), ); expect(thirdPageless1Completed, true); await tester.pumpAndSettle(); @@ -3356,7 +3454,12 @@ void main() { } await tester.pumpWidget( - buildNavigator(pages: myPages, onPopPage: onPopPage, key: navigator), + buildNavigator( + view: tester.view, + pages: myPages, + onPopPage: onPopPage, + key: navigator, + ), ); expect(find.text('second'), findsOneWidget); expect(find.text('initial'), findsNothing); @@ -3378,7 +3481,12 @@ void main() { const TestPage(key: ValueKey('2'), name:'second'), ]; await tester.pumpWidget( - buildNavigator(pages: myPages, onPopPage: onPopPage, key: navigator), + buildNavigator( + view: tester.view, + pages: myPages, + onPopPage: onPopPage, + key: navigator, + ), ); await tester.pumpAndSettle(); @@ -3411,6 +3519,7 @@ void main() { // Add initial page route with one pageless route. await tester.pumpWidget( buildNavigator( + view: tester.view, pages: myPages, onPopPage: onPopPage, key: navigator, @@ -3432,6 +3541,7 @@ void main() { ]; await tester.pumpWidget( buildNavigator( + view: tester.view, pages: myPages, onPopPage: onPopPage, key: navigator, @@ -3461,6 +3571,7 @@ void main() { ]; await tester.pumpWidget( buildNavigator( + view: tester.view, pages: myPages, onPopPage: onPopPage, key: navigator, @@ -3488,6 +3599,7 @@ void main() { ]; await tester.pumpWidget( buildNavigator( + view: tester.view, pages: myPages, onPopPage: onPopPage, key: navigator, @@ -3505,6 +3617,7 @@ void main() { ]; await tester.pumpWidget( buildNavigator( + view: tester.view, pages: myPages, onPopPage: onPopPage, key: navigator, @@ -3522,6 +3635,7 @@ void main() { ]; await tester.pumpWidget( buildNavigator( + view: tester.view, pages: myPages, onPopPage: onPopPage, key: navigator, @@ -3547,7 +3661,12 @@ void main() { return route.didPop(result); } await tester.pumpWidget( - buildNavigator(pages: myPages, onPopPage: onPopPage, key: navigator), + buildNavigator( + view: tester.view, + pages: myPages, + onPopPage: onPopPage, + key: navigator, + ), ); // Pops the second page route. @@ -3555,7 +3674,12 @@ void main() { const TestPage(key: ValueKey('1'), name: 'initial'), ]; await tester.pumpWidget( - buildNavigator(pages: myPages, onPopPage: onPopPage, key: navigator), + buildNavigator( + view: tester.view, + pages: myPages, + onPopPage: onPopPage, + key: navigator, + ), ); // Re-push the second page again before it finishes popping. @@ -3564,7 +3688,12 @@ void main() { const TestPage(key: ValueKey('2'), name: 'second'), ]; await tester.pumpWidget( - buildNavigator(pages: myPages, onPopPage: onPopPage, key: navigator), + buildNavigator( + view: tester.view, + pages: myPages, + onPopPage: onPopPage, + key: navigator, + ), ); // It should not crash the app. @@ -3584,7 +3713,12 @@ void main() { return route.didPop(result); } await tester.pumpWidget( - buildNavigator(pages: myPages, onPopPage: onPopPage, key: navigator), + buildNavigator( + view: tester.view, + pages: myPages, + onPopPage: onPopPage, + key: navigator, + ), ); // Pops the second page route. @@ -3592,7 +3726,12 @@ void main() { const TestPage(key: ValueKey('1'), name: 'initial'), ]; await tester.pumpWidget( - buildNavigator(pages: myPages, onPopPage: onPopPage, key: navigator), + buildNavigator( + view: tester.view, + pages: myPages, + onPopPage: onPopPage, + key: navigator, + ), ); // Updates the pages again before second page finishes popping. @@ -3600,7 +3739,12 @@ void main() { const TestPage(key: ValueKey('1'), name: 'initial'), ]; await tester.pumpWidget( - buildNavigator(pages: myPages, onPopPage: onPopPage, key: navigator), + buildNavigator( + view: tester.view, + pages: myPages, + onPopPage: onPopPage, + key: navigator, + ), ); // It should not crash the app. @@ -3621,7 +3765,12 @@ void main() { return route.didPop(result); } await tester.pumpWidget( - buildNavigator(pages: myPages, onPopPage: onPopPage, key: navigator), + buildNavigator( + view: tester.view, + pages: myPages, + onPopPage: onPopPage, + key: navigator, + ), ); // Pushes a pageless route. showDialog( @@ -3638,7 +3787,12 @@ void main() { const TestPage(key: ValueKey('1'), name: 'initial'), ]; await tester.pumpWidget( - buildNavigator(pages: myPages, onPopPage: onPopPage, key: navigator), + buildNavigator( + view: tester.view, + pages: myPages, + onPopPage: onPopPage, + key: navigator, + ), ); // It should not crash the app. expect(tester.takeException(), isNull); @@ -3677,6 +3831,7 @@ void main() { await tester.pumpWidget( buildNavigator( + view: tester.view, pages: myPages, onPopPage: onPopPage, key: navigator, @@ -3690,6 +3845,7 @@ void main() { await tester.pumpWidget( buildNavigator( + view: tester.view, pages: myPages, onPopPage: onPopPage, key: navigator,