diff --git a/packages/webview_flutter/webview_flutter/example/integration_test/webview_flutter_test.dart b/packages/webview_flutter/webview_flutter/example/integration_test/webview_flutter_test.dart index eaf9d7ea30944..819818848c9bb 100644 --- a/packages/webview_flutter/webview_flutter/example/integration_test/webview_flutter_test.dart +++ b/packages/webview_flutter/webview_flutter/example/integration_test/webview_flutter_test.dart @@ -491,7 +491,7 @@ Future main() async { }); group('Programmatic Scroll', () { - testWidgets('setAndGetScrollPosition', (WidgetTester tester) async { + Future pumpScrollTestPage(WidgetTester tester) async { const String scrollTestPage = ''' @@ -518,58 +518,105 @@ Future main() async { final Completer pageLoaded = Completer(); final WebViewController controller = WebViewController(); - ScrollPositionChange? recordedPosition; - await controller.setJavaScriptMode(JavaScriptMode.unrestricted); await controller.setNavigationDelegate(NavigationDelegate( onPageFinished: (_) => pageLoaded.complete(), )); - await controller.setOnScrollPositionChange( - (ScrollPositionChange contentOffsetChange) { - recordedPosition = contentOffsetChange; - }); await controller.loadRequest(Uri.parse( 'data:text/html;charset=utf-8;base64,$scrollTestPageBase64', )); await tester.pumpWidget(WebViewWidget(controller: controller)); - await pageLoaded.future; - await tester.pumpAndSettle(const Duration(seconds: 3)); - - Offset scrollPos = await controller.getScrollPosition(); - - // Check scrollTo() - const int X_SCROLL = 123; - const int Y_SCROLL = 321; - // Get the initial position; this ensures that scrollTo is actually - // changing something, but also gives the native view's scroll position - // time to settle. - expect(scrollPos.dx, isNot(X_SCROLL)); - expect(scrollPos.dy, isNot(Y_SCROLL)); - expect(recordedPosition?.x, isNot(X_SCROLL)); - expect(recordedPosition?.y, isNot(Y_SCROLL)); - - await controller.scrollTo(X_SCROLL, Y_SCROLL); - scrollPos = await controller.getScrollPosition(); - expect(scrollPos.dx, X_SCROLL); - expect(scrollPos.dy, Y_SCROLL); - expect(recordedPosition?.x, X_SCROLL); - expect(recordedPosition?.y, Y_SCROLL); - - // Check scrollBy() (on top of scrollTo()) - await controller.scrollBy(X_SCROLL, Y_SCROLL); - scrollPos = await controller.getScrollPosition(); - expect(scrollPos.dx, X_SCROLL * 2); - expect(scrollPos.dy, Y_SCROLL * 2); - expect(recordedPosition?.x, X_SCROLL * 2); - expect(recordedPosition?.y, Y_SCROLL * 2); + return controller; + } + + testWidgets('getScrollPosition', (WidgetTester tester) async { + final WebViewController controller = await pumpScrollTestPage(tester); + await controller.setJavaScriptMode(JavaScriptMode.unrestricted); + + const Offset testScrollPosition = Offset(123, 321); + + // Ensure the start scroll position is not equal to the test position. + expect(await controller.getScrollPosition(), isNot(testScrollPosition)); + + final Completer testScrollPositionCompleter = Completer(); + await controller.setOnScrollPositionChange( + (ScrollPositionChange contentOffsetChange) { + if (Offset(contentOffsetChange.x, contentOffsetChange.y) == + testScrollPosition) { + testScrollPositionCompleter.complete(); + } + }, + ); + + await controller.scrollTo( + testScrollPosition.dx.toInt(), + testScrollPosition.dy.toInt(), + ); + await testScrollPositionCompleter.future; + + expect(await controller.getScrollPosition(), testScrollPosition); + }); + + testWidgets('scrollTo', (WidgetTester tester) async { + final WebViewController controller = await pumpScrollTestPage(tester); + + const Offset testScrollPosition = Offset(123, 321); + + // Ensure the start scroll position is not equal to the test position. + expect(await controller.getScrollPosition(), isNot(testScrollPosition)); + + late ScrollPositionChange lastPositionChange; + await controller.setOnScrollPositionChange( + expectAsyncUntil1( + (ScrollPositionChange contentOffsetChange) { + lastPositionChange = contentOffsetChange; + }, + () { + return Offset(lastPositionChange.x, lastPositionChange.y) == + testScrollPosition; + }, + ), + ); + + await controller.scrollTo( + testScrollPosition.dx.toInt(), + testScrollPosition.dy.toInt(), + ); + }); + + testWidgets('scrollBy', (WidgetTester tester) async { + final WebViewController controller = await pumpScrollTestPage(tester); + + const Offset testScrollPosition = Offset(123, 321); + + // Ensure the start scroll position is not equal to the test position. + expect(await controller.getScrollPosition(), isNot(testScrollPosition)); + + late ScrollPositionChange lastPositionChange; + await controller.setOnScrollPositionChange( + expectAsyncUntil1( + (ScrollPositionChange contentOffsetChange) { + lastPositionChange = contentOffsetChange; + }, + () { + return Offset(lastPositionChange.x, lastPositionChange.y) == + testScrollPosition; + }, + ), + ); + + await controller.scrollTo(0, 0); + await controller.scrollBy( + testScrollPosition.dx.toInt(), + testScrollPosition.dy.toInt(), + ); }); }, // Scroll position is currently not implemented for macOS. - // Flakes on iOS: https://github.com/flutter/flutter/issues/154826 - skip: Platform.isMacOS || Platform.isIOS); + skip: Platform.isMacOS); group('NavigationDelegate', () { const String blankPage = ''; diff --git a/packages/webview_flutter/webview_flutter_android/example/integration_test/webview_flutter_test.dart b/packages/webview_flutter/webview_flutter_android/example/integration_test/webview_flutter_test.dart index 4c22df1ff28c7..76f5549fb88d8 100644 --- a/packages/webview_flutter/webview_flutter_android/example/integration_test/webview_flutter_test.dart +++ b/packages/webview_flutter/webview_flutter_android/example/integration_test/webview_flutter_test.dart @@ -758,8 +758,9 @@ Future main() async { }); group('Programmatic Scroll', () { - testWidgets('setAndGetAndListenScrollPosition', - (WidgetTester tester) async { + Future pumpScrollTestPage( + WidgetTester tester, + ) async { const String scrollTestPage = ''' @@ -785,28 +786,20 @@ Future main() async { base64Encode(const Utf8Encoder().convert(scrollTestPage)); final Completer pageLoaded = Completer(); - ScrollPositionChange? recordedPosition; final PlatformWebViewController controller = PlatformWebViewController( const PlatformWebViewControllerCreationParams(), ); - await controller.setJavaScriptMode(JavaScriptMode.unrestricted); final PlatformNavigationDelegate delegate = PlatformNavigationDelegate( const PlatformNavigationDelegateCreationParams(), ); await delegate.setOnPageFinished((_) => pageLoaded.complete()); await controller.setPlatformNavigationDelegate(delegate); - await controller.setOnScrollPositionChange( - (ScrollPositionChange contentOffsetChange) { - recordedPosition = contentOffsetChange; - }); - await controller.loadRequest( - LoadRequestParams( - uri: Uri.parse( - 'data:text/html;charset=utf-8;base64,$scrollTestPageBase64', - ), + await controller.loadRequest(LoadRequestParams( + uri: Uri.parse( + 'data:text/html;charset=utf-8;base64,$scrollTestPageBase64', ), - ); + )); await tester.pumpWidget(Builder( builder: (BuildContext context) { @@ -815,37 +808,95 @@ Future main() async { ).build(context); }, )); - await pageLoaded.future; - await tester.pumpAndSettle(const Duration(seconds: 3)); - - Offset scrollPos = await controller.getScrollPosition(); - - // Check scrollTo() - const int X_SCROLL = 123; - const int Y_SCROLL = 321; - // Get the initial position; this ensures that scrollTo is actually - // changing something, but also gives the native view's scroll position - // time to settle. - expect(scrollPos.dx, isNot(X_SCROLL)); - expect(scrollPos.dy, isNot(Y_SCROLL)); - expect(recordedPosition, null); - - await controller.scrollTo(X_SCROLL, Y_SCROLL); - scrollPos = await controller.getScrollPosition(); - expect(scrollPos.dx, X_SCROLL); - expect(scrollPos.dy, Y_SCROLL); - expect(recordedPosition?.x, X_SCROLL); - expect(recordedPosition?.y, Y_SCROLL); - - // Check scrollBy() (on top of scrollTo()) - await controller.scrollBy(X_SCROLL, Y_SCROLL); - scrollPos = await controller.getScrollPosition(); - expect(scrollPos.dx, X_SCROLL * 2); - expect(scrollPos.dy, Y_SCROLL * 2); - expect(recordedPosition?.x, X_SCROLL * 2); - expect(recordedPosition?.y, Y_SCROLL * 2); + return controller; + } + + testWidgets('getScrollPosition', (WidgetTester tester) async { + final PlatformWebViewController controller = + await pumpScrollTestPage(tester); + await controller.setJavaScriptMode(JavaScriptMode.unrestricted); + + const Offset testScrollPosition = Offset(123, 321); + + // Ensure the start scroll position is not equal to the test position. + expect(await controller.getScrollPosition(), isNot(testScrollPosition)); + + final Completer testScrollPositionCompleter = Completer(); + await controller.setOnScrollPositionChange( + (ScrollPositionChange contentOffsetChange) { + if (Offset(contentOffsetChange.x, contentOffsetChange.y) == + testScrollPosition) { + testScrollPositionCompleter.complete(); + } + }, + ); + + await controller.scrollTo( + testScrollPosition.dx.toInt(), + testScrollPosition.dy.toInt(), + ); + await testScrollPositionCompleter.future; + + expect(await controller.getScrollPosition(), testScrollPosition); + }); + + testWidgets('scrollTo', (WidgetTester tester) async { + final PlatformWebViewController controller = + await pumpScrollTestPage(tester); + + const Offset testScrollPosition = Offset(123, 321); + + // Ensure the start scroll position is not equal to the test position. + expect(await controller.getScrollPosition(), isNot(testScrollPosition)); + + late ScrollPositionChange lastPositionChange; + await controller.setOnScrollPositionChange( + expectAsyncUntil1( + (ScrollPositionChange contentOffsetChange) { + lastPositionChange = contentOffsetChange; + }, + () { + return Offset(lastPositionChange.x, lastPositionChange.y) == + testScrollPosition; + }, + ), + ); + + await controller.scrollTo( + testScrollPosition.dx.toInt(), + testScrollPosition.dy.toInt(), + ); + }); + + testWidgets('scrollBy', (WidgetTester tester) async { + final PlatformWebViewController controller = + await pumpScrollTestPage(tester); + + const Offset testScrollPosition = Offset(123, 321); + + // Ensure the start scroll position is not equal to the test position. + expect(await controller.getScrollPosition(), isNot(testScrollPosition)); + + late ScrollPositionChange lastPositionChange; + await controller.setOnScrollPositionChange( + expectAsyncUntil1( + (ScrollPositionChange contentOffsetChange) { + lastPositionChange = contentOffsetChange; + }, + () { + return Offset(lastPositionChange.x, lastPositionChange.y) == + testScrollPosition; + }, + ), + ); + + await controller.scrollTo(0, 0); + await controller.scrollBy( + testScrollPosition.dx.toInt(), + testScrollPosition.dy.toInt(), + ); }); }); diff --git a/packages/webview_flutter/webview_flutter_wkwebview/example/integration_test/webview_flutter_test.dart b/packages/webview_flutter/webview_flutter_wkwebview/example/integration_test/webview_flutter_test.dart index 6f9256687df0e..0a11f26e717b1 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/example/integration_test/webview_flutter_test.dart +++ b/packages/webview_flutter/webview_flutter_wkwebview/example/integration_test/webview_flutter_test.dart @@ -716,8 +716,8 @@ Future main() async { }); group('Programmatic Scroll', () { - testWidgets('setAndGetAndListenScrollPosition', - (WidgetTester tester) async { + Future pumpScrollTestPage( + WidgetTester tester) async { const String scrollTestPage = ''' @@ -743,28 +743,20 @@ Future main() async { base64Encode(const Utf8Encoder().convert(scrollTestPage)); final Completer pageLoaded = Completer(); - ScrollPositionChange? recordedPosition; final PlatformWebViewController controller = PlatformWebViewController( const PlatformWebViewControllerCreationParams(), ); - unawaited(controller.setJavaScriptMode(JavaScriptMode.unrestricted)); final PlatformNavigationDelegate delegate = PlatformNavigationDelegate( const PlatformNavigationDelegateCreationParams(), ); - unawaited(delegate.setOnPageFinished((_) => pageLoaded.complete())); - unawaited(controller.setPlatformNavigationDelegate(delegate)); - unawaited(controller.setOnScrollPositionChange( - (ScrollPositionChange scrollPositionChange) { - recordedPosition = scrollPositionChange; - })); + await delegate.setOnPageFinished((_) => pageLoaded.complete()); + await controller.setPlatformNavigationDelegate(delegate); - await controller.loadRequest( - LoadRequestParams( - uri: Uri.parse( - 'data:text/html;charset=utf-8;base64,$scrollTestPageBase64', - ), + await controller.loadRequest(LoadRequestParams( + uri: Uri.parse( + 'data:text/html;charset=utf-8;base64,$scrollTestPageBase64', ), - ); + )); await tester.pumpWidget(Builder( builder: (BuildContext context) { @@ -773,43 +765,99 @@ Future main() async { ).build(context); }, )); - await pageLoaded.future; - await tester.pumpAndSettle(const Duration(seconds: 3)); - - Offset scrollPos = await controller.getScrollPosition(); - - // Check scrollTo() - const int X_SCROLL = 123; - const int Y_SCROLL = 321; - // Get the initial position; this ensures that scrollTo is actually - // changing something, but also gives the native view's scroll position - // time to settle. - expect(scrollPos.dx, isNot(X_SCROLL)); - expect(scrollPos.dy, isNot(Y_SCROLL)); - expect(recordedPosition?.x, isNot(X_SCROLL)); - expect(recordedPosition?.y, isNot(Y_SCROLL)); - - await controller.scrollTo(X_SCROLL, Y_SCROLL); - scrollPos = await controller.getScrollPosition(); - expect(scrollPos.dx, X_SCROLL); - expect(scrollPos.dy, Y_SCROLL); - expect(recordedPosition?.x, X_SCROLL); - expect(recordedPosition?.y, Y_SCROLL); - - // Check scrollBy() (on top of scrollTo()) - await controller.scrollBy(X_SCROLL, Y_SCROLL); - scrollPos = await controller.getScrollPosition(); - expect(scrollPos.dx, X_SCROLL * 2); - expect(scrollPos.dy, Y_SCROLL * 2); - expect(recordedPosition?.x, X_SCROLL * 2); - expect(recordedPosition?.y, Y_SCROLL * 2); + return controller; + } + + testWidgets('getScrollPosition', (WidgetTester tester) async { + final PlatformWebViewController controller = + await pumpScrollTestPage(tester); + await controller.setJavaScriptMode(JavaScriptMode.unrestricted); + + const Offset testScrollPosition = Offset(123, 321); + + // Ensure the start scroll position is not equal to the test position. + expect(await controller.getScrollPosition(), isNot(testScrollPosition)); + + final Completer testScrollPositionCompleter = Completer(); + await controller.setOnScrollPositionChange( + (ScrollPositionChange contentOffsetChange) { + if (Offset(contentOffsetChange.x, contentOffsetChange.y) == + testScrollPosition) { + testScrollPositionCompleter.complete(); + } + }, + ); + + await controller.scrollTo( + testScrollPosition.dx.toInt(), + testScrollPosition.dy.toInt(), + ); + await testScrollPositionCompleter.future; + + expect(await controller.getScrollPosition(), testScrollPosition); + }); + + testWidgets('scrollTo', (WidgetTester tester) async { + final PlatformWebViewController controller = + await pumpScrollTestPage(tester); + + const Offset testScrollPosition = Offset(123, 321); + + // Ensure the start scroll position is not equal to the test position + expect(await controller.getScrollPosition(), isNot(testScrollPosition)); + + late ScrollPositionChange lastPositionChange; + await controller.setOnScrollPositionChange( + expectAsyncUntil1( + (ScrollPositionChange contentOffsetChange) { + lastPositionChange = contentOffsetChange; + }, + () { + return Offset(lastPositionChange.x, lastPositionChange.y) == + testScrollPosition; + }, + ), + ); + + await controller.scrollTo( + testScrollPosition.dx.toInt(), + testScrollPosition.dy.toInt(), + ); + }); + + testWidgets('scrollBy', (WidgetTester tester) async { + final PlatformWebViewController controller = + await pumpScrollTestPage(tester); + + const Offset testScrollPosition = Offset(123, 321); + + // Ensure the start scroll position is not equal to the test position + expect(await controller.getScrollPosition(), isNot(testScrollPosition)); + + late ScrollPositionChange lastPositionChange; + await controller.setOnScrollPositionChange( + expectAsyncUntil1( + (ScrollPositionChange contentOffsetChange) { + lastPositionChange = contentOffsetChange; + }, + () { + return Offset(lastPositionChange.x, lastPositionChange.y) == + testScrollPosition; + }, + ), + ); + + await controller.scrollTo(0, 0); + await controller.scrollBy( + testScrollPosition.dx.toInt(), + testScrollPosition.dy.toInt(), + ); }); }, // Scroll position is currently not implemented for macOS. - // Flakes on iOS: https://github.com/flutter/flutter/issues/154826 - skip: Platform.isMacOS || Platform.isIOS); + skip: Platform.isMacOS); group('NavigationDelegate', () { const String blankPage = '';