diff --git a/dev/automated_tests/pubspec.yaml b/dev/automated_tests/pubspec.yaml index 7c7633b16f..c5702503cd 100644 --- a/dev/automated_tests/pubspec.yaml +++ b/dev/automated_tests/pubspec.yaml @@ -19,7 +19,7 @@ dependencies: charcode: 1.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" collection: 1.14.11 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" convert: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - coverage: 0.13.3+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + coverage: 0.13.3+3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" crypto: 2.1.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" csslib: 0.16.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" front_end: 0.1.27 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -74,4 +74,4 @@ flutter: assets: - icon/ -# PUBSPEC CHECKSUM: ebc8 +# PUBSPEC CHECKSUM: deca diff --git a/dev/benchmarks/complex_layout/pubspec.yaml b/dev/benchmarks/complex_layout/pubspec.yaml index b34f3fc222..c008c64ae8 100644 --- a/dev/benchmarks/complex_layout/pubspec.yaml +++ b/dev/benchmarks/complex_layout/pubspec.yaml @@ -17,6 +17,8 @@ dependencies: # flutter update-packages --force-upgrade flutter_gallery_assets: 0.1.9+2 + archive: 2.0.11 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + args: 1.5.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" async: 2.4.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" charcode: 1.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" collection: 1.14.11 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -25,17 +27,20 @@ dependencies: file: 5.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" intl: 0.16.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" json_rpc_2: 2.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + matcher: 0.12.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" meta: 1.1.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" path: 1.6.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" pub_semver: 1.4.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" source_span: 1.5.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" stack_trace: 1.9.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" stream_channel: 2.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + sync_http: 0.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" term_glyph: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" typed_data: 1.1.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vector_math: 2.0.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vm_service_client: 0.2.6+2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web_socket_channel: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + webdriver: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" dev_dependencies: flutter_test: @@ -43,10 +48,8 @@ dev_dependencies: test: 1.9.4 analyzer: 0.38.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - archive: 2.0.11 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - args: 1.5.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" boolean_selector: 1.0.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - coverage: 0.13.3+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + coverage: 0.13.3+3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" csslib: 0.16.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" front_end: 0.1.27 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" glob: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -59,7 +62,6 @@ dev_dependencies: js: 0.6.1+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" kernel: 0.3.27 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" logging: 0.11.3+2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - matcher: 0.12.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" mime: 0.9.6+3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" multi_server_socket: 1.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" node_interop: 1.0.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -91,4 +93,4 @@ flutter: - packages/flutter_gallery_assets/people/square/ali.png - packages/flutter_gallery_assets/places/india_chettinad_silk_maker.png -# PUBSPEC CHECKSUM: 4cef +# PUBSPEC CHECKSUM: 3f37 diff --git a/dev/benchmarks/macrobenchmarks/pubspec.yaml b/dev/benchmarks/macrobenchmarks/pubspec.yaml index 471d22ca0e..54cde47556 100644 --- a/dev/benchmarks/macrobenchmarks/pubspec.yaml +++ b/dev/benchmarks/macrobenchmarks/pubspec.yaml @@ -17,6 +17,8 @@ dependencies: # flutter update-packages --force-upgrade flutter_gallery_assets: 0.1.9+2 + archive: 2.0.11 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + args: 1.5.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" async: 2.4.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" charcode: 1.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" collection: 1.14.11 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -25,17 +27,20 @@ dependencies: file: 5.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" intl: 0.16.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" json_rpc_2: 2.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + matcher: 0.12.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" meta: 1.1.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" path: 1.6.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" pub_semver: 1.4.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" source_span: 1.5.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" stack_trace: 1.9.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" stream_channel: 2.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + sync_http: 0.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" term_glyph: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" typed_data: 1.1.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vector_math: 2.0.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vm_service_client: 0.2.6+2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web_socket_channel: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + webdriver: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" dev_dependencies: flutter_test: @@ -43,10 +48,8 @@ dev_dependencies: test: 1.9.4 analyzer: 0.38.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - archive: 2.0.11 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - args: 1.5.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" boolean_selector: 1.0.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - coverage: 0.13.3+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + coverage: 0.13.3+3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" csslib: 0.16.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" front_end: 0.1.27 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" glob: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -59,7 +62,6 @@ dev_dependencies: js: 0.6.1+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" kernel: 0.3.27 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" logging: 0.11.3+2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - matcher: 0.12.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" mime: 0.9.6+3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" multi_server_socket: 1.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" node_interop: 1.0.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -92,4 +94,4 @@ flutter: - packages/flutter_gallery_assets/food/cherry_pie.png - assets/999x1000.png -# PUBSPEC CHECKSUM: 4cef +# PUBSPEC CHECKSUM: 3f37 diff --git a/dev/benchmarks/microbenchmarks/pubspec.yaml b/dev/benchmarks/microbenchmarks/pubspec.yaml index ed952cf055..12840f8d07 100644 --- a/dev/benchmarks/microbenchmarks/pubspec.yaml +++ b/dev/benchmarks/microbenchmarks/pubspec.yaml @@ -23,7 +23,7 @@ dependencies: charcode: 1.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" collection: 1.14.11 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" convert: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - coverage: 0.13.3+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + coverage: 0.13.3+3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" crypto: 2.1.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" csslib: 0.16.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" dart_style: 1.3.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -79,4 +79,4 @@ dependencies: flutter: uses-material-design: true -# PUBSPEC CHECKSUM: e51f +# PUBSPEC CHECKSUM: e521 diff --git a/dev/bots/pubspec.yaml b/dev/bots/pubspec.yaml index 46654577c6..dd9e1986c8 100644 --- a/dev/bots/pubspec.yaml +++ b/dev/bots/pubspec.yaml @@ -24,7 +24,7 @@ dependencies: charcode: 1.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" collection: 1.14.11 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" convert: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - coverage: 0.13.3+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + coverage: 0.13.3+3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" crypto: 2.1.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" csslib: 0.16.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" file: 5.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -70,4 +70,4 @@ dev_dependencies: mockito: 4.1.1 test_api: 0.2.11 -# PUBSPEC CHECKSUM: 2235 +# PUBSPEC CHECKSUM: a937 diff --git a/dev/bots/test.dart b/dev/bots/test.dart index d18333019d..f2f54348bf 100644 --- a/dev/bots/test.dart +++ b/dev/bots/test.dart @@ -439,7 +439,7 @@ Future _runFrameworkTests() async { await _runFlutterTest(path.join(flutterRoot, 'examples', 'hello_world'), tableData: bigqueryApi?.tabledata); await _runFlutterTest(path.join(flutterRoot, 'examples', 'layers'), tableData: bigqueryApi?.tabledata); await _runFlutterTest(path.join(flutterRoot, 'examples', 'stocks'), tableData: bigqueryApi?.tabledata); - await _runFlutterTest(path.join(flutterRoot, 'packages', 'flutter_driver'), tableData: bigqueryApi?.tabledata); + await _runFlutterTest(path.join(flutterRoot, 'packages', 'flutter_driver'), tableData: bigqueryApi?.tabledata, tests: [path.join('test', 'src', 'real_tests')]); await _runFlutterTest(path.join(flutterRoot, 'packages', 'flutter_goldens'), tableData: bigqueryApi?.tabledata); await _runFlutterTest(path.join(flutterRoot, 'packages', 'flutter_localizations'), tableData: bigqueryApi?.tabledata); await _runFlutterTest(path.join(flutterRoot, 'packages', 'flutter_test'), tableData: bigqueryApi?.tabledata); @@ -534,6 +534,10 @@ Future _runWebTests() async { path.join(flutterRoot, 'packages', 'flutter_web_plugins'), ['test'], ); + await _runFlutterWebTest( + path.join(flutterRoot, 'packages', 'flutter_driver'), + [path.join('test', 'src', 'web_tests', 'web_extension_test.dart')], + ); }; await selectSubshard(subshards); diff --git a/dev/devicelab/pubspec.yaml b/dev/devicelab/pubspec.yaml index 9477c5a5a2..b9fed1803d 100644 --- a/dev/devicelab/pubspec.yaml +++ b/dev/devicelab/pubspec.yaml @@ -43,7 +43,7 @@ dev_dependencies: analyzer: 0.38.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" boolean_selector: 1.0.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - coverage: 0.13.3+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + coverage: 0.13.3+3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" csslib: 0.16.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" front_end: 0.1.27 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" glob: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -77,4 +77,4 @@ dev_dependencies: watcher: 0.9.7+13 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" yaml: 2.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" -# PUBSPEC CHECKSUM: 9e46 +# PUBSPEC CHECKSUM: 9648 diff --git a/dev/integration_tests/android_embedding_v2_smoke_test/pubspec.yaml b/dev/integration_tests/android_embedding_v2_smoke_test/pubspec.yaml index a94145a816..76f9c37fcf 100644 --- a/dev/integration_tests/android_embedding_v2_smoke_test/pubspec.yaml +++ b/dev/integration_tests/android_embedding_v2_smoke_test/pubspec.yaml @@ -20,12 +20,12 @@ dependencies: flutter: sdk: flutter # This plugin is using Android Embedding 1 - battery: 0.3.1+4 + battery: 0.3.1+6 # TODO(egarciad): Add a plugin that uses Android Embedding 2 # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: 0.1.2 + cupertino_icons: 0.1.3 collection: 1.14.11 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" meta: 1.1.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -100,4 +100,4 @@ flutter: # For details regarding fonts from package dependencies, # see https://flutter.dev/custom-fonts/#from-packages -# PUBSPEC CHECKSUM: fad6 +# PUBSPEC CHECKSUM: 9bd9 diff --git a/dev/integration_tests/android_semantics_testing/pubspec.yaml b/dev/integration_tests/android_semantics_testing/pubspec.yaml index 2139674d48..7bfe54f3d8 100644 --- a/dev/integration_tests/android_semantics_testing/pubspec.yaml +++ b/dev/integration_tests/android_semantics_testing/pubspec.yaml @@ -9,13 +9,14 @@ dependencies: test: 1.9.4 analyzer: 0.38.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + archive: 2.0.11 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" args: 1.5.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" async: 2.4.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" boolean_selector: 1.0.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" charcode: 1.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" collection: 1.14.11 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" convert: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - coverage: 0.13.3+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + coverage: 0.13.3+3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" crypto: 2.1.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" csslib: 0.16.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" file: 5.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -54,6 +55,7 @@ dependencies: stack_trace: 1.9.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" stream_channel: 2.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" string_scanner: 1.0.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + sync_http: 0.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" term_glyph: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" test_api: 0.2.11 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" test_core: 0.2.15 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -63,9 +65,10 @@ dependencies: vm_service_client: 0.2.6+2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" watcher: 0.9.7+13 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web_socket_channel: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + webdriver: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" yaml: 2.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" flutter: uses-material-design: true -# PUBSPEC CHECKSUM: f2a9 +# PUBSPEC CHECKSUM: cd51 diff --git a/dev/integration_tests/android_splash_screens/splash_screen_kitchen_sink/pubspec.yaml b/dev/integration_tests/android_splash_screens/splash_screen_kitchen_sink/pubspec.yaml index 832e345ac8..8a2daf4730 100644 --- a/dev/integration_tests/android_splash_screens/splash_screen_kitchen_sink/pubspec.yaml +++ b/dev/integration_tests/android_splash_screens/splash_screen_kitchen_sink/pubspec.yaml @@ -22,7 +22,7 @@ dependencies: # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: 0.1.2 + cupertino_icons: 0.1.3 collection: 1.14.11 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" meta: 1.1.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -49,7 +49,7 @@ dev_dependencies: boolean_selector: 1.0.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" charcode: 1.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" convert: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - coverage: 0.13.3+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + coverage: 0.13.3+3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" crypto: 2.1.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" csslib: 0.16.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" file: 5.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -90,6 +90,7 @@ dev_dependencies: stack_trace: 1.9.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" stream_channel: 2.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" string_scanner: 1.0.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + sync_http: 0.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" term_glyph: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" test_api: 0.2.11 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" test_core: 0.2.15 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -97,6 +98,7 @@ dev_dependencies: vm_service_client: 0.2.6+2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" watcher: 0.9.7+13 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web_socket_channel: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + webdriver: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" xml: 3.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" yaml: 2.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -138,4 +140,4 @@ flutter: # For details regarding fonts from package dependencies, # see https://flutter.dev/custom-fonts/#from-packages -# PUBSPEC CHECKSUM: 8095 +# PUBSPEC CHECKSUM: c0dd diff --git a/dev/integration_tests/android_splash_screens/splash_screen_load_rotate/pubspec.yaml b/dev/integration_tests/android_splash_screens/splash_screen_load_rotate/pubspec.yaml index b4ae8e3446..5e5dd72253 100644 --- a/dev/integration_tests/android_splash_screens/splash_screen_load_rotate/pubspec.yaml +++ b/dev/integration_tests/android_splash_screens/splash_screen_load_rotate/pubspec.yaml @@ -22,7 +22,7 @@ dependencies: # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: 0.1.2 + cupertino_icons: 0.1.3 collection: 1.14.11 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" meta: 1.1.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -97,4 +97,4 @@ flutter: # For details regarding fonts from package dependencies, # see https://flutter.dev/custom-fonts/#from-packages -# PUBSPEC CHECKSUM: 712e +# PUBSPEC CHECKSUM: 6e2f diff --git a/dev/integration_tests/android_splash_screens/splash_screen_trans_rotate/pubspec.yaml b/dev/integration_tests/android_splash_screens/splash_screen_trans_rotate/pubspec.yaml index ee41f968af..09f8ae7c69 100644 --- a/dev/integration_tests/android_splash_screens/splash_screen_trans_rotate/pubspec.yaml +++ b/dev/integration_tests/android_splash_screens/splash_screen_trans_rotate/pubspec.yaml @@ -22,7 +22,7 @@ dependencies: # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: 0.1.2 + cupertino_icons: 0.1.3 collection: 1.14.11 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" meta: 1.1.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -49,7 +49,7 @@ dev_dependencies: boolean_selector: 1.0.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" charcode: 1.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" convert: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - coverage: 0.13.3+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + coverage: 0.13.3+3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" crypto: 2.1.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" csslib: 0.16.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" file: 5.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -90,6 +90,7 @@ dev_dependencies: stack_trace: 1.9.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" stream_channel: 2.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" string_scanner: 1.0.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + sync_http: 0.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" term_glyph: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" test_api: 0.2.11 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" test_core: 0.2.15 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -97,6 +98,7 @@ dev_dependencies: vm_service_client: 0.2.6+2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" watcher: 0.9.7+13 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web_socket_channel: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + webdriver: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" xml: 3.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" yaml: 2.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -138,4 +140,4 @@ flutter: # For details regarding fonts from package dependencies, # see https://flutter.dev/custom-fonts/#from-packages -# PUBSPEC CHECKSUM: 8095 +# PUBSPEC CHECKSUM: c0dd diff --git a/dev/integration_tests/android_views/pubspec.yaml b/dev/integration_tests/android_views/pubspec.yaml index 9fad209a96..8714fc47ab 100644 --- a/dev/integration_tests/android_views/pubspec.yaml +++ b/dev/integration_tests/android_views/pubspec.yaml @@ -7,7 +7,7 @@ dependencies: sdk: flutter flutter_driver: sdk: flutter - path_provider: 1.4.5 + path_provider: 1.5.1 collection: 1.14.11 assets_for_android_views: git: @@ -15,6 +15,8 @@ dependencies: ref: c47f1308188dca65b3899228cac37f252ea8b411 path: dev/integration_tests/assets_for_android_views + archive: 2.0.11 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + args: 1.5.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" async: 2.4.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" charcode: 1.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" convert: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -22,6 +24,7 @@ dependencies: file: 5.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" intl: 0.16.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" json_rpc_2: 2.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + matcher: 0.12.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" meta: 1.1.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" path: 1.6.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" platform: 2.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -29,11 +32,13 @@ dependencies: source_span: 1.5.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" stack_trace: 1.9.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" stream_channel: 2.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + sync_http: 0.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" term_glyph: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" typed_data: 1.1.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vector_math: 2.0.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vm_service_client: 0.2.6+2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web_socket_channel: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + webdriver: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" dev_dependencies: flutter_test: @@ -41,10 +46,8 @@ dev_dependencies: test: 1.9.4 analyzer: 0.38.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - archive: 2.0.11 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - args: 1.5.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" boolean_selector: 1.0.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - coverage: 0.13.3+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + coverage: 0.13.3+3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" csslib: 0.16.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" front_end: 0.1.27 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" glob: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -57,7 +60,6 @@ dev_dependencies: js: 0.6.1+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" kernel: 0.3.27 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" logging: 0.11.3+2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - matcher: 0.12.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" mime: 0.9.6+3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" multi_server_socket: 1.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" node_interop: 1.0.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -86,4 +88,4 @@ dev_dependencies: flutter: uses-material-design: true -# PUBSPEC CHECKSUM: 4173 +# PUBSPEC CHECKSUM: 95b7 diff --git a/dev/integration_tests/channels/pubspec.yaml b/dev/integration_tests/channels/pubspec.yaml index 98245b6649..6b33d16668 100644 --- a/dev/integration_tests/channels/pubspec.yaml +++ b/dev/integration_tests/channels/pubspec.yaml @@ -13,13 +13,14 @@ dependencies: test: 1.9.4 analyzer: 0.38.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + archive: 2.0.11 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" args: 1.5.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" async: 2.4.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" boolean_selector: 1.0.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" charcode: 1.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" collection: 1.14.11 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" convert: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - coverage: 0.13.3+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + coverage: 0.13.3+3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" crypto: 2.1.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" csslib: 0.16.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" file: 5.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -58,6 +59,7 @@ dependencies: stack_trace: 1.9.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" stream_channel: 2.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" string_scanner: 1.0.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + sync_http: 0.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" term_glyph: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" test_api: 0.2.11 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" test_core: 0.2.15 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -67,9 +69,10 @@ dependencies: vm_service_client: 0.2.6+2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" watcher: 0.9.7+13 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web_socket_channel: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + webdriver: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" yaml: 2.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" flutter: uses-material-design: true -# PUBSPEC CHECKSUM: f2a9 +# PUBSPEC CHECKSUM: cd51 diff --git a/dev/integration_tests/codegen/pubspec.yaml b/dev/integration_tests/codegen/pubspec.yaml index 9160ca37d8..ab2a6872ee 100644 --- a/dev/integration_tests/codegen/pubspec.yaml +++ b/dev/integration_tests/codegen/pubspec.yaml @@ -11,6 +11,8 @@ dependencies: flutter_driver: sdk: flutter + archive: 2.0.11 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + args: 1.5.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" async: 2.4.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" charcode: 1.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" collection: 1.14.11 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -19,25 +21,27 @@ dependencies: file: 5.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" intl: 0.16.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" json_rpc_2: 2.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + matcher: 0.12.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" meta: 1.1.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" path: 1.6.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" pub_semver: 1.4.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" source_span: 1.5.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" stack_trace: 1.9.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" stream_channel: 2.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + sync_http: 0.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" term_glyph: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" typed_data: 1.1.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vector_math: 2.0.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vm_service_client: 0.2.6+2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web_socket_channel: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + webdriver: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" dev_dependencies: test: 1.9.4 analyzer: 0.38.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - args: 1.5.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" boolean_selector: 1.0.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - coverage: 0.13.3+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + coverage: 0.13.3+3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" csslib: 0.16.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" front_end: 0.1.27 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" glob: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -49,7 +53,6 @@ dev_dependencies: js: 0.6.1+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" kernel: 0.3.27 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" logging: 0.11.3+2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - matcher: 0.12.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" mime: 0.9.6+3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" multi_server_socket: 1.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" node_interop: 1.0.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -79,4 +82,4 @@ builders: flutter: uses-material-design: true -# PUBSPEC CHECKSUM: f2a9 +# PUBSPEC CHECKSUM: cd51 diff --git a/dev/integration_tests/external_ui/pubspec.yaml b/dev/integration_tests/external_ui/pubspec.yaml index 7b8916acc0..76aa9e3bd1 100644 --- a/dev/integration_tests/external_ui/pubspec.yaml +++ b/dev/integration_tests/external_ui/pubspec.yaml @@ -13,13 +13,14 @@ dependencies: test: 1.9.4 analyzer: 0.38.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + archive: 2.0.11 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" args: 1.5.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" async: 2.4.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" boolean_selector: 1.0.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" charcode: 1.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" collection: 1.14.11 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" convert: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - coverage: 0.13.3+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + coverage: 0.13.3+3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" crypto: 2.1.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" csslib: 0.16.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" file: 5.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -58,6 +59,7 @@ dependencies: stack_trace: 1.9.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" stream_channel: 2.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" string_scanner: 1.0.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + sync_http: 0.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" term_glyph: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" test_api: 0.2.11 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" test_core: 0.2.15 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -67,9 +69,10 @@ dependencies: vm_service_client: 0.2.6+2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" watcher: 0.9.7+13 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web_socket_channel: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + webdriver: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" yaml: 2.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" flutter: uses-material-design: true -# PUBSPEC CHECKSUM: f2a9 +# PUBSPEC CHECKSUM: cd51 diff --git a/dev/integration_tests/flavors/pubspec.yaml b/dev/integration_tests/flavors/pubspec.yaml index 864e366654..d9c47b3588 100644 --- a/dev/integration_tests/flavors/pubspec.yaml +++ b/dev/integration_tests/flavors/pubspec.yaml @@ -13,13 +13,14 @@ dependencies: test: 1.9.4 analyzer: 0.38.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + archive: 2.0.11 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" args: 1.5.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" async: 2.4.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" boolean_selector: 1.0.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" charcode: 1.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" collection: 1.14.11 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" convert: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - coverage: 0.13.3+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + coverage: 0.13.3+3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" crypto: 2.1.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" csslib: 0.16.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" file: 5.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -58,6 +59,7 @@ dependencies: stack_trace: 1.9.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" stream_channel: 2.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" string_scanner: 1.0.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + sync_http: 0.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" term_glyph: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" test_api: 0.2.11 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" test_core: 0.2.15 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -67,9 +69,10 @@ dependencies: vm_service_client: 0.2.6+2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" watcher: 0.9.7+13 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web_socket_channel: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + webdriver: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" yaml: 2.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" flutter: uses-material-design: true -# PUBSPEC CHECKSUM: f2a9 +# PUBSPEC CHECKSUM: cd51 diff --git a/dev/integration_tests/flutter_driver_screenshot_test/pubspec.yaml b/dev/integration_tests/flutter_driver_screenshot_test/pubspec.yaml index 8ae3e37818..3777597f69 100644 --- a/dev/integration_tests/flutter_driver_screenshot_test/pubspec.yaml +++ b/dev/integration_tests/flutter_driver_screenshot_test/pubspec.yaml @@ -9,9 +9,11 @@ dependencies: sdk: flutter flutter_driver: sdk: flutter - cupertino_icons: 0.1.2 - device_info: 0.4.1+2 + cupertino_icons: 0.1.3 + device_info: 0.4.1+4 + archive: 2.0.11 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + args: 1.5.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" async: 2.4.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" charcode: 1.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" collection: 1.14.11 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -20,25 +22,27 @@ dependencies: file: 5.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" intl: 0.16.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" json_rpc_2: 2.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + matcher: 0.12.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" meta: 1.1.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" path: 1.6.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" pub_semver: 1.4.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" source_span: 1.5.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" stack_trace: 1.9.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" stream_channel: 2.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + sync_http: 0.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" term_glyph: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" typed_data: 1.1.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vector_math: 2.0.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vm_service_client: 0.2.6+2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web_socket_channel: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + webdriver: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" dev_dependencies: test: 1.9.4 analyzer: 0.38.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - args: 1.5.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" boolean_selector: 1.0.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - coverage: 0.13.3+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + coverage: 0.13.3+3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" csslib: 0.16.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" front_end: 0.1.27 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" glob: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -50,7 +54,6 @@ dev_dependencies: js: 0.6.1+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" kernel: 0.3.27 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" logging: 0.11.3+2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - matcher: 0.12.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" mime: 0.9.6+3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" multi_server_socket: 1.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" node_interop: 1.0.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -78,4 +81,4 @@ flutter: assets: - assets/ -# PUBSPEC CHECKSUM: e877 +# PUBSPEC CHECKSUM: 8022 diff --git a/dev/integration_tests/image_loading/pubspec.yaml b/dev/integration_tests/image_loading/pubspec.yaml index 9c2ea370ad..b6ecac1a10 100644 --- a/dev/integration_tests/image_loading/pubspec.yaml +++ b/dev/integration_tests/image_loading/pubspec.yaml @@ -14,7 +14,7 @@ dependencies: charcode: 1.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" collection: 1.14.11 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" convert: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - coverage: 0.13.3+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + coverage: 0.13.3+3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" crypto: 2.1.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" csslib: 0.16.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" front_end: 0.1.27 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -63,4 +63,4 @@ dependencies: flutter: uses-material-design: true -# PUBSPEC CHECKSUM: a6c7 +# PUBSPEC CHECKSUM: fcc9 diff --git a/dev/integration_tests/ios_add2app/flutterapp/pubspec.yaml b/dev/integration_tests/ios_add2app/flutterapp/pubspec.yaml index a58087384e..3320ce684c 100644 --- a/dev/integration_tests/ios_add2app/flutterapp/pubspec.yaml +++ b/dev/integration_tests/ios_add2app/flutterapp/pubspec.yaml @@ -22,7 +22,7 @@ dependencies: # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: 0.1.2 + cupertino_icons: 0.1.3 collection: 1.14.11 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" meta: 1.1.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -105,4 +105,4 @@ flutter: androidPackage: com.example.iosadd2appflutter iosBundleIdentifier: com.example.iosAdd2appFlutter -# PUBSPEC CHECKSUM: 712e +# PUBSPEC CHECKSUM: 6e2f diff --git a/dev/integration_tests/platform_interaction/pubspec.yaml b/dev/integration_tests/platform_interaction/pubspec.yaml index dcc209fe15..b2d335cc6f 100644 --- a/dev/integration_tests/platform_interaction/pubspec.yaml +++ b/dev/integration_tests/platform_interaction/pubspec.yaml @@ -13,13 +13,14 @@ dependencies: test: 1.9.4 analyzer: 0.38.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + archive: 2.0.11 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" args: 1.5.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" async: 2.4.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" boolean_selector: 1.0.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" charcode: 1.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" collection: 1.14.11 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" convert: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - coverage: 0.13.3+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + coverage: 0.13.3+3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" crypto: 2.1.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" csslib: 0.16.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" file: 5.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -58,6 +59,7 @@ dependencies: stack_trace: 1.9.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" stream_channel: 2.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" string_scanner: 1.0.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + sync_http: 0.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" term_glyph: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" test_api: 0.2.11 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" test_core: 0.2.15 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -67,9 +69,10 @@ dependencies: vm_service_client: 0.2.6+2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" watcher: 0.9.7+13 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web_socket_channel: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + webdriver: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" yaml: 2.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" flutter: uses-material-design: true -# PUBSPEC CHECKSUM: f2a9 +# PUBSPEC CHECKSUM: cd51 diff --git a/dev/integration_tests/release_smoke_test/pubspec.yaml b/dev/integration_tests/release_smoke_test/pubspec.yaml index 3a95f02118..828f1f52dc 100644 --- a/dev/integration_tests/release_smoke_test/pubspec.yaml +++ b/dev/integration_tests/release_smoke_test/pubspec.yaml @@ -17,7 +17,7 @@ dev_dependencies: flutter_test: sdk: flutter - e2e: 0.2.1+1 + e2e: 0.2.2+3 archive: 2.0.11 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" args: 1.5.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -40,4 +40,4 @@ dev_dependencies: test_api: 0.2.11 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" xml: 3.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" -# PUBSPEC CHECKSUM: b92d +# PUBSPEC CHECKSUM: b430 diff --git a/dev/integration_tests/ui/pubspec.yaml b/dev/integration_tests/ui/pubspec.yaml index a530981703..9bc9264d62 100644 --- a/dev/integration_tests/ui/pubspec.yaml +++ b/dev/integration_tests/ui/pubspec.yaml @@ -21,7 +21,7 @@ dependencies: charcode: 1.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" collection: 1.14.11 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" convert: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - coverage: 0.13.3+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + coverage: 0.13.3+3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" crypto: 2.1.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" csslib: 0.16.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" file: 5.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -61,6 +61,7 @@ dependencies: stack_trace: 1.9.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" stream_channel: 2.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" string_scanner: 1.0.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + sync_http: 0.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" term_glyph: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" test_core: 0.2.15 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" typed_data: 1.1.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -69,6 +70,7 @@ dependencies: vm_service_client: 0.2.6+2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" watcher: 0.9.7+13 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web_socket_channel: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + webdriver: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" xml: 3.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" yaml: 2.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -82,4 +84,4 @@ dev_dependencies: flutter: uses-material-design: true -# PUBSPEC CHECKSUM: 1cf0 +# PUBSPEC CHECKSUM: d238 diff --git a/dev/snippets/pubspec.yaml b/dev/snippets/pubspec.yaml index 6aade2fb72..6377b50cf0 100644 --- a/dev/snippets/pubspec.yaml +++ b/dev/snippets/pubspec.yaml @@ -47,7 +47,7 @@ dev_dependencies: test: 1.9.4 boolean_selector: 1.0.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - coverage: 0.13.3+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + coverage: 0.13.3+3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" http: 0.12.0+2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" http_multi_server: 2.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" http_parser: 3.1.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -101,4 +101,4 @@ executables: vm_service_client: 0.2.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web_socket_channel: 1.0.9 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" -# PUBSPEC CHECKSUM: a7d1 +# PUBSPEC CHECKSUM: fdd3 diff --git a/dev/tools/pubspec.yaml b/dev/tools/pubspec.yaml index 09f0177fcc..6925b5c0f6 100644 --- a/dev/tools/pubspec.yaml +++ b/dev/tools/pubspec.yaml @@ -35,7 +35,7 @@ dev_dependencies: analyzer: 0.38.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" boolean_selector: 1.0.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - coverage: 0.13.3+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + coverage: 0.13.3+3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" csslib: 0.16.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" front_end: 0.1.27 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" glob: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -69,4 +69,4 @@ dev_dependencies: web_socket_channel: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" yaml: 2.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" -# PUBSPEC CHECKSUM: 3590 +# PUBSPEC CHECKSUM: 1892 diff --git a/examples/catalog/pubspec.yaml b/examples/catalog/pubspec.yaml index 160d041770..69a470c36b 100644 --- a/examples/catalog/pubspec.yaml +++ b/examples/catalog/pubspec.yaml @@ -29,7 +29,7 @@ dev_dependencies: boolean_selector: 1.0.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" charcode: 1.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" convert: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - coverage: 0.13.3+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + coverage: 0.13.3+3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" crypto: 2.1.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" csslib: 0.16.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" file: 5.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -69,6 +69,7 @@ dev_dependencies: stack_trace: 1.9.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" stream_channel: 2.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" string_scanner: 1.0.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + sync_http: 0.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" term_glyph: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" test_api: 0.2.11 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" test_core: 0.2.15 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -76,10 +77,11 @@ dev_dependencies: vm_service_client: 0.2.6+2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" watcher: 0.9.7+13 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web_socket_channel: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + webdriver: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" xml: 3.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" yaml: 2.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" flutter: uses-material-design: true -# PUBSPEC CHECKSUM: 1cf0 +# PUBSPEC CHECKSUM: d238 diff --git a/examples/flutter_gallery/pubspec.yaml b/examples/flutter_gallery/pubspec.yaml index fa56e6f497..336974b427 100644 --- a/examples/flutter_gallery/pubspec.yaml +++ b/examples/flutter_gallery/pubspec.yaml @@ -8,13 +8,13 @@ dependencies: flutter: sdk: flutter collection: 1.14.11 - device_info: 0.4.1+2 + device_info: 0.4.1+4 intl: 0.16.0 - connectivity: 0.4.5+6 + connectivity: 0.4.6+1 string_scanner: 1.0.5 url_launcher: 5.2.7 - cupertino_icons: 0.1.2 - video_player: 0.10.3+3 + cupertino_icons: 0.1.3 + video_player: 0.10.4+2 scoped_model: 1.0.1 shrine_images: 1.1.2 @@ -25,11 +25,13 @@ dependencies: charcode: 1.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" meta: 1.1.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" path: 1.6.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + plugin_platform_interface: 1.0.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" source_span: 1.5.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" term_glyph: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" typed_data: 1.1.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - url_launcher_platform_interface: 1.0.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + url_launcher_platform_interface: 1.0.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vector_math: 2.0.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + video_player_platform_interface: 1.0.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" dev_dependencies: flutter_test: @@ -46,7 +48,7 @@ dev_dependencies: async: 2.4.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" boolean_selector: 1.0.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" convert: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - coverage: 0.13.3+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + coverage: 0.13.3+3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" crypto: 2.1.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" csslib: 0.16.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" file: 5.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -85,12 +87,14 @@ dev_dependencies: source_maps: 0.10.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" stack_trace: 1.9.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" stream_channel: 2.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + sync_http: 0.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" test_api: 0.2.11 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" test_core: 0.2.15 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vm_service: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vm_service_client: 0.2.6+2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" watcher: 0.9.7+13 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web_socket_channel: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + webdriver: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" xml: 3.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" yaml: 2.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -265,4 +269,4 @@ flutter: - asset: packages/flutter_gallery_assets/fonts/merriweather/Merriweather-Regular.ttf - asset: packages/flutter_gallery_assets/fonts/merriweather/Merriweather-Light.ttf -# PUBSPEC CHECKSUM: ab21 +# PUBSPEC CHECKSUM: fd51 diff --git a/examples/flutter_gallery/test_driver/scroll_perf_web.dart b/examples/flutter_gallery/test_driver/scroll_perf_web.dart new file mode 100644 index 0000000000..1df1be8370 --- /dev/null +++ b/examples/flutter_gallery/test_driver/scroll_perf_web.dart @@ -0,0 +1,12 @@ +// Copyright 2014 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter_driver/driver_extension.dart'; +import 'package:flutter_gallery/gallery/app.dart' show GalleryApp; +import 'package:flutter/material.dart'; + +void main() { + enableFlutterDriverExtension(); + runApp(const GalleryApp(testMode: true)); +} diff --git a/examples/flutter_gallery/test_driver/scroll_perf_web_test.dart b/examples/flutter_gallery/test_driver/scroll_perf_web_test.dart new file mode 100644 index 0000000000..485bf7cba8 --- /dev/null +++ b/examples/flutter_gallery/test_driver/scroll_perf_web_test.dart @@ -0,0 +1,48 @@ +// Copyright 2014 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'dart:async'; + +import 'package:flutter_driver/flutter_driver.dart'; +import 'package:test/test.dart' hide TypeMatcher, isInstanceOf; + +void main() { + group('scrolling performance test', () { + FlutterDriver driver; + + setUpAll(() async { + driver = await FlutterDriver.connect(browser: true); + }); + + tearDownAll(() async { + if (driver != null) + driver.close(); + }); + + test('measure', () async { + final Timeline timeline = await driver.traceAction(() async { + await driver.tap(find.text('Material')); + + final SerializableFinder demoList = find.byValueKey('GalleryDemoList'); + + // TODO(eseidel): These are very artificial scrolls, we should use better + // https://github.com/flutter/flutter/issues/3316 + // Scroll down + for (int i = 0; i < 5; i++) { + await driver.scroll(demoList, 0.0, -300.0, const Duration(milliseconds: 300)); + await Future.delayed(const Duration(milliseconds: 500)); + } + + // Scroll up + for (int i = 0; i < 5; i++) { + await driver.scroll(demoList, 0.0, 300.0, const Duration(milliseconds: 300)); + await Future.delayed(const Duration(milliseconds: 500)); + } + }); + + TimelineSummary.summarize(timeline) + ..writeTimelineToFile('home_scroll_perf', pretty: true); + }); + }); +} diff --git a/examples/image_list/pubspec.yaml b/examples/image_list/pubspec.yaml index bf3e2776ba..dfe15eae12 100644 --- a/examples/image_list/pubspec.yaml +++ b/examples/image_list/pubspec.yaml @@ -12,7 +12,7 @@ dependencies: # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: 0.1.2 + cupertino_icons: 0.1.3 collection: 1.14.11 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" meta: 1.1.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -60,4 +60,4 @@ flutter: assets: - images/coast.jpg -# PUBSPEC CHECKSUM: 712e +# PUBSPEC CHECKSUM: 6e2f diff --git a/examples/platform_channel/pubspec.yaml b/examples/platform_channel/pubspec.yaml index d6b3b729f1..0cad345a2d 100644 --- a/examples/platform_channel/pubspec.yaml +++ b/examples/platform_channel/pubspec.yaml @@ -27,7 +27,7 @@ dev_dependencies: boolean_selector: 1.0.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" charcode: 1.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" convert: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - coverage: 0.13.3+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + coverage: 0.13.3+3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" crypto: 2.1.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" csslib: 0.16.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" file: 5.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -68,6 +68,7 @@ dev_dependencies: stack_trace: 1.9.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" stream_channel: 2.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" string_scanner: 1.0.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + sync_http: 0.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" term_glyph: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" test_api: 0.2.11 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" test_core: 0.2.15 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -75,10 +76,11 @@ dev_dependencies: vm_service_client: 0.2.6+2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" watcher: 0.9.7+13 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web_socket_channel: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + webdriver: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" xml: 3.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" yaml: 2.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" flutter: uses-material-design: true -# PUBSPEC CHECKSUM: 1cf0 +# PUBSPEC CHECKSUM: d238 diff --git a/examples/platform_channel_swift/pubspec.yaml b/examples/platform_channel_swift/pubspec.yaml index 08a357f241..481b94fb08 100644 --- a/examples/platform_channel_swift/pubspec.yaml +++ b/examples/platform_channel_swift/pubspec.yaml @@ -27,7 +27,7 @@ dev_dependencies: boolean_selector: 1.0.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" charcode: 1.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" convert: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - coverage: 0.13.3+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + coverage: 0.13.3+3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" crypto: 2.1.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" csslib: 0.16.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" file: 5.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -68,6 +68,7 @@ dev_dependencies: stack_trace: 1.9.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" stream_channel: 2.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" string_scanner: 1.0.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + sync_http: 0.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" term_glyph: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" test_api: 0.2.11 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" test_core: 0.2.15 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -75,10 +76,11 @@ dev_dependencies: vm_service_client: 0.2.6+2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" watcher: 0.9.7+13 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web_socket_channel: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + webdriver: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" xml: 3.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" yaml: 2.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" flutter: uses-material-design: true -# PUBSPEC CHECKSUM: 1cf0 +# PUBSPEC CHECKSUM: d238 diff --git a/examples/stocks/pubspec.yaml b/examples/stocks/pubspec.yaml index 485bda33ae..4a49d6fd31 100644 --- a/examples/stocks/pubspec.yaml +++ b/examples/stocks/pubspec.yaml @@ -54,7 +54,7 @@ dev_dependencies: archive: 2.0.11 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" boolean_selector: 1.0.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - coverage: 0.13.3+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + coverage: 0.13.3+3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" file: 5.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" http_multi_server: 2.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" image: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -76,14 +76,16 @@ dev_dependencies: source_maps: 0.10.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" stack_trace: 1.9.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" stream_channel: 2.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + sync_http: 0.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" test_api: 0.2.11 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" test_core: 0.2.15 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vm_service: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vm_service_client: 0.2.6+2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web_socket_channel: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + webdriver: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" xml: 3.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" flutter: uses-material-design: true -# PUBSPEC CHECKSUM: e110 +# PUBSPEC CHECKSUM: 3d57 diff --git a/packages/flutter_driver/lib/src/driver/driver.dart b/packages/flutter_driver/lib/src/driver/driver.dart index d5a48c2660..affd5f1d2c 100644 --- a/packages/flutter_driver/lib/src/driver/driver.dart +++ b/packages/flutter_driver/lib/src/driver/driver.dart @@ -3,23 +3,15 @@ // found in the LICENSE file. import 'dart:async'; -import 'dart:convert'; -import 'dart:io'; -import 'package:file/file.dart' as f; -import 'package:fuchsia_remote_debug_protocol/fuchsia_remote_debug_protocol.dart' as fuchsia; -import 'package:json_rpc_2/error_code.dart' as error_code; import 'package:json_rpc_2/json_rpc_2.dart' as rpc; import 'package:meta/meta.dart'; -import 'package:path/path.dart' as p; import 'package:vm_service_client/vm_service_client.dart'; -import 'package:web_socket_channel/io.dart'; import '../common/diagnostics_tree.dart'; import '../common/error.dart'; import '../common/find.dart'; import '../common/frame_sync.dart'; -import '../common/fuchsia_compat.dart'; import '../common/geometry.dart'; import '../common/gesture.dart'; import '../common/health.dart'; @@ -30,8 +22,12 @@ import '../common/request_data.dart'; import '../common/semantics.dart'; import '../common/text.dart'; import '../common/wait.dart'; -import 'common.dart'; import 'timeline.dart'; +import 'vmservice_driver.dart'; +import 'web_driver.dart'; + +export 'vmservice_driver.dart'; +export 'web_driver.dart'; /// Timeline stream identifier. enum TimelineStream { @@ -63,52 +59,11 @@ enum TimelineStream { vm, } -const List _defaultStreams = [TimelineStream.all]; - /// How long to wait before showing a message saying that /// things seem to be taking a long time. @visibleForTesting const Duration kUnusuallyLongTimeout = Duration(seconds: 5); -/// The amount of time we wait prior to making the next attempt to connect to -/// the VM service. -const Duration _kPauseBetweenReconnectAttempts = Duration(seconds: 1); - -// See https://github.com/dart-lang/sdk/blob/master/runtime/vm/timeline.cc#L32 -String _timelineStreamsToString(List streams) { - final String contents = streams.map((TimelineStream stream) { - switch (stream) { - case TimelineStream.all: return 'all'; - case TimelineStream.api: return 'API'; - case TimelineStream.compiler: return 'Compiler'; - case TimelineStream.dart: return 'Dart'; - case TimelineStream.debugger: return 'Debugger'; - case TimelineStream.embedder: return 'Embedder'; - case TimelineStream.gc: return 'GC'; - case TimelineStream.isolate: return 'Isolate'; - case TimelineStream.vm: return 'VM'; - default: - throw 'Unknown timeline stream $stream'; - } - }).join(', '); - return '[$contents]'; -} - -void _log(String message) { - driverLog('FlutterDriver', message); -} - -Future _warnIfSlow({ - @required Future future, - @required Duration timeout, - @required String message, -}) { - assert(future != null); - assert(timeout != null); - assert(message != null); - return future..timeout(timeout, onTimeout: () { _log(message); return null; }); -} - /// A convenient accessor to frequently used finders. /// /// Examples: @@ -125,43 +80,27 @@ const CommonFinders find = CommonFinders._(); typedef EvaluatorFunction = dynamic Function(); /// Drives a Flutter Application running in another process. -class FlutterDriver { - /// Creates a driver that uses a connection provided by the given - /// [serviceClient], [_peer] and [appIsolate]. +abstract class FlutterDriver { + /// Default constructor. @visibleForTesting - FlutterDriver.connectedTo( - this.serviceClient, - this._peer, - this.appIsolate, { - bool printCommunication = false, - bool logCommunicationToFile = true, - }) : _printCommunication = printCommunication, - _logCommunicationToFile = logCommunicationToFile, - _driverId = _nextDriverId++; + FlutterDriver(); - static const String _flutterExtensionMethodName = 'ext.flutter.driver'; - static const String _setVMTimelineFlagsMethodName = 'setVMTimelineFlags'; - static const String _getVMTimelineMethodName = 'getVMTimeline'; - static const String _clearVMTimelineMethodName = 'clearVMTimeline'; - static const String _collectAllGarbageMethodName = '_collectAllGarbage'; - - static int _nextDriverId = 0; - - // The additional blank line in the beginning is for _log.warning. - static const String _kDebugWarning = ''' - -┏╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍┓ -┇ ⚠ THIS BENCHMARK IS BEING RUN IN DEBUG MODE ⚠ ┇ -┡╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍┦ -│ │ -│ Numbers obtained from a benchmark while asserts are │ -│ enabled will not accurately reflect the performance │ -│ that will be experienced by end users using release ╎ -│ builds. Benchmarks should be run using this command ┆ -│ line: flutter drive --profile test_perf.dart ┊ -│ ┊ -└─────────────────────────────────────────────────╌┄┈ 🐢 -'''; + /// Creates a driver that uses a connection provided by either the combination + /// of [webConnection] and [browser], or the combination of [serviceClient], + /// [peer] and [appIsolate] + @visibleForTesting + factory FlutterDriver.connectedTo({ + FlutterWebConnection webConnection, + Browser browser, + VMServiceClient serviceClient, + rpc.Peer peer, + VMIsolate appIsolate, + }) { + if (webConnection != null && browser != null) { + return WebFlutterDriver.connectedTo(webConnection, browser); + } + return VMServiceFlutterDriver.connectedTo(serviceClient, peer, appIsolate); + } /// Connects to a Flutter application. /// @@ -188,6 +127,10 @@ class FlutterDriver { /// `isolateNumber` is set, as this is already enough information to connect /// to an isolate. /// + /// `browser` specifies which FlutterDriver implementation to use. If not + /// speicifed or set to false, [VMServiceFlutterDriver] implementation + /// will be used. Otherwise, [WebFlutterDriver] implementation will be used. + /// /// The return value is a future. This method never times out, though it may /// fail (completing with an error). A timeout can be applied by the caller /// using [Future.timeout] if necessary. @@ -197,308 +140,64 @@ class FlutterDriver { bool logCommunicationToFile = true, int isolateNumber, Pattern fuchsiaModuleTarget, + bool browser = false, + Duration timeout, }) async { - // If running on a Fuchsia device, connect to the first isolate whose name - // matches FUCHSIA_MODULE_TARGET. - // - // If the user has already supplied an isolate number/URL to the Dart VM - // service, then this won't be run as it is unnecessary. - if (Platform.isFuchsia && isolateNumber == null) { - // On Fuchsia stderr/stdout appear to have issues working correctly, - // so we work around the issue by using print directly. - // TODO(awdavies): Fix Dart or Fuchsia to not need this workaround. - driverLog = (String source, String message) { - print('$source: $message'); - }; - fuchsiaModuleTarget ??= Platform.environment['FUCHSIA_MODULE_TARGET']; - if (fuchsiaModuleTarget == null) { - throw DriverError( - 'No Fuchsia module target has been specified.\n' - 'Please make sure to specify the FUCHSIA_MODULE_TARGET ' - 'environment variable.' - ); - } - final fuchsia.FuchsiaRemoteConnection fuchsiaConnection = - await FuchsiaCompat.connect(); - final List refs = - await fuchsiaConnection.getMainIsolatesByPattern(fuchsiaModuleTarget); - final fuchsia.IsolateRef ref = refs.first; - isolateNumber = ref.number; - dartVmServiceUrl = ref.dartVm.uri.toString(); - await fuchsiaConnection.stop(); - FuchsiaCompat.cleanup(); + + if (browser) { + return WebFlutterDriver.connectWeb(hostUrl: dartVmServiceUrl, timeout: timeout); } - - dartVmServiceUrl ??= Platform.environment['VM_SERVICE_URL']; - - if (dartVmServiceUrl == null) { - throw DriverError( - 'Could not determine URL to connect to application.\n' - 'Either the VM_SERVICE_URL environment variable should be set, or an explicit ' - 'URL should be provided to the FlutterDriver.connect() method.' - ); - } - - // Connect to Dart VM services - _log('Connecting to Flutter application at $dartVmServiceUrl'); - final VMServiceClientConnection connection = - await vmServiceConnectFunction(dartVmServiceUrl); - final VMServiceClient client = connection.client; - final VM vm = await client.getVM(); - final VMIsolateRef isolateRef = isolateNumber == - null ? vm.isolates.first : - vm.isolates.firstWhere( - (VMIsolateRef isolate) => isolate.number == isolateNumber); - _log('Isolate found with number: ${isolateRef.number}'); - - VMIsolate isolate = await isolateRef.loadRunnable(); - - // TODO(yjbanov): vm_service_client does not support "None" pause event yet. - // It is currently reported as null, but we cannot rely on it because - // eventually the event will be reported as a non-null object. For now, - // list all the events we know about. Later we'll check for "None" event - // explicitly. - // - // See: https://github.com/dart-lang/vm_service_client/issues/4 - if (isolate.pauseEvent is! VMPauseStartEvent && - isolate.pauseEvent is! VMPauseExitEvent && - isolate.pauseEvent is! VMPauseBreakpointEvent && - isolate.pauseEvent is! VMPauseExceptionEvent && - isolate.pauseEvent is! VMPauseInterruptedEvent && - isolate.pauseEvent is! VMResumeEvent) { - isolate = await isolateRef.loadRunnable(); - } - - final FlutterDriver driver = FlutterDriver.connectedTo( - client, connection.peer, isolate, - printCommunication: printCommunication, - logCommunicationToFile: logCommunicationToFile, + return VMServiceFlutterDriver.connect( + dartVmServiceUrl: dartVmServiceUrl, + printCommunication: printCommunication, + logCommunicationToFile: logCommunicationToFile, + isolateNumber: isolateNumber, + fuchsiaModuleTarget: fuchsiaModuleTarget, ); - - driver._dartVmReconnectUrl = dartVmServiceUrl; - - // Attempts to resume the isolate, but does not crash if it fails because - // the isolate is already resumed. There could be a race with other tools, - // such as a debugger, any of which could have resumed the isolate. - Future resumeLeniently() { - _log('Attempting to resume isolate...'); - return isolate.resume().catchError((dynamic e) { - const int vmMustBePausedCode = 101; - if (e is rpc.RpcException && e.code == vmMustBePausedCode) { - // No biggie; something else must have resumed the isolate - _log( - 'Attempted to resume an already resumed isolate. This may happen ' - 'when we lose a race with another tool (usually a debugger) that ' - 'is connected to the same isolate.' - ); - } else { - // Failed to resume due to another reason. Fail hard. - throw e; - } - }); - } - - /// Waits for a signal from the VM service that the extension is registered. - /// Returns [_flutterExtensionMethodName] - Future waitForServiceExtension() { - return isolate.onExtensionAdded.firstWhere((String extension) { - return extension == _flutterExtensionMethodName; - }); - } - - /// Tells the Dart VM Service to notify us about "Isolate" events. - /// - /// This is a workaround for an issue in package:vm_service_client, which - /// subscribes to the "Isolate" stream lazily upon subscription, which - /// results in lost events. - /// - /// Details: https://github.com/dart-lang/vm_service_client/issues/17 - Future enableIsolateStreams() async { - await connection.peer.sendRequest('streamListen', { - 'streamId': 'Isolate', - }); - } - - // Attempt to resume isolate if it was paused - if (isolate.pauseEvent is VMPauseStartEvent) { - _log('Isolate is paused at start.'); - - // If the isolate is paused at the start, e.g. via the --start-paused - // option, then the VM service extension is not registered yet. Wait for - // it to be registered. - await enableIsolateStreams(); - final Future whenServiceExtensionReady = waitForServiceExtension(); - final Future whenResumed = resumeLeniently(); - await whenResumed; - - _log('Waiting for service extension...'); - // We will never receive the extension event if the user does not - // register it. If that happens, show a message but continue waiting. - await _warnIfSlow( - future: whenServiceExtensionReady, - timeout: kUnusuallyLongTimeout, - message: 'Flutter Driver extension is taking a long time to become available. ' - 'Ensure your test app (often "lib/main.dart") imports ' - '"package:flutter_driver/driver_extension.dart" and ' - 'calls enableFlutterDriverExtension() as the first call in main().', - ); - } else if (isolate.pauseEvent is VMPauseExitEvent || - isolate.pauseEvent is VMPauseBreakpointEvent || - isolate.pauseEvent is VMPauseExceptionEvent || - isolate.pauseEvent is VMPauseInterruptedEvent) { - // If the isolate is paused for any other reason, assume the extension is - // already there. - _log('Isolate is paused mid-flight.'); - await resumeLeniently(); - } else if (isolate.pauseEvent is VMResumeEvent) { - _log('Isolate is not paused. Assuming application is ready.'); - } else { - _log( - 'Unknown pause event type ${isolate.pauseEvent.runtimeType}. ' - 'Assuming application is ready.' - ); - } - - // Invoked checkHealth and try to fix delays in the registration of Service - // extensions - Future checkHealth() async { - try { - // At this point the service extension must be installed. Verify it. - return await driver.checkHealth(); - } on rpc.RpcException catch (e) { - if (e.code != error_code.METHOD_NOT_FOUND) { - rethrow; - } - _log('Check Health failed, try to wait for the service extensions to be registered.'); - await enableIsolateStreams(); - await waitForServiceExtension(); - return driver.checkHealth(); - } - } - - final Health health = await checkHealth(); - if (health.status != HealthStatus.ok) { - await client.close(); - throw DriverError('Flutter application health check failed.'); - } - - _log('Connected to Flutter application.'); - return driver; } - /// The unique ID of this driver instance. - final int _driverId; - - /// Client connected to the Dart VM running the Flutter application + /// Sends [command] to the Flutter Driver extensions. + /// This must be implemented by subclass. /// - /// You can use [VMServiceClient] to check VM version, flags and get - /// notified when a new isolate has been instantiated. That could be - /// useful if your application spawns multiple isolates that you - /// would like to instrument. - final VMServiceClient serviceClient; - - /// JSON-RPC client useful for sending raw JSON requests. - rpc.Peer _peer; - - String _dartVmReconnectUrl; - - Future _restorePeerConnectionIfNeeded() async { - if (!_peer.isClosed || _dartVmReconnectUrl == null) { - return; - } - _log('Peer connection is closed! Trying to restore the connection...'); - final String webSocketUrl = _getWebSocketUrl(_dartVmReconnectUrl); - final WebSocket ws = await WebSocket.connect(webSocketUrl); - ws.done.whenComplete(() => _checkCloseCode(ws)); - _peer = rpc.Peer( - IOWebSocketChannel(ws).cast(), - onUnhandledError: _unhandledJsonRpcError, - )..listen(); - } - - /// The main isolate hosting the Flutter application. + /// See also: /// - /// If you used the [registerExtension] API to instrument your application, - /// you can use this [VMIsolate] to call these extension methods via - /// [invokeExtension]. - final VMIsolate appIsolate; - - /// Whether to print communication between host and app to `stdout`. - final bool _printCommunication; - - /// Whether to log communication between host and app to `flutter_driver_commands.log`. - final bool _logCommunicationToFile; - - Future> _sendCommand(Command command) async { - Map response; - try { - final Map serialized = command.serialize(); - _logCommunication('>>> $serialized'); - final Future> future = appIsolate.invokeExtension( - _flutterExtensionMethodName, - serialized, - ).then>((Object value) => value as Map); - response = await _warnIfSlow>( - future: future, - timeout: command.timeout ?? kUnusuallyLongTimeout, - message: '${command.kind} message is taking a long time to complete...', - ); - _logCommunication('<<< $response'); - } catch (error, stackTrace) { - throw DriverError( - 'Failed to fulfill ${command.runtimeType} due to remote error', - error, - stackTrace, - ); - } - if (response['isError'] as bool) - throw DriverError('Error in Flutter application: ${response['response']}'); - return response['response'] as Map; - } - - void _logCommunication(String message) { - if (_printCommunication) - _log(message); - if (_logCommunicationToFile) { - final f.File file = fs.file(p.join(testOutputsDirectory, 'flutter_driver_commands_$_driverId.log')); - file.createSync(recursive: true); // no-op if file exists - file.writeAsStringSync('${DateTime.now()} $message\n', mode: f.FileMode.append, flush: true); - } - } + /// * [VMServiceFlutterDriver], which uses vmservice to implement. + /// * [WebFlutterDriver], which uses webdriver to implement. + Future> sendCommand(Command command); /// Checks the status of the Flutter Driver extension. Future checkHealth({ Duration timeout }) async { - return Health.fromJson(await _sendCommand(GetHealth(timeout: timeout))); + return Health.fromJson(await sendCommand(GetHealth(timeout: timeout))); } /// Returns a dump of the render tree. Future getRenderTree({ Duration timeout }) async { - return RenderTree.fromJson(await _sendCommand(GetRenderTree(timeout: timeout))); + return RenderTree.fromJson(await sendCommand(GetRenderTree(timeout: timeout))); } /// Returns a dump of the layer tree. Future getLayerTree({ Duration timeout }) async { - return LayerTree.fromJson(await _sendCommand(GetLayerTree(timeout: timeout))); + return LayerTree.fromJson(await sendCommand(GetLayerTree(timeout: timeout))); } /// Taps at the center of the widget located by [finder]. Future tap(SerializableFinder finder, { Duration timeout }) async { - await _sendCommand(Tap(finder, timeout: timeout)); + await sendCommand(Tap(finder, timeout: timeout)); } /// Waits until [finder] locates the target. Future waitFor(SerializableFinder finder, { Duration timeout }) async { - await _sendCommand(WaitFor(finder, timeout: timeout)); + await sendCommand(WaitFor(finder, timeout: timeout)); } /// Waits until [finder] can no longer locate the target. Future waitForAbsent(SerializableFinder finder, { Duration timeout }) async { - await _sendCommand(WaitForAbsent(finder, timeout: timeout)); + await sendCommand(WaitForAbsent(finder, timeout: timeout)); } /// Waits until the given [waitCondition] is satisfied. Future waitForCondition(SerializableWaitCondition waitCondition, {Duration timeout}) async { - await _sendCommand(WaitForCondition(waitCondition, timeout: timeout)); + await sendCommand(WaitForCondition(waitCondition, timeout: timeout)); } /// Waits until there are no more transient callbacks in the queue. @@ -506,20 +205,22 @@ class FlutterDriver { /// Use this method when you need to wait for the moment when the application /// becomes "stable", for example, prior to taking a [screenshot]. Future waitUntilNoTransientCallbacks({ Duration timeout }) async { - await _sendCommand(WaitForCondition(const NoTransientCallbacks(), timeout: timeout)); + await sendCommand(WaitForCondition(const NoTransientCallbacks(), timeout: timeout)); } /// Waits until the next [Window.onReportTimings] is called. /// /// Use this method to wait for the first frame to be rasterized during the /// app launch. + /// + /// Throws [UnimplementedError] on [WebFlutterDriver] instances. Future waitUntilFirstFrameRasterized() async { - await _sendCommand(const WaitForCondition(FirstFrameRasterized())); + await sendCommand(const WaitForCondition(FirstFrameRasterized())); } Future _getOffset(SerializableFinder finder, OffsetType type, { Duration timeout }) async { final GetOffset command = GetOffset(finder, type, timeout: timeout); - final GetOffsetResult result = GetOffsetResult.fromJson(await _sendCommand(command)); + final GetOffsetResult result = GetOffsetResult.fromJson(await sendCommand(command)); return DriverOffset(result.dx, result.dy); } @@ -590,7 +291,7 @@ class FlutterDriver { bool includeProperties = true, Duration timeout, }) async { - return _sendCommand(GetDiagnosticsTree( + return sendCommand(GetDiagnosticsTree( finder, DiagnosticsType.renderObject, subtreeDepth: subtreeDepth, @@ -623,7 +324,7 @@ class FlutterDriver { bool includeProperties = true, Duration timeout, }) async { - return _sendCommand(GetDiagnosticsTree( + return sendCommand(GetDiagnosticsTree( finder, DiagnosticsType.widget, subtreeDepth: subtreeDepth, @@ -646,7 +347,7 @@ class FlutterDriver { /// The move events are generated at a given [frequency] in Hz (or events per /// second). It defaults to 60Hz. Future scroll(SerializableFinder finder, double dx, double dy, Duration duration, { int frequency = 60, Duration timeout }) async { - await _sendCommand(Scroll(finder, dx, dy, duration, frequency, timeout: timeout)); + await sendCommand(Scroll(finder, dx, dy, duration, frequency, timeout: timeout)); } /// Scrolls the Scrollable ancestor of the widget located by [finder] @@ -657,7 +358,7 @@ class FlutterDriver { /// then this method may fail because [finder] doesn't actually exist. /// The [scrollUntilVisible] method can be used in this case. Future scrollIntoView(SerializableFinder finder, { double alignment = 0.0, Duration timeout }) async { - await _sendCommand(ScrollIntoView(finder, alignment: alignment, timeout: timeout)); + await sendCommand(ScrollIntoView(finder, alignment: alignment, timeout: timeout)); } /// Repeatedly [scroll] the widget located by [scrollable] by [dxScroll] and @@ -714,7 +415,7 @@ class FlutterDriver { /// Returns the text in the `Text` widget located by [finder]. Future getText(SerializableFinder finder, { Duration timeout }) async { - return GetTextResult.fromJson(await _sendCommand(GetText(finder, timeout: timeout))).text; + return GetTextResult.fromJson(await sendCommand(GetText(finder, timeout: timeout))).text; } /// Enters `text` into the currently focused text input, such as the @@ -750,7 +451,7 @@ class FlutterDriver { /// }); /// ``` Future enterText(String text, { Duration timeout }) async { - await _sendCommand(EnterText(text, timeout: timeout)); + await sendCommand(EnterText(text, timeout: timeout)); } /// Configures text entry emulation. @@ -768,7 +469,7 @@ class FlutterDriver { /// channel will be mocked out. Future setTextEntryEmulation({ @required bool enabled, Duration timeout }) async { assert(enabled != null); - await _sendCommand(SetTextEntryEmulation(enabled, timeout: timeout)); + await sendCommand(SetTextEntryEmulation(enabled, timeout: timeout)); } /// Sends a string and returns a string. @@ -778,7 +479,7 @@ class FlutterDriver { /// callback in [enableFlutterDriverExtension] that can successfully handle /// these requests. Future requestData(String message, { Duration timeout }) async { - return RequestDataResult.fromJson(await _sendCommand(RequestData(message, timeout: timeout))).message; + return RequestDataResult.fromJson(await sendCommand(RequestData(message, timeout: timeout))).message; } /// Turns semantics on or off in the Flutter app under test. @@ -786,7 +487,7 @@ class FlutterDriver { /// Returns true when the call actually changed the state from on to off or /// vice versa. Future setSemantics(bool enabled, { Duration timeout }) async { - final SetSemanticsResult result = SetSemanticsResult.fromJson(await _sendCommand(SetSemantics(enabled, timeout: timeout))); + final SetSemanticsResult result = SetSemanticsResult.fromJson(await sendCommand(SetSemantics(enabled, timeout: timeout))); return result.changedState; } @@ -799,7 +500,7 @@ class FlutterDriver { /// Semantics must be enabled to use this method, either using a platform /// specific shell command or [setSemantics]. Future getSemanticsId(SerializableFinder finder, { Duration timeout }) async { - final Map jsonResponse = await _sendCommand(GetSemanticsId(finder, timeout: timeout)); + final Map jsonResponse = await sendCommand(GetSemanticsId(finder, timeout: timeout)); final GetSemanticsIdResult result = GetSemanticsIdResult.fromJson(jsonResponse); return result.id; } @@ -807,58 +508,54 @@ class FlutterDriver { /// Take a screenshot. /// /// The image will be returned as a PNG. - Future> screenshot() async { - // HACK: this artificial delay here is to deal with a race between the - // driver script and the GPU thread. The issue is that driver API - // synchronizes with the framework based on transient callbacks, which - // are out of sync with the GPU thread. Here's the timeline of events - // in ASCII art: - // - // ------------------------------------------------------------------- - // Without this delay: - // ------------------------------------------------------------------- - // UI : <-- build --> - // GPU : <-- rasterize --> - // Gap : | random | - // Driver: <-- screenshot --> - // - // In the diagram above, the gap is the time between the last driver - // action taken, such as a `tap()`, and the subsequent call to - // `screenshot()`. The gap is random because it is determined by the - // unpredictable network communication between the driver process and - // the application. If this gap is too short, which it typically will - // be, the screenshot is taken before the GPU thread is done - // rasterizing the frame, so the screenshot of the previous frame is - // taken, which is wrong. - // - // ------------------------------------------------------------------- - // With this delay, if we're lucky: - // ------------------------------------------------------------------- - // UI : <-- build --> - // GPU : <-- rasterize --> - // Gap : | 2 seconds or more | - // Driver: <-- screenshot --> - // - // The two-second gap should be long enough for the GPU thread to - // finish rasterizing the frame, but not longer than necessary to keep - // driver tests as fast a possible. - // - // ------------------------------------------------------------------- - // With this delay, if we're not lucky: - // ------------------------------------------------------------------- - // UI : <-- build --> - // GPU : <-- rasterize randomly slow today --> - // Gap : | 2 seconds or more | - // Driver: <-- screenshot --> - // - // In practice, sometimes the device gets really busy for a while and - // even two seconds isn't enough, which means that this is still racy - // and a source of flakes. - await Future.delayed(const Duration(seconds: 2)); - - final Map result = await _peer.sendRequest('_flutter.screenshot') as Map; - return base64.decode(result['screenshot'] as String); - } + /// + /// HACK: There will be a 2-second artificial delay before screenshotting, + /// the delay here is to deal with a race between the driver script and + /// the GPU thread. The issue is that driver API synchronizes with the + /// framework based on transient callbacks, which are out of sync with + /// the GPU thread. Here's the timeline of events in ASCII art: + /// + /// ------------------------------------------------------------------- + /// Without this delay: + /// ------------------------------------------------------------------- + /// UI : <-- build --> + /// GPU : <-- rasterize --> + /// Gap : | random | + /// Driver: <-- screenshot --> + /// + /// In the diagram above, the gap is the time between the last driver + /// action taken, such as a `tap()`, and the subsequent call to + /// `screenshot()`. The gap is random because it is determined by the + /// unpredictable network communication between the driver process and + /// the application. If this gap is too short, which it typically will + /// be, the screenshot is taken before the GPU thread is done + /// rasterizing the frame, so the screenshot of the previous frame is + /// taken, which is wrong. + /// + /// ------------------------------------------------------------------- + /// With this delay, if we're lucky: + /// ------------------------------------------------------------------- + /// UI : <-- build --> + /// GPU : <-- rasterize --> + /// Gap : | 2 seconds or more | + /// Driver: <-- screenshot --> + /// + /// The two-second gap should be long enough for the GPU thread to + /// finish rasterizing the frame, but not longer than necessary to keep + /// driver tests as fast a possible. + /// + /// ------------------------------------------------------------------- + /// With this delay, if we're not lucky: + /// ------------------------------------------------------------------- + /// UI : <-- build --> + /// GPU : <-- rasterize randomly slow today --> + /// Gap : | 2 seconds or more | + /// Driver: <-- screenshot --> + /// + /// In practice, sometimes the device gets really busy for a while and + /// even two seconds isn't enough, which means that this is still racy + /// and a source of flakes. + Future> screenshot(); /// Returns the Flags set in the Dart VM as JSON. /// @@ -879,76 +576,32 @@ class FlutterDriver { /// ] /// /// [getFlagList]: https://github.com/dart-lang/sdk/blob/master/runtime/vm/service/service.md#getflaglist - Future>> getVmFlags() async { - await _restorePeerConnectionIfNeeded(); - final Map result = await _peer.sendRequest('getFlagList') as Map; - return result != null - ? (result['flags'] as List).cast>() - : const >[]; - } + /// + /// Throws [UnimplementedError] on [WebFlutterDriver] instances. + Future>> getVmFlags(); /// Starts recording performance traces. /// /// The `timeout` argument causes a warning to be displayed to the user if the /// operation exceeds the specified timeout; it does not actually cancel the /// operation. + /// + /// For [WebFlutterDriver], this is only supported for Chrome. Future startTracing({ - List streams = _defaultStreams, + List streams = const [TimelineStream.all], Duration timeout = kUnusuallyLongTimeout, - }) async { - assert(streams != null && streams.isNotEmpty); - assert(timeout != null); - try { - await _warnIfSlow( - future: _peer.sendRequest(_setVMTimelineFlagsMethodName, { - 'recordedStreams': _timelineStreamsToString(streams), - }), - timeout: timeout, - message: 'VM is taking an unusually long time to respond to being told to start tracing...', - ); - } catch (error, stackTrace) { - throw DriverError( - 'Failed to start tracing due to remote error', - error, - stackTrace, - ); - } - } + }); /// Stops recording performance traces and downloads the timeline. /// /// The `timeout` argument causes a warning to be displayed to the user if the /// operation exceeds the specified timeout; it does not actually cancel the /// operation. + /// + /// For [WebFlutterDriver], this is only supported for Chrome. Future stopTracingAndDownloadTimeline({ Duration timeout = kUnusuallyLongTimeout, - }) async { - assert(timeout != null); - try { - await _warnIfSlow( - future: _peer.sendRequest(_setVMTimelineFlagsMethodName, {'recordedStreams': '[]'}), - timeout: timeout, - message: 'VM is taking an unusually long time to respond to being told to stop tracing...', - ); - return Timeline.fromJson(await _peer.sendRequest(_getVMTimelineMethodName) as Map); - } catch (error, stackTrace) { - throw DriverError( - 'Failed to stop tracing due to remote error', - error, - stackTrace, - ); - } - } - - Future _isPrecompiledMode() async { - final List> flags = await getVmFlags(); - for(Map flag in flags) { - if (flag['name'] == 'precompiled_mode') { - return flag['valueAsString'] == 'true'; - } - } - return false; - } + }); /// Runs [action] and outputs a performance trace for it. /// @@ -967,46 +620,24 @@ class FlutterDriver { /// /// If this is run in debug mode, a warning message will be printed to suggest /// running the benchmark in profile mode instead. + /// + /// For [WebFlutterDriver], this is only supported for Chrome. Future traceAction( Future action(), { - List streams = _defaultStreams, + List streams = const [TimelineStream.all], bool retainPriorEvents = false, - }) async { - if (!retainPriorEvents) { - await clearTimeline(); - } - await startTracing(streams: streams); - await action(); - - if (!(await _isPrecompiledMode())) { - _log(_kDebugWarning); - } - return stopTracingAndDownloadTimeline(); - } + }); /// Clears all timeline events recorded up until now. /// /// The `timeout` argument causes a warning to be displayed to the user if the /// operation exceeds the specified timeout; it does not actually cancel the /// operation. + /// + /// For [WebFlutterDriver], this is only supported for Chrome. Future clearTimeline({ Duration timeout = kUnusuallyLongTimeout, - }) async { - assert(timeout != null); - try { - await _warnIfSlow( - future: _peer.sendRequest(_clearVMTimelineMethodName, {}), - timeout: timeout, - message: 'VM is taking an unusually long time to respond to being told to clear its timeline buffer...', - ); - } catch (error, stackTrace) { - throw DriverError( - 'Failed to clear event timeline due to remote error', - error, - stackTrace, - ); - } - } + }); /// [action] will be executed with the frame sync mechanism disabled. /// @@ -1025,155 +656,25 @@ class FlutterDriver { /// ensure that no action is performed while the app is undergoing a /// transition to avoid flakiness. Future runUnsynchronized(Future action(), { Duration timeout }) async { - await _sendCommand(SetFrameSync(false, timeout: timeout)); + await sendCommand(SetFrameSync(false, timeout: timeout)); T result; try { result = await action(); } finally { - await _sendCommand(SetFrameSync(true, timeout: timeout)); + await sendCommand(SetFrameSync(true, timeout: timeout)); } return result; } /// Force a garbage collection run in the VM. - Future forceGC() async { - try { - await _peer - .sendRequest(_collectAllGarbageMethodName, { - 'isolateId': 'isolates/${appIsolate.numberAsString}', - }); - } catch (error, stackTrace) { - throw DriverError( - 'Failed to force a GC due to remote error', - error, - stackTrace, - ); - } - } + /// + /// Throws [UnimplementedError] on [WebFlutterDriver] instances. + Future forceGC(); /// Closes the underlying connection to the VM service. /// /// Returns a [Future] that fires once the connection has been closed. - Future close() async { - // Don't leak vm_service_client-specific objects, if any - await serviceClient.close(); - await _peer.close(); - } -} - -/// Encapsulates connection information to an instance of a Flutter application. -@visibleForTesting -class VMServiceClientConnection { - /// Creates an instance of this class given a [client] and a [peer]. - VMServiceClientConnection(this.client, this.peer); - - /// Use this for structured access to the VM service's public APIs. - final VMServiceClient client; - - /// Use this to make arbitrary raw JSON-RPC calls. - /// - /// This object allows reaching into private VM service APIs. Use with - /// caution. - final rpc.Peer peer; -} - -/// A function that connects to a Dart VM service given the [url]. -typedef VMServiceConnectFunction = Future Function(String url); - -/// The connection function used by [FlutterDriver.connect]. -/// -/// Overwrite this function if you require a custom method for connecting to -/// the VM service. -VMServiceConnectFunction vmServiceConnectFunction = _waitAndConnect; - -/// Restores [vmServiceConnectFunction] to its default value. -void restoreVmServiceConnectFunction() { - vmServiceConnectFunction = _waitAndConnect; -} - -/// The JSON RPC 2 spec says that a notification from a client must not respond -/// to the client. It's possible the client sent a notification as a "ping", but -/// the service isn't set up yet to respond. -/// -/// For example, if the client sends a notification message to the server for -/// 'streamNotify', but the server has not finished loading, it will throw an -/// exception. Since the message is a notification, the server follows the -/// specification and does not send a response back, but is left with an -/// unhandled exception. That exception is safe for us to ignore - the client -/// is signaling that it will try again later if it doesn't get what it wants -/// here by sending a notification. -// This may be ignoring too many exceptions. It would be best to rewrite -// the client code to not use notifications so that it gets error replies back -// and can decide what to do from there. -// TODO(dnfield): https://github.com/flutter/flutter/issues/31813 -bool _ignoreRpcError(dynamic error) { - if (error is rpc.RpcException) { - final rpc.RpcException exception = error; - return exception.data == null || exception.data['id'] == null; - } else if (error is String && error.startsWith('JSON-RPC error -32601')) { - return true; - } - return false; -} - -void _unhandledJsonRpcError(dynamic error, dynamic stack) { - if (_ignoreRpcError(error)) { - return; - } - _log('Unhandled RPC error:\n$error\n$stack'); - // TODO(dnfield): https://github.com/flutter/flutter/issues/31813 - // assert(false); -} - -String _getWebSocketUrl(String url) { - Uri uri = Uri.parse(url); - final List pathSegments = [ - // If there's an authentication code (default), we need to add it to our path. - if (uri.pathSegments.isNotEmpty) uri.pathSegments.first, - 'ws', - ]; - if (uri.scheme == 'http') - uri = uri.replace(scheme: 'ws', pathSegments: pathSegments); - return uri.toString(); -} - -void _checkCloseCode(WebSocket ws) { - if (ws.closeCode != 1000 && ws.closeCode != null) { - _log('$ws is closed with an unexpected code ${ws.closeCode}'); - } -} - -/// Waits for a real Dart VM service to become available, then connects using -/// the [VMServiceClient]. -Future _waitAndConnect(String url) async { - final String webSocketUrl = _getWebSocketUrl(url); - int attempts = 0; - while (true) { - WebSocket ws1; - WebSocket ws2; - try { - ws1 = await WebSocket.connect(webSocketUrl); - ws2 = await WebSocket.connect(webSocketUrl); - - ws1.done.whenComplete(() => _checkCloseCode(ws1)); - ws2.done.whenComplete(() => _checkCloseCode(ws2)); - - return VMServiceClientConnection( - VMServiceClient(IOWebSocketChannel(ws1).cast()), - rpc.Peer( - IOWebSocketChannel(ws2).cast(), - onUnhandledError: _unhandledJsonRpcError, - )..listen(), - ); - } catch (e) { - await ws1?.close(); - await ws2?.close(); - if (attempts > 5) - _log('It is taking an unusually long time to connect to the VM...'); - attempts += 1; - await Future.delayed(_kPauseBetweenReconnectAttempts); - } - } + Future close(); } /// Provides convenient accessors to frequently used finders. diff --git a/packages/flutter_driver/lib/src/driver/vmservice_driver.dart b/packages/flutter_driver/lib/src/driver/vmservice_driver.dart new file mode 100644 index 0000000000..0a362173b8 --- /dev/null +++ b/packages/flutter_driver/lib/src/driver/vmservice_driver.dart @@ -0,0 +1,649 @@ +// Copyright 2014 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'dart:async'; +import 'dart:convert'; +import 'dart:io'; + +import 'package:file/file.dart' as f; +import 'package:fuchsia_remote_debug_protocol/fuchsia_remote_debug_protocol.dart' as fuchsia; +import 'package:json_rpc_2/error_code.dart' as error_code; +import 'package:json_rpc_2/json_rpc_2.dart' as rpc; +import 'package:meta/meta.dart'; +import 'package:path/path.dart' as p; +import 'package:vm_service_client/vm_service_client.dart'; +import 'package:web_socket_channel/io.dart'; + +import '../../flutter_driver.dart'; +import '../common/error.dart'; +import '../common/frame_sync.dart'; +import '../common/fuchsia_compat.dart'; +import '../common/health.dart'; +import '../common/message.dart'; +import 'common.dart'; +import 'driver.dart'; +import 'timeline.dart'; + +/// An implementation of the Flutter Driver over the vmservice protocol. +class VMServiceFlutterDriver extends FlutterDriver { + /// Creates a driver that uses a connection provided by the given + /// [serviceClient], [_peer] and [appIsolate]. + VMServiceFlutterDriver.connectedTo( + this._serviceClient, + this._peer, + this._appIsolate, { + bool printCommunication = false, + bool logCommunicationToFile = true, + }) : _printCommunication = printCommunication, + _logCommunicationToFile = logCommunicationToFile, + _driverId = _nextDriverId++; + + /// Connects to a Flutter application. + /// + /// See [FlutterDriver.connect] for more documentation. + static Future connect({ + String dartVmServiceUrl, + bool printCommunication = false, + bool logCommunicationToFile = true, + int isolateNumber, + Pattern fuchsiaModuleTarget, + }) async { + // If running on a Fuchsia device, connect to the first isolate whose name + // matches FUCHSIA_MODULE_TARGET. + // + // If the user has already supplied an isolate number/URL to the Dart VM + // service, then this won't be run as it is unnecessary. + if (Platform.isFuchsia && isolateNumber == null) { + // TODO(awdavies): Use something other than print. On fuchsia + // `stderr`/`stdout` appear to have issues working correctly. + driverLog = (String source, String message) { + print('$source: $message'); + }; + fuchsiaModuleTarget ??= Platform.environment['FUCHSIA_MODULE_TARGET']; + if (fuchsiaModuleTarget == null) { + throw DriverError( + 'No Fuchsia module target has been specified.\n' + 'Please make sure to specify the FUCHSIA_MODULE_TARGET ' + 'environment variable.' + ); + } + final fuchsia.FuchsiaRemoteConnection fuchsiaConnection = + await FuchsiaCompat.connect(); + final List refs = + await fuchsiaConnection.getMainIsolatesByPattern(fuchsiaModuleTarget); + final fuchsia.IsolateRef ref = refs.first; + isolateNumber = ref.number; + dartVmServiceUrl = ref.dartVm.uri.toString(); + await fuchsiaConnection.stop(); + FuchsiaCompat.cleanup(); + } + + dartVmServiceUrl ??= Platform.environment['VM_SERVICE_URL']; + + if (dartVmServiceUrl == null) { + throw DriverError( + 'Could not determine URL to connect to application.\n' + 'Either the VM_SERVICE_URL environment variable should be set, or an explicit ' + 'URL should be provided to the FlutterDriver.connect() method.' + ); + } + + // Connect to Dart VM services + _log('Connecting to Flutter application at $dartVmServiceUrl'); + final VMServiceClientConnection connection = + await vmServiceConnectFunction(dartVmServiceUrl); + final VMServiceClient client = connection.client; + final VM vm = await client.getVM(); + final VMIsolateRef isolateRef = isolateNumber == + null ? vm.isolates.first : + vm.isolates.firstWhere( + (VMIsolateRef isolate) => isolate.number == isolateNumber); + _log('Isolate found with number: ${isolateRef.number}'); + + VMIsolate isolate = await isolateRef.loadRunnable(); + + // TODO(yjbanov): vm_service_client does not support "None" pause event yet. + // It is currently reported as null, but we cannot rely on it because + // eventually the event will be reported as a non-null object. For now, + // list all the events we know about. Later we'll check for "None" event + // explicitly. + // + // See: https://github.com/dart-lang/vm_service_client/issues/4 + if (isolate.pauseEvent is! VMPauseStartEvent && + isolate.pauseEvent is! VMPauseExitEvent && + isolate.pauseEvent is! VMPauseBreakpointEvent && + isolate.pauseEvent is! VMPauseExceptionEvent && + isolate.pauseEvent is! VMPauseInterruptedEvent && + isolate.pauseEvent is! VMResumeEvent) { + isolate = await isolateRef.loadRunnable(); + } + + final VMServiceFlutterDriver driver = VMServiceFlutterDriver.connectedTo( + client, connection.peer, isolate, + printCommunication: printCommunication, + logCommunicationToFile: logCommunicationToFile, + ); + + driver._dartVmReconnectUrl = dartVmServiceUrl; + + // Attempts to resume the isolate, but does not crash if it fails because + // the isolate is already resumed. There could be a race with other tools, + // such as a debugger, any of which could have resumed the isolate. + Future resumeLeniently() { + _log('Attempting to resume isolate'); + return isolate.resume().catchError((dynamic e) { + const int vmMustBePausedCode = 101; + if (e is rpc.RpcException && e.code == vmMustBePausedCode) { + // No biggie; something else must have resumed the isolate + _log( + 'Attempted to resume an already resumed isolate. This may happen ' + 'when we lose a race with another tool (usually a debugger) that ' + 'is connected to the same isolate.' + ); + } else { + // Failed to resume due to another reason. Fail hard. + throw e; + } + }); + } + + /// Waits for a signal from the VM service that the extension is registered. + /// Returns [_flutterExtensionMethodName] + Future waitForServiceExtension() { + return isolate.onExtensionAdded.firstWhere((String extension) { + return extension == _flutterExtensionMethodName; + }); + } + + /// Tells the Dart VM Service to notify us about "Isolate" events. + /// + /// This is a workaround for an issue in package:vm_service_client, which + /// subscribes to the "Isolate" stream lazily upon subscription, which + /// results in lost events. + /// + /// Details: https://github.com/dart-lang/vm_service_client/issues/17 + Future enableIsolateStreams() async { + await connection.peer.sendRequest('streamListen', { + 'streamId': 'Isolate', + }); + } + + // Attempt to resume isolate if it was paused + if (isolate.pauseEvent is VMPauseStartEvent) { + _log('Isolate is paused at start.'); + + // If the isolate is paused at the start, e.g. via the --start-paused + // option, then the VM service extension is not registered yet. Wait for + // it to be registered. + await enableIsolateStreams(); + final Future whenServiceExtensionReady = waitForServiceExtension(); + final Future whenResumed = resumeLeniently(); + await whenResumed; + + _log('Waiting for service extension'); + // We will never receive the extension event if the user does not + // register it. If that happens, show a message but continue waiting. + await _warnIfSlow( + future: whenServiceExtensionReady, + timeout: kUnusuallyLongTimeout, + message: 'Flutter Driver extension is taking a long time to become available. ' + 'Ensure your test app (often "lib/main.dart") imports ' + '"package:flutter_driver/driver_extension.dart" and ' + 'calls enableFlutterDriverExtension() as the first call in main().', + ); + } else if (isolate.pauseEvent is VMPauseExitEvent || + isolate.pauseEvent is VMPauseBreakpointEvent || + isolate.pauseEvent is VMPauseExceptionEvent || + isolate.pauseEvent is VMPauseInterruptedEvent) { + // If the isolate is paused for any other reason, assume the extension is + // already there. + _log('Isolate is paused mid-flight.'); + await resumeLeniently(); + } else if (isolate.pauseEvent is VMResumeEvent) { + _log('Isolate is not paused. Assuming application is ready.'); + } else { + _log( + 'Unknown pause event type ${isolate.pauseEvent.runtimeType}. ' + 'Assuming application is ready.' + ); + } + + // Invoked checkHealth and try to fix delays in the registration of Service + // extensions + Future checkHealth() async { + try { + // At this point the service extension must be installed. Verify it. + return await driver.checkHealth(); + } on rpc.RpcException catch (e) { + if (e.code != error_code.METHOD_NOT_FOUND) { + rethrow; + } + _log( + 'Check Health failed, try to wait for the service extensions to be' + 'registered.' + ); + await enableIsolateStreams(); + await waitForServiceExtension(); + return driver.checkHealth(); + } + } + + final Health health = await checkHealth(); + if (health.status != HealthStatus.ok) { + await client.close(); + throw DriverError('Flutter application health check failed.'); + } + + _log('Connected to Flutter application.'); + return driver; + } + + static int _nextDriverId = 0; + + static const String _flutterExtensionMethodName = 'ext.flutter.driver'; + static const String _setVMTimelineFlagsMethodName = 'setVMTimelineFlags'; + static const String _getVMTimelineMethodName = 'getVMTimeline'; + static const String _clearVMTimelineMethodName = 'clearVMTimeline'; + static const String _collectAllGarbageMethodName = '_collectAllGarbage'; + + // The additional blank line in the beginning is for _log. + static const String _kDebugWarning = ''' +┏╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍┓ +┇ ⚠ THIS BENCHMARK IS BEING RUN IN DEBUG MODE ⚠ ┇ +┡╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍┦ +│ │ +│ Numbers obtained from a benchmark while asserts are │ +│ enabled will not accurately reflect the performance │ +│ that will be experienced by end users using release ╎ +│ builds. Benchmarks should be run using this command ┆ +│ line: flutter drive --profile test_perf.dart ┊ +│ ┊ +└─────────────────────────────────────────────────╌┄┈ 🐢 +'''; + /// The unique ID of this driver instance. + final int _driverId; + + /// Client connected to the Dart VM running the Flutter application + /// + /// You can use [VMServiceClient] to check VM version, flags and get + /// notified when a new isolate has been instantiated. That could be + /// useful if your application spawns multiple isolates that you + /// would like to instrument. + final VMServiceClient _serviceClient; + + /// JSON-RPC client useful for sending raw JSON requests. + rpc.Peer _peer; + + String _dartVmReconnectUrl; + + Future _restorePeerConnectionIfNeeded() async { + if (!_peer.isClosed || _dartVmReconnectUrl == null) { + return; + } + + _log( + 'Peer connection is closed! Trying to restore the connection...' + ); + + final String webSocketUrl = _getWebSocketUrl(_dartVmReconnectUrl); + final WebSocket ws = await WebSocket.connect(webSocketUrl); + ws.done.whenComplete(() => _checkCloseCode(ws)); + _peer = rpc.Peer( + IOWebSocketChannel(ws).cast(), + onUnhandledError: _unhandledJsonRpcError, + )..listen(); + } + + /// The main isolate hosting the Flutter application. + /// + /// If you used the [registerExtension] API to instrument your application, + /// you can use this [VMIsolate] to call these extension methods via + /// [invokeExtension]. + final VMIsolate _appIsolate; + + /// Whether to print communication between host and app to `stdout`. + final bool _printCommunication; + + /// Whether to log communication between host and app to `flutter_driver_commands.log`. + final bool _logCommunicationToFile; + + @override + Future> sendCommand(Command command) async { + Map response; + try { + final Map serialized = command.serialize(); + _logCommunication('>>> $serialized'); + final Future> future = _appIsolate.invokeExtension( + _flutterExtensionMethodName, + serialized, + ).then>((Object value) => value as Map); + response = await _warnIfSlow>( + future: future, + timeout: command.timeout ?? kUnusuallyLongTimeout, + message: '${command.kind} message is taking a long time to complete...', + ); + _logCommunication('<<< $response'); + } catch (error, stackTrace) { + throw DriverError( + 'Failed to fulfill ${command.runtimeType} due to remote error', + error, + stackTrace, + ); + } + if (response['isError'] as bool) + throw DriverError('Error in Flutter application: ${response['response']}'); + return response['response'] as Map; + } + + void _logCommunication(String message) { + if (_printCommunication) + _log(message); + if (_logCommunicationToFile) { + final f.File file = fs.file(p.join(testOutputsDirectory, 'flutter_driver_commands_$_driverId.log')); + file.createSync(recursive: true); // no-op if file exists + file.writeAsStringSync('${DateTime.now()} $message\n', mode: f.FileMode.append, flush: true); + } + } + + @override + Future> screenshot() async { + await Future.delayed(const Duration(seconds: 2)); + + final Map result = await _peer.sendRequest('_flutter.screenshot') as Map; + return base64.decode(result['screenshot'] as String); + } + + @override + Future>> getVmFlags() async { + await _restorePeerConnectionIfNeeded(); + final Map result = await _peer.sendRequest('getFlagList') as Map; + return result != null + ? (result['flags'] as List).cast>() + : const >[]; + } + + @override + Future startTracing({ + List streams = const [TimelineStream.all], + Duration timeout = kUnusuallyLongTimeout, + }) async { + assert(streams != null && streams.isNotEmpty); + assert(timeout != null); + try { + await _warnIfSlow( + future: _peer.sendRequest(_setVMTimelineFlagsMethodName, { + 'recordedStreams': _timelineStreamsToString(streams), + }), + timeout: timeout, + message: 'VM is taking an unusually long time to respond to being told to start tracing...', + ); + } catch (error, stackTrace) { + throw DriverError( + 'Failed to start tracing due to remote error', + error, + stackTrace, + ); + } + } + + + @override + Future stopTracingAndDownloadTimeline({ + Duration timeout = kUnusuallyLongTimeout, + }) async { + assert(timeout != null); + try { + await _warnIfSlow( + future: _peer.sendRequest(_setVMTimelineFlagsMethodName, {'recordedStreams': '[]'}), + timeout: timeout, + message: 'VM is taking an unusually long time to respond to being told to stop tracing...', + ); + return Timeline.fromJson(await _peer.sendRequest(_getVMTimelineMethodName) as Map); + } catch (error, stackTrace) { + throw DriverError( + 'Failed to stop tracing due to remote error', + error, + stackTrace, + ); + } + } + + Future _isPrecompiledMode() async { + final List> flags = await getVmFlags(); + for(Map flag in flags) { + if (flag['name'] == 'precompiled_mode') { + return flag['valueAsString'] == 'true'; + } + } + return false; + } + + @override + Future traceAction( + Future action(), { + List streams = const [TimelineStream.all], + bool retainPriorEvents = false, + }) async { + if (!retainPriorEvents) { + await clearTimeline(); + } + await startTracing(streams: streams); + await action(); + + if (!(await _isPrecompiledMode())) { + _log(_kDebugWarning); + } + return stopTracingAndDownloadTimeline(); + } + + @override + Future clearTimeline({ + Duration timeout = kUnusuallyLongTimeout, + }) async { + assert(timeout != null); + try { + await _warnIfSlow( + future: _peer.sendRequest(_clearVMTimelineMethodName, {}), + timeout: timeout, + message: 'VM is taking an unusually long time to respond to being told to clear its timeline buffer...', + ); + } catch (error, stackTrace) { + throw DriverError( + 'Failed to clear event timeline due to remote error', + error, + stackTrace, + ); + } + } + + @override + Future runUnsynchronized(Future action(), { Duration timeout }) async { + await sendCommand(SetFrameSync(false, timeout: timeout)); + T result; + try { + result = await action(); + } finally { + await sendCommand(SetFrameSync(true, timeout: timeout)); + } + return result; + } + + @override + Future forceGC() async { + try { + await _peer + .sendRequest(_collectAllGarbageMethodName, { + 'isolateId': 'isolates/${_appIsolate.numberAsString}', + }); + } catch (error, stackTrace) { + throw DriverError( + 'Failed to force a GC due to remote error', + error, + stackTrace, + ); + } + } + + @override + Future close() async { + // Don't leak vm_service_client-specific objects, if any + await _serviceClient.close(); + await _peer.close(); + } +} + + +/// The connection function used by [FlutterDriver.connect]. +/// +/// Overwrite this function if you require a custom method for connecting to +/// the VM service. +VMServiceConnectFunction vmServiceConnectFunction = _waitAndConnect; + +/// Restores [vmServiceConnectFunction] to its default value. +void restoreVmServiceConnectFunction() { + vmServiceConnectFunction = _waitAndConnect; +} + +/// The JSON RPC 2 spec says that a notification from a client must not respond +/// to the client. It's possible the client sent a notification as a "ping", but +/// the service isn't set up yet to respond. +/// +/// For example, if the client sends a notification message to the server for +/// 'streamNotify', but the server has not finished loading, it will throw an +/// exception. Since the message is a notification, the server follows the +/// specification and does not send a response back, but is left with an +/// unhandled exception. That exception is safe for us to ignore - the client +/// is signaling that it will try again later if it doesn't get what it wants +/// here by sending a notification. +// This may be ignoring too many exceptions. It would be best to rewrite +// the client code to not use notifications so that it gets error replies back +// and can decide what to do from there. +// TODO(dnfield): https://github.com/flutter/flutter/issues/31813 +bool _ignoreRpcError(dynamic error) { + if (error is rpc.RpcException) { + final rpc.RpcException exception = error; + return exception.data == null || exception.data['id'] == null; + } else if (error is String && error.startsWith('JSON-RPC error -32601')) { + return true; + } + return false; +} + +void _unhandledJsonRpcError(dynamic error, dynamic stack) { + if (_ignoreRpcError(error)) { + return; + } + _log('Unhandled RPC error:\n$error\n$stack'); + // TODO(dnfield): https://github.com/flutter/flutter/issues/31813 + // assert(false); +} + +String _getWebSocketUrl(String url) { + Uri uri = Uri.parse(url); + final List pathSegments = [ + // If there's an authentication code (default), we need to add it to our path. + if (uri.pathSegments.isNotEmpty) uri.pathSegments.first, + 'ws', + ]; + if (uri.scheme == 'http') + uri = uri.replace(scheme: 'ws', pathSegments: pathSegments); + return uri.toString(); +} + +void _checkCloseCode(WebSocket ws) { + if (ws.closeCode != 1000 && ws.closeCode != null) { + _log('$ws is closed with an unexpected code ${ws.closeCode}'); + } +} + +/// Waits for a real Dart VM service to become available, then connects using +/// the [VMServiceClient]. +Future _waitAndConnect(String url) async { + final String webSocketUrl = _getWebSocketUrl(url); + int attempts = 0; + while (true) { + WebSocket ws1; + WebSocket ws2; + try { + ws1 = await WebSocket.connect(webSocketUrl); + ws2 = await WebSocket.connect(webSocketUrl); + + ws1.done.whenComplete(() => _checkCloseCode(ws1)); + ws2.done.whenComplete(() => _checkCloseCode(ws2)); + + return VMServiceClientConnection( + VMServiceClient(IOWebSocketChannel(ws1).cast()), + rpc.Peer( + IOWebSocketChannel(ws2).cast(), + onUnhandledError: _unhandledJsonRpcError, + )..listen(), + ); + } catch (e) { + await ws1?.close(); + await ws2?.close(); + if (attempts > 5) + _log('It is taking an unusually long time to connect to the VM...'); + attempts += 1; + await Future.delayed(_kPauseBetweenReconnectAttempts); + } + } +} + + +/// The amount of time we wait prior to making the next attempt to connect to +/// the VM service. +const Duration _kPauseBetweenReconnectAttempts = Duration(seconds: 1); + +// See https://github.com/dart-lang/sdk/blob/master/runtime/vm/timeline.cc#L32 +String _timelineStreamsToString(List streams) { + final String contents = streams.map((TimelineStream stream) { + switch (stream) { + case TimelineStream.all: return 'all'; + case TimelineStream.api: return 'API'; + case TimelineStream.compiler: return 'Compiler'; + case TimelineStream.dart: return 'Dart'; + case TimelineStream.debugger: return 'Debugger'; + case TimelineStream.embedder: return 'Embedder'; + case TimelineStream.gc: return 'GC'; + case TimelineStream.isolate: return 'Isolate'; + case TimelineStream.vm: return 'VM'; + default: + throw 'Unknown timeline stream $stream'; + } + }).join(', '); + return '[$contents]'; +} + +void _log(String message) { + driverLog('VMServiceFlutterDriver', message); +} +Future _warnIfSlow({ + @required Future future, + @required Duration timeout, + @required String message, +}) { + assert(future != null); + assert(timeout != null); + assert(message != null); + return future..timeout(timeout, onTimeout: () { _log(message); return null; }); +} + +/// Encapsulates connection information to an instance of a Flutter application. +@visibleForTesting +class VMServiceClientConnection { + /// Creates an instance of this class given a [client] and a [peer]. + VMServiceClientConnection(this.client, this.peer); + + /// Use this for structured access to the VM service's public APIs. + final VMServiceClient client; + + /// Use this to make arbitrary raw JSON-RPC calls. + /// + /// This object allows reaching into private VM service APIs. Use with + /// caution. + final rpc.Peer peer; +} + +/// A function that connects to a Dart VM service given the [url]. +typedef VMServiceConnectFunction = Future Function(String url); diff --git a/packages/flutter_driver/lib/src/driver/web_driver.dart b/packages/flutter_driver/lib/src/driver/web_driver.dart new file mode 100644 index 0000000000..2ab99b320e --- /dev/null +++ b/packages/flutter_driver/lib/src/driver/web_driver.dart @@ -0,0 +1,248 @@ +// Copyright 2014 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'dart:async'; +import 'dart:convert'; +import 'dart:io'; +import 'dart:math' as math; + +import 'package:matcher/matcher.dart'; +import 'package:meta/meta.dart'; +import 'package:webdriver/sync_io.dart' as sync_io; +import 'package:webdriver/support/async.dart'; + +import '../common/error.dart'; +import '../common/message.dart'; +import 'driver.dart'; +import 'timeline.dart'; +import 'web_driver_config.dart'; + +export 'web_driver_config.dart'; + +/// An implementation of the Flutter Driver using the WebDriver. +/// +/// Example of how to test WebFlutterDriver: +/// 1. Have Selenium server (https://bit.ly/2TlkRyu) and WebDriver binary (https://chromedriver.chromium.org/downloads) downloaded and placed under the same folder +/// 2. Launch WebDriver Server: java -jar selenium-server-standalone-3.141.59.jar +/// 3. Launch Flutter Web application: flutter run -v -d chrome --target=test_driver/scroll_perf_web.dart +/// 4. Run test script: flutter drive --target=test_driver/scroll_perf.dart -v --use-existing-app=/application address/ +class WebFlutterDriver extends FlutterDriver { + /// Creates a driver that uses a connection provided by the given + /// [_connection] and [_browserName]. + WebFlutterDriver.connectedTo(this._connection, this._browser); + + final FlutterWebConnection _connection; + final Browser _browser; + DateTime _startTime; + + /// Start time for tracing + @visibleForTesting + DateTime get startTime => _startTime; + + /// Creates a driver that uses a connection provided by the given + /// [hostUrl] which would fallback to environment variable VM_SERVICE_URL. + /// Driver also depends on environment variables BROWSER_NAME, + /// BROWSER_DIMENSION, HEADLESS and SELENIUM_PORT for configurations. + static Future connectWeb( + {String hostUrl, Duration timeout}) async { + hostUrl ??= Platform.environment['VM_SERVICE_URL']; + final Browser browser = browserNameToEnum(Platform.environment['BROWSER_NAME']); + final Map settings = { + 'browser': browser, + 'browser-dimension': Platform.environment['BROWSER_DIMENSION'], + 'headless': Platform.environment['HEADLESS']?.toLowerCase() == 'true', + 'selenium-port': Platform.environment['SELENIUM_PORT'], + }; + final FlutterWebConnection connection = await FlutterWebConnection.connect + (hostUrl, settings, timeout: timeout); + return WebFlutterDriver.connectedTo(connection, browser); + } + + @override + Future> sendCommand(Command command) async { + Map response; + final Map serialized = command.serialize(); + try { + final dynamic data = await _connection.sendCommand('window.\$flutterDriver(\'${jsonEncode(serialized)}\')', command.timeout); + response = data != null ? json.decode(data as String) as Map : {}; + } catch (error, stackTrace) { + throw DriverError('Failed to respond to $command due to remote error\n : \$flutterDriver(\'${jsonEncode(serialized)}\')', + error, + stackTrace + ); + } + if (response['isError'] == true) + throw DriverError('Error in Flutter application: ${response['response']}'); + return response['response'] as Map; + } + + @override + Future close() => _connection.close(); + + @override + Future forceGC() async { + throw UnimplementedError(); + } + + @override + Future>> getVmFlags() async { + throw UnimplementedError(); + } + + @override + Future waitUntilFirstFrameRasterized() async { + throw UnimplementedError(); + } + + @override + Future> screenshot() async { + await Future.delayed(const Duration(seconds: 2)); + + return _connection.screenshot(); + } + + @override + Future startTracing({ + List streams = const [TimelineStream.all], + Duration timeout = kUnusuallyLongTimeout, + }) async { + _checkBrowserSupportsTimeline(); + + _startTime = DateTime.now(); + } + + @override + Future stopTracingAndDownloadTimeline({Duration timeout = kUnusuallyLongTimeout}) async { + _checkBrowserSupportsTimeline(); + if (_startTime == null) { + return null; + } + + final List> events = >[]; + for (sync_io.LogEntry entry in _connection.logs) { + if (_startTime.isBefore(entry.timestamp)) { + final Map data = jsonDecode(entry.message)['message'] as Map; + if (data['method'] == 'Tracing.dataCollected') { + // 'ts' data collected from Chrome is in double format, conversion needed + try { + data['params']['ts'] = + double.parse(data['params']['ts'].toString()).toInt(); + } on FormatException catch (_) { + // data is corrupted, skip + continue; + } + events.add(data['params'] as Map); + } + } + } + final Map json = { + 'traceEvents': events, + }; + _startTime = null; + return Timeline.fromJson(json); + } + + @override + Future traceAction(Future Function() action, { + List streams = const [TimelineStream.all], + bool retainPriorEvents = false, + }) async { + _checkBrowserSupportsTimeline(); + if (!retainPriorEvents) { + await clearTimeline(); + } + await startTracing(streams: streams); + await action(); + + return stopTracingAndDownloadTimeline(); + } + + @override + Future clearTimeline({Duration timeout = kUnusuallyLongTimeout}) async { + _checkBrowserSupportsTimeline(); + + // Reset start time + _startTime = null; + } + + /// Checks whether browser supports Timeline related operations + void _checkBrowserSupportsTimeline() { + if (_browser != Browser.chrome) { + throw UnimplementedError(); + } + } +} + +/// Encapsulates connection information to an instance of a Flutter Web application. +class FlutterWebConnection { + FlutterWebConnection._(this._driver); + + final sync_io.WebDriver _driver; + + /// Starts WebDriver with the given [capabilities] and + /// establishes the connection to Flutter Web application. + static Future connect( + String url, + Map settings, + {Duration timeout}) async { + // Use sync WebDriver because async version will create a 15 seconds + // overhead when quitting. + final sync_io.WebDriver driver = createDriver(settings); + driver.get(url); + + // Configure WebDriver browser by setting its location and dimension. + final List dimensions = settings['browser-dimension'].split(',') as List; + if (dimensions.length != 2) { + throw DriverError('Invalid browser window size.'); + } + final int x = int.parse(dimensions[0]); + final int y = int.parse(dimensions[1]); + final sync_io.Window window = driver.window; + window.setLocation(const math.Point(0, 0)); + window.setSize(math.Rectangle(0, 0, x, y)); + + // Wait until extension is installed. + await waitFor(() => driver.execute('return typeof(window.\$flutterDriver)', []), + matcher: 'function', + timeout: timeout ?? const Duration(days: 365)); + return FlutterWebConnection._(driver); + } + + /// Sends command via WebDriver to Flutter web application + Future sendCommand(String script, Duration duration) async { + dynamic result; + try { + _driver.execute(script, []); + } catch (_) { + // In case there is an exception, do nothing + } + + try { + result = await waitFor(() => _driver.execute('r' + 'eturn \$flutterDriverResult', []), + matcher: isNotNull, + timeout: duration ?? const Duration(days: 30)); + } catch (_) { + // Returns null if exception thrown. + return null; + } finally { + // Resets the result. + _driver.execute(''' + \$flutterDriverResult = null + ''', []); + } + return result; + } + + /// Gets performance log from WebDriver. + List get logs => _driver.logs.get(sync_io.LogType.performance); + + /// Takes screenshot via WebDriver. + List screenshot() => _driver.captureScreenshotAsList(); + + /// Closes the WebDriver. + Future close() async { + _driver.quit(); + } +} diff --git a/packages/flutter_driver/lib/src/driver/web_driver_config.dart b/packages/flutter_driver/lib/src/driver/web_driver_config.dart new file mode 100644 index 0000000000..f2a7a5fc86 --- /dev/null +++ b/packages/flutter_driver/lib/src/driver/web_driver_config.dart @@ -0,0 +1,130 @@ +// Copyright 2014 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:meta/meta.dart'; +import 'package:webdriver/sync_io.dart' as sync_io; + +import '../common/error.dart'; + +/// A list of supported browsers +enum Browser { + /// Chrome: https://www.google.com/chrome/ + chrome, + /// Edge: https://www.microsoft.com/en-us/windows/microsoft-edge + edge, + /// Firefox: https://www.mozilla.org/en-US/firefox/ + firefox, + /// Safari in iOS: https://www.apple.com/safari/ + iosSafari, + /// Safari in macOS: https://www.apple.com/safari/ + safari, +} + +/// Converts [browserName] string to [Browser] +Browser browserNameToEnum(String browserName){ + switch (browserName) { + case 'chrome': return Browser.chrome; + case 'edge': return Browser.edge; + case 'firefox': return Browser.firefox; + case 'ios-safari': return Browser.iosSafari; + case 'safari': return Browser.safari; + } + throw DriverError('Browser $browserName not supported'); +} + +/// Creates a WebDriver instance with the given [settings]. +sync_io.WebDriver createDriver(Map settings) { + return _createDriver( + settings['selenium-port'] as String, + settings['browser'] as Browser, + settings['headless'] as bool + ); +} + +sync_io.WebDriver _createDriver(String seleniumPort, Browser browser, bool headless) { + return sync_io.createDriver( + uri: Uri.parse('http://localhost:$seleniumPort/wd/hub/'), + desired: getDesiredCapabilities(browser, headless), + spec: browser != Browser.iosSafari ? sync_io.WebDriverSpec.JsonWire : sync_io.WebDriverSpec.W3c + ); +} + +/// Returns desired capabilities for given [browser] and [headless]. +@visibleForTesting +Map getDesiredCapabilities(Browser browser, bool headless) { + switch (browser) { + case Browser.chrome: + return { + 'acceptInsecureCerts': true, + 'browserName': 'chrome', + 'goog:loggingPrefs': { sync_io.LogType.performance: 'ALL'}, + 'chromeOptions': { + 'args': [ + '--bwsi', + '--disable-background-timer-throttling', + '--disable-default-apps', + '--disable-extensions', + '--disable-popup-blocking', + '--disable-translate', + '--no-default-browser-check', + '--no-sandbox', + '--no-first-run', + if (headless) '--headless' + ], + 'perfLoggingPrefs': { + 'traceCategories': + 'devtools.timeline,' + 'v8,blink.console,benchmark,blink,' + 'blink.user_timing' + } + } + }; + break; + case Browser.firefox: + return { + 'acceptInsecureCerts': true, + 'browserName': 'firefox', + 'moz:firefoxOptions' : { + 'args': [ + if (headless) '-headless' + ], + 'prefs': { + 'dom.file.createInChild': true, + 'dom.timeout.background_throttling_max_budget': -1, + 'media.autoplay.default': 0, + 'media.gmp-manager.url': '', + 'media.gmp-provider.enabled': false, + 'network.captive-portal-service.enabled': false, + 'security.insecure_field_warning.contextual.enabled': false, + 'test.currentTimeOffsetSeconds': 11491200 + }, + 'log': {'level': 'trace'} + } + }; + break; + case Browser.edge: + return { + 'acceptInsecureCerts': true, + 'browserName': 'edge', + }; + break; + case Browser.safari: + return { + 'browserName': 'safari', + 'safari.options': { + 'skipExtensionInstallation': true, + 'cleanSession': true + } + }; + break; + case Browser.iosSafari: + return { + 'platformName': 'ios', + 'browserName': 'safari', + 'safari:useSimulator': true + }; + default: + throw DriverError('Browser $browser not supported.'); + } +} diff --git a/packages/flutter_driver/lib/src/extension/extension.dart b/packages/flutter_driver/lib/src/extension/extension.dart index af1f8bec0a..fc43c21021 100644 --- a/packages/flutter_driver/lib/src/extension/extension.dart +++ b/packages/flutter_driver/lib/src/extension/extension.dart @@ -4,15 +4,14 @@ import 'dart:async'; -import 'package:flutter/semantics.dart'; import 'package:meta/meta.dart'; - import 'package:flutter/cupertino.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart' show RendererBinding, SemanticsHandle; import 'package:flutter/scheduler.dart'; +import 'package:flutter/semantics.dart'; import 'package:flutter/services.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_test/flutter_test.dart'; @@ -31,6 +30,7 @@ import '../common/request_data.dart'; import '../common/semantics.dart'; import '../common/text.dart'; import '../common/wait.dart'; +import 'io_extension.dart' if (dart.library.html) 'web_extension.dart'; import 'wait_conditions.dart'; const String _extensionMethodName = 'driver'; @@ -56,6 +56,9 @@ class _DriverBinding extends BindingBase with ServicesBinding, SchedulerBinding, name: _extensionMethodName, callback: extension.call, ); + if (kIsWeb) { + registerWebServiceExtension(extension.call); + } } @override diff --git a/packages/flutter_driver/lib/src/extension/io_extension.dart b/packages/flutter_driver/lib/src/extension/io_extension.dart new file mode 100644 index 0000000000..34684af90c --- /dev/null +++ b/packages/flutter_driver/lib/src/extension/io_extension.dart @@ -0,0 +1,12 @@ +// Copyright 2014 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +/// The dart:io implementation of [registerWebServiceExtension]. +/// +/// See also: +/// +/// * [web_extension.dart], which has the dart:html implementation +void registerWebServiceExtension(Future> Function(Map) call) { + throw UnsupportedError('Use registerServiceExtension instead'); +} diff --git a/packages/flutter_driver/lib/src/extension/web_extension.dart b/packages/flutter_driver/lib/src/extension/web_extension.dart new file mode 100644 index 0000000000..596a21ee98 --- /dev/null +++ b/packages/flutter_driver/lib/src/extension/web_extension.dart @@ -0,0 +1,30 @@ +// Copyright 2014 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'dart:async'; +import 'dart:convert'; +import 'dart:html' as html; +import 'dart:js'; +import 'dart:js_util' as js_util; + +/// The dart:html implementation of [registerWebServiceExtension]. +/// +/// Registers Web Service Extension for Flutter Web application. +/// +/// window.$flutterDriver will be called by Flutter Web Driver to process +/// Flutter Command. +/// +/// See also: +/// +/// * [io_extension.dart], which has the dart:io implemeantion +void registerWebServiceExtension(Future> Function(Map) call) { + js_util.setProperty(html.window, '\$flutterDriver', allowInterop((dynamic message) async { + // ignore: undefined_function, undefined_identifier + final Map params = Map.from( + jsonDecode(message as String) as Map); + final Map result = Map.from( + await call(params)); + context['\$flutterDriverResult'] = json.encode(result); + })); +} diff --git a/packages/flutter_driver/pubspec.yaml b/packages/flutter_driver/pubspec.yaml index ddcfc018f9..2e14b37adf 100644 --- a/packages/flutter_driver/pubspec.yaml +++ b/packages/flutter_driver/pubspec.yaml @@ -14,6 +14,7 @@ dependencies: path: 1.6.4 web_socket_channel: 1.1.0 vm_service_client: 0.2.6+2 + webdriver: 2.1.1 flutter: sdk: flutter flutter_test: @@ -41,6 +42,7 @@ dependencies: stack_trace: 1.9.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" stream_channel: 2.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" string_scanner: 1.0.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + sync_http: 0.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" term_glyph: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" test_api: 0.2.11 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" typed_data: 1.1.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -51,4 +53,4 @@ dev_dependencies: mockito: 4.1.1 quiver: 2.0.5 -# PUBSPEC CHECKSUM: a765 +# PUBSPEC CHECKSUM: 1daa diff --git a/packages/flutter_driver/test/flutter_driver_test.dart b/packages/flutter_driver/test/flutter_driver_test.dart index 4ee125689e..6fa20c8f0a 100644 --- a/packages/flutter_driver/test/flutter_driver_test.dart +++ b/packages/flutter_driver/test/flutter_driver_test.dart @@ -3,6 +3,7 @@ // found in the LICENSE file. import 'dart:async'; +import 'dart:convert'; import 'package:flutter_driver/src/common/error.dart'; import 'package:flutter_driver/src/common/health.dart'; @@ -20,6 +21,8 @@ import 'common.dart'; /// Magical timeout value that's different from the default. const Duration _kTestTimeout = Duration(milliseconds: 1234); const String _kSerializedTestTimeout = '1234'; +const String _kWebScriptPrefix = 'window.\$flutterDriver(\''; +const String _kWebScriptSuffix = '\')'; void main() { final List log = []; @@ -27,7 +30,7 @@ void main() { log.add('$source: $message'); }; - group('FlutterDriver.connect', () { + group('VMServiceFlutterDriver.connect', () { MockVMServiceClient mockClient; MockVM mockVM; MockIsolate mockIsolate; @@ -115,17 +118,17 @@ void main() { }); }); - group('FlutterDriver', () { + group('VMServiceFlutterDriver', () { MockVMServiceClient mockClient; MockPeer mockPeer; MockIsolate mockIsolate; - FlutterDriver driver; + VMServiceFlutterDriver driver; setUp(() { mockClient = MockVMServiceClient(); mockPeer = MockPeer(); mockIsolate = MockIsolate(); - driver = FlutterDriver.connectedTo(mockClient, mockPeer, mockIsolate); + driver = VMServiceFlutterDriver.connectedTo(mockClient, mockPeer, mockIsolate); }); test('checks the health of the driver extension', () async { @@ -615,7 +618,7 @@ void main() { expect(log, []); time.elapse(kUnusuallyLongTimeout); }); - expect(log, ['FlutterDriver: waitFor message is taking a long time to complete...']); + expect(log, ['VMServiceFlutterDriver: waitFor message is taking a long time to complete...']); }); test('local custom timeout', () async { @@ -630,7 +633,7 @@ void main() { expect(log, []); time.elapse(customTimeout); }); - expect(log, ['FlutterDriver: waitFor message is taking a long time to complete...']); + expect(log, ['VMServiceFlutterDriver: waitFor message is taking a long time to complete...']); }); test('remote error', () async { @@ -650,17 +653,17 @@ void main() { }); }); - group('FlutterDriver with custom timeout', () { + group('VMServiceFlutterDriver with custom timeout', () { MockVMServiceClient mockClient; MockPeer mockPeer; MockIsolate mockIsolate; - FlutterDriver driver; + VMServiceFlutterDriver driver; setUp(() { mockClient = MockVMServiceClient(); mockPeer = MockPeer(); mockIsolate = MockIsolate(); - driver = FlutterDriver.connectedTo(mockClient, mockPeer, mockIsolate); + driver = VMServiceFlutterDriver.connectedTo(mockClient, mockPeer, mockIsolate); }); test('GetHealth has no default timeout', () async { @@ -684,6 +687,377 @@ void main() { await driver.checkHealth(timeout: _kTestTimeout); }); }); + + group('WebFlutterDriver', () { + MockFlutterWebConnection mockConnection; + WebFlutterDriver driver; + + setUp(() { + mockConnection = MockFlutterWebConnection(); + driver = WebFlutterDriver.connectedTo(mockConnection, Browser.chrome); + }); + + test('closes connection', () async { + when(mockConnection.close()).thenAnswer((Invocation invocation) => Future.value(null)); + await driver.close(); + }); + + group('ByValueKey', () { + test('restricts value types', () async { + expect(() => find.byValueKey(null), + throwsA(isInstanceOf())); + }); + + test('finds by ValueKey', () async { + when(mockConnection.sendCommand(any, any)).thenAnswer((Invocation i) async { + final String script = _checkAndEncode(i.positionalArguments[0]); + expect(Map.from(jsonDecode(script) as Map), { + 'command': 'tap', + 'timeout': _kSerializedTestTimeout, + 'finderType': 'ByValueKey', + 'keyValueString': 'foo', + 'keyValueType': 'String', + }); + return jsonEncode(await makeMockResponse({})); + }); + await driver.tap(find.byValueKey('foo'), timeout: _kTestTimeout); + }); + }); + + group('BySemanticsLabel', () { + test('finds by Semantic label using String', () async { + when(mockConnection.sendCommand(any, any)).thenAnswer((Invocation i) async { + final String script = _checkAndEncode(i.positionalArguments[0]); + expect(Map.from(jsonDecode(script) as Map), { + 'command': 'tap', + 'timeout': _kSerializedTestTimeout, + 'finderType': 'BySemanticsLabel', + 'label': 'foo', + }); + return jsonEncode(await makeMockResponse({})); + }); + await driver.tap(find.bySemanticsLabel('foo'), timeout: _kTestTimeout); + }); + + test('finds by Semantic label using RegExp', () async { + when(mockConnection.sendCommand(any, any)).thenAnswer((Invocation i) async { + final String script = _checkAndEncode(i.positionalArguments[0]); + expect(Map.from(jsonDecode(script) as Map), { + 'command': 'tap', + 'timeout': _kSerializedTestTimeout, + 'finderType': 'BySemanticsLabel', + 'label': '^foo', + 'isRegExp': 'true', + }); + return jsonEncode(await makeMockResponse({})); + }); + await driver.tap(find.bySemanticsLabel(RegExp('^foo')), timeout: _kTestTimeout); + }); + }); + + group('tap', () { + test('requires a target reference', () async { + expect(driver.tap(null), throwsA(isInstanceOf())); + }); + + test('sends the tap command', () async { + when(mockConnection.sendCommand(any, any)).thenAnswer((Invocation i) async { + final String script = _checkAndEncode(i.positionalArguments[0]); + expect(Map.from(jsonDecode(script) as Map), { + 'command': 'tap', + 'timeout': _kSerializedTestTimeout, + 'finderType': 'ByText', + 'text': 'foo', + }); + return jsonEncode(await makeMockResponse({})); + }); + await driver.tap(find.text('foo'), timeout: _kTestTimeout); + }); + }); + + group('getText', () { + test('requires a target reference', () async { + expect(driver.getText(null), throwsA(isInstanceOf())); + }); + + test('sends the getText command', () async { + when(mockConnection.sendCommand(any, any)).thenAnswer((Invocation i) async { + final String script = _checkAndEncode(i.positionalArguments[0]); + expect(Map.from(jsonDecode(script) as Map), { + 'command': 'get_text', + 'timeout': _kSerializedTestTimeout, + 'finderType': 'ByValueKey', + 'keyValueString': '123', + 'keyValueType': 'int', + }); + return jsonEncode(await makeMockResponse({ + 'text': 'hello', + })); + }); + final String result = await driver.getText(find.byValueKey(123), timeout: _kTestTimeout); + expect(result, 'hello'); + }); + }); + + group('waitFor', () { + test('requires a target reference', () async { + expect(driver.waitFor(null), throwsA(isInstanceOf())); + }); + + test('sends the waitFor command', () async { + when(mockConnection.sendCommand(any, any)).thenAnswer((Invocation i) async { + final String script = _checkAndEncode(i.positionalArguments[0]); + expect(Map.from(jsonDecode(script) as Map), { + 'command': 'waitFor', + 'finderType': 'ByTooltipMessage', + 'text': 'foo', + 'timeout': _kSerializedTestTimeout, + }); + return jsonEncode(await makeMockResponse({})); + }); + await driver.waitFor(find.byTooltip('foo'), timeout: _kTestTimeout); + }); + }); + + group('waitForCondition', () { + test('sends the wait for NoPendingFrameCondition command', () async { + when(mockConnection.sendCommand(any, any)).thenAnswer((Invocation i) async { + final String script = _checkAndEncode(i.positionalArguments[0]); + expect(Map.from(jsonDecode(script) as Map), { + 'command': 'waitForCondition', + 'timeout': _kSerializedTestTimeout, + 'conditionName': 'NoPendingFrameCondition', + }); + return jsonEncode(await makeMockResponse({})); + }); + await driver.waitForCondition(const NoPendingFrame(), timeout: _kTestTimeout); + }); + + test('sends the wait for NoPendingPlatformMessages command', () async { + when(mockConnection.sendCommand(any, any)).thenAnswer((Invocation i) async { + final String script = _checkAndEncode(i.positionalArguments[0]); + expect(Map.from(jsonDecode(script) as Map), { + 'command': 'waitForCondition', + 'timeout': _kSerializedTestTimeout, + 'conditionName': 'NoPendingPlatformMessagesCondition', + }); + return jsonEncode(await makeMockResponse({})); + }); + await driver.waitForCondition(const NoPendingPlatformMessages(), timeout: _kTestTimeout); + }); + + test('sends the waitForCondition of combined conditions command', () async { + when(mockConnection.sendCommand(any, any)).thenAnswer((Invocation i) async { + final String script = _checkAndEncode(i.positionalArguments[0]); + expect(Map.from(jsonDecode(script) as Map), { + 'command': 'waitForCondition', + 'timeout': _kSerializedTestTimeout, + 'conditionName': 'CombinedCondition', + 'conditions': '[{"conditionName":"NoPendingFrameCondition"},{"conditionName":"NoTransientCallbacksCondition"}]', + }); + return jsonEncode(await makeMockResponse({})); + }); + const SerializableWaitCondition combinedCondition = + CombinedCondition([NoPendingFrame(), NoTransientCallbacks()]); + await driver.waitForCondition(combinedCondition, timeout: _kTestTimeout); + }); + }); + + group('waitUntilNoTransientCallbacks', () { + test('sends the waitUntilNoTransientCallbacks command', () async { + when(mockConnection.sendCommand(any, any)).thenAnswer((Invocation i) async { + final String script = _checkAndEncode(i.positionalArguments[0]); + expect(Map.from(jsonDecode(script) as Map), { + 'command': 'waitForCondition', + 'timeout': _kSerializedTestTimeout, + 'conditionName': 'NoTransientCallbacksCondition', + }); + return jsonEncode(await makeMockResponse({})); + }); + await driver.waitUntilNoTransientCallbacks(timeout: _kTestTimeout); + }); + }); + + group('getOffset', () { + test('requires a target reference', () async { + expect(driver.getCenter(null), throwsA(isInstanceOf())); + expect(driver.getTopLeft(null), throwsA(isInstanceOf())); + expect(driver.getTopRight(null), throwsA(isInstanceOf())); + expect(driver.getBottomLeft(null), throwsA(isInstanceOf())); + expect(driver.getBottomRight(null), throwsA(isInstanceOf())); + }); + + test('sends the getCenter command', () async { + when(mockConnection.sendCommand(any, any)).thenAnswer((Invocation i) async { + final String script = _checkAndEncode(i.positionalArguments[0]); + expect(Map.from(jsonDecode(script) as Map), { + 'command': 'get_offset', + 'offsetType': 'center', + 'timeout': _kSerializedTestTimeout, + 'finderType': 'ByValueKey', + 'keyValueString': '123', + 'keyValueType': 'int', + }); + return jsonEncode(await makeMockResponse({ + 'dx': 11, + 'dy': 12, + })); + }); + final DriverOffset result = await driver.getCenter(find.byValueKey(123), timeout: _kTestTimeout); + expect(result, const DriverOffset(11, 12)); + }); + + test('sends the getTopLeft command', () async { + when(mockConnection.sendCommand(any, any)).thenAnswer((Invocation i) async { + final String script = _checkAndEncode(i.positionalArguments[0]); + expect(Map.from(jsonDecode(script) as Map), { + 'command': 'get_offset', + 'offsetType': 'topLeft', + 'timeout': _kSerializedTestTimeout, + 'finderType': 'ByValueKey', + 'keyValueString': '123', + 'keyValueType': 'int', + }); + return jsonEncode(await makeMockResponse({ + 'dx': 11, + 'dy': 12, + })); + }); + final DriverOffset result = await driver.getTopLeft(find.byValueKey(123), timeout: _kTestTimeout); + expect(result, const DriverOffset(11, 12)); + }); + + test('sends the getTopRight command', () async { + when(mockConnection.sendCommand(any, any)).thenAnswer((Invocation i) async { + final String script = _checkAndEncode(i.positionalArguments[0]); + expect(Map.from(jsonDecode(script) as Map), { + 'command': 'get_offset', + 'offsetType': 'topRight', + 'timeout': _kSerializedTestTimeout, + 'finderType': 'ByValueKey', + 'keyValueString': '123', + 'keyValueType': 'int', + }); + return jsonEncode(await makeMockResponse({ + 'dx': 11, + 'dy': 12, + })); + }); + final DriverOffset result = await driver.getTopRight(find.byValueKey(123), timeout: _kTestTimeout); + expect(result, const DriverOffset(11, 12)); + }); + + test('sends the getBottomLeft command', () async { + when(mockConnection.sendCommand(any, any)).thenAnswer((Invocation i) async { + final String script = _checkAndEncode(i.positionalArguments[0]); + expect(Map.from(jsonDecode(script) as Map), { + 'command': 'get_offset', + 'offsetType': 'bottomLeft', + 'timeout': _kSerializedTestTimeout, + 'finderType': 'ByValueKey', + 'keyValueString': '123', + 'keyValueType': 'int', + }); + return jsonEncode(await makeMockResponse({ + 'dx': 11, + 'dy': 12, + })); + }); + final DriverOffset result = await driver.getBottomLeft(find.byValueKey(123), timeout: _kTestTimeout); + expect(result, const DriverOffset(11, 12)); + }); + + test('sends the getBottomRight command', () async { + when(mockConnection.sendCommand(any, any)).thenAnswer((Invocation i) async { + final String script = _checkAndEncode(i.positionalArguments[0]); + expect(Map.from(jsonDecode(script) as Map), { + 'command': 'get_offset', + 'offsetType': 'bottomRight', + 'timeout': _kSerializedTestTimeout, + 'finderType': 'ByValueKey', + 'keyValueString': '123', + 'keyValueType': 'int', + }); + return jsonEncode(await makeMockResponse({ + 'dx': 11, + 'dy': 12, + })); + }); + final DriverOffset result = await driver.getBottomRight(find.byValueKey(123), timeout: _kTestTimeout); + expect(result, const DriverOffset(11, 12)); + }); + }); + + test('checks the health of the driver extension', () async { + when(mockConnection.sendCommand(any, any)).thenAnswer((Invocation i) async { + final String script = _checkAndEncode(i.positionalArguments[0]); + expect(Map.from(jsonDecode(script) as Map), { + 'command': 'get_health', + }); + return jsonEncode(await makeMockResponse({'status': 'ok'})); + }); + await driver.checkHealth(); + }); + + group('clearTimeline', () { + test('clears timeline', () async { + await driver.startTracing(); + expect(driver.startTime, isNotNull); + await driver.clearTimeline(); + expect(driver.startTime, isNull); + }); + }); + + group('WebFlutterDriver Unimplemented error', () { + test('forceGC', () async { + expect(driver.forceGC(), + throwsA(isInstanceOf())); + }); + + test('getVmFlags', () async { + expect(driver.getVmFlags(), + throwsA(isInstanceOf())); + }); + + test('waitUntilFirstFrameRasterized', () async { + expect(driver.waitUntilFirstFrameRasterized(), + throwsA(isInstanceOf())); + }); + }); + }); + + group('WebFlutterDriver with non-chrome browser', () { + MockFlutterWebConnection mockConnection; + WebFlutterDriver driver; + + setUp(() { + mockConnection = MockFlutterWebConnection(); + driver = WebFlutterDriver.connectedTo(mockConnection, Browser.edge); + }); + + test('tracing', () async { + expect(driver.traceAction(() async { return Future.value(); }), + throwsA(isInstanceOf())); + expect(driver.startTracing(), + throwsA(isInstanceOf())); + expect(driver.stopTracingAndDownloadTimeline(), + throwsA(isInstanceOf())); + expect(driver.clearTimeline(), + throwsA(isInstanceOf())); + }); + }); +} + +/// This function will verify the format of the script +/// and return the actual script. +/// script will be in the following format: +// window.flutterDriver('[actual script]') +String _checkAndEncode(dynamic script) { + expect(script is String, isTrue); + expect(script.startsWith(_kWebScriptPrefix), isTrue); + expect(script.endsWith(_kWebScriptSuffix), isTrue); + // Strip prefix and suffix + return script.substring(_kWebScriptPrefix.length, script.length - 2) as String; } Future> makeMockResponse( @@ -708,6 +1082,8 @@ class MockVMPauseBreakpointEvent extends Mock implements VMPauseBreakpointEvent class MockVMResumeEvent extends Mock implements VMResumeEvent { } +class MockFlutterWebConnection extends Mock implements FlutterWebConnection { } + class MockPeer extends Mock implements rpc.Peer { @override bool get isClosed => false; diff --git a/packages/flutter_driver/test/src/extension_test.dart b/packages/flutter_driver/test/src/real_tests/extension_test.dart similarity index 100% rename from packages/flutter_driver/test/src/extension_test.dart rename to packages/flutter_driver/test/src/real_tests/extension_test.dart diff --git a/packages/flutter_driver/test/src/find_test.dart b/packages/flutter_driver/test/src/real_tests/find_test.dart similarity index 98% rename from packages/flutter_driver/test/src/find_test.dart rename to packages/flutter_driver/test/src/real_tests/find_test.dart index c258f953d6..b2407e376d 100644 --- a/packages/flutter_driver/test/src/find_test.dart +++ b/packages/flutter_driver/test/src/real_tests/find_test.dart @@ -4,7 +4,7 @@ import 'package:flutter_driver/src/common/find.dart'; -import '../common.dart'; +import '../../common.dart'; void main() { test('Ancestor finder serialize', () { diff --git a/packages/flutter_driver/test/src/real_tests/io_extension_test.dart b/packages/flutter_driver/test/src/real_tests/io_extension_test.dart new file mode 100644 index 0000000000..614d34d910 --- /dev/null +++ b/packages/flutter_driver/test/src/real_tests/io_extension_test.dart @@ -0,0 +1,24 @@ +// Copyright 2014 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter_driver/src/extension/io_extension.dart'; + +import '../../common.dart'; + +void main() { + group('test io_extension',() { + Future> Function(Map) call; + + setUp(() { + call = (Map args) async { + return Future>.value(args); + }; + }); + + test('io_extension should throw exception', () { + expect(() => registerWebServiceExtension(call), + throwsA(isInstanceOf())); + }); + }); +} diff --git a/packages/flutter_driver/test/src/timeline_summary_test.dart b/packages/flutter_driver/test/src/real_tests/timeline_summary_test.dart similarity index 99% rename from packages/flutter_driver/test/src/timeline_summary_test.dart rename to packages/flutter_driver/test/src/real_tests/timeline_summary_test.dart index ad2588b5b8..146fe18726 100644 --- a/packages/flutter_driver/test/src/timeline_summary_test.dart +++ b/packages/flutter_driver/test/src/real_tests/timeline_summary_test.dart @@ -9,7 +9,7 @@ import 'package:flutter_driver/flutter_driver.dart'; import 'package:flutter_driver/src/driver/common.dart'; import 'package:path/path.dart' as path; -import '../common.dart'; +import '../../common.dart'; void main() { group('TimelineSummary', () { diff --git a/packages/flutter_driver/test/src/timeline_test.dart b/packages/flutter_driver/test/src/real_tests/timeline_test.dart similarity index 98% rename from packages/flutter_driver/test/src/timeline_test.dart rename to packages/flutter_driver/test/src/real_tests/timeline_test.dart index ab6aefb3ad..fc29a55455 100644 --- a/packages/flutter_driver/test/src/timeline_test.dart +++ b/packages/flutter_driver/test/src/real_tests/timeline_test.dart @@ -4,7 +4,7 @@ import 'package:flutter_driver/src/driver/timeline.dart'; -import '../common.dart'; +import '../../common.dart'; void main() { group('Timeline', () { diff --git a/packages/flutter_driver/test/src/wait_test.dart b/packages/flutter_driver/test/src/real_tests/wait_test.dart similarity index 99% rename from packages/flutter_driver/test/src/wait_test.dart rename to packages/flutter_driver/test/src/real_tests/wait_test.dart index b7b654218d..bc98af53d9 100644 --- a/packages/flutter_driver/test/src/wait_test.dart +++ b/packages/flutter_driver/test/src/real_tests/wait_test.dart @@ -4,7 +4,7 @@ import 'package:flutter_driver/src/common/wait.dart'; -import '../common.dart'; +import '../../common.dart'; void main() { group('WaitForCondition', () { diff --git a/packages/flutter_driver/test/src/real_tests/web_driver_config_test.dart b/packages/flutter_driver/test/src/real_tests/web_driver_config_test.dart new file mode 100644 index 0000000000..b6afbf8cc0 --- /dev/null +++ b/packages/flutter_driver/test/src/real_tests/web_driver_config_test.dart @@ -0,0 +1,149 @@ +// Copyright 2014 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter_driver/src/driver/web_driver_config.dart'; +import 'package:webdriver/sync_io.dart' as sync_io; + +import '../../common.dart'; + +void main() { + group('getDesiredCapabilities', () { + test('Chrome with headless on', () { + final Map expected = { + 'acceptInsecureCerts': true, + 'browserName': 'chrome', + 'goog:loggingPrefs': { sync_io.LogType.performance: 'ALL'}, + 'chromeOptions': { + 'args': [ + '--bwsi', + '--disable-background-timer-throttling', + '--disable-default-apps', + '--disable-extensions', + '--disable-popup-blocking', + '--disable-translate', + '--no-default-browser-check', + '--no-sandbox', + '--no-first-run', + '--headless' + ], + 'perfLoggingPrefs': { + 'traceCategories': + 'devtools.timeline,' + 'v8,blink.console,benchmark,blink,' + 'blink.user_timing' + } + } + }; + + expect(getDesiredCapabilities(Browser.chrome, true), expected); + }); + + test('Chrome with headless off', () { + final Map expected = { + 'acceptInsecureCerts': true, + 'browserName': 'chrome', + 'goog:loggingPrefs': { sync_io.LogType.performance: 'ALL'}, + 'chromeOptions': { + 'args': [ + '--bwsi', + '--disable-background-timer-throttling', + '--disable-default-apps', + '--disable-extensions', + '--disable-popup-blocking', + '--disable-translate', + '--no-default-browser-check', + '--no-sandbox', + '--no-first-run', + ], + 'perfLoggingPrefs': { + 'traceCategories': + 'devtools.timeline,' + 'v8,blink.console,benchmark,blink,' + 'blink.user_timing' + } + } + }; + + expect(getDesiredCapabilities(Browser.chrome, false), expected); + + }); + + test('Firefox with headless on', () { + final Map expected = { + 'acceptInsecureCerts': true, + 'browserName': 'firefox', + 'moz:firefoxOptions' : { + 'args': ['-headless'], + 'prefs': { + 'dom.file.createInChild': true, + 'dom.timeout.background_throttling_max_budget': -1, + 'media.autoplay.default': 0, + 'media.gmp-manager.url': '', + 'media.gmp-provider.enabled': false, + 'network.captive-portal-service.enabled': false, + 'security.insecure_field_warning.contextual.enabled': false, + 'test.currentTimeOffsetSeconds': 11491200 + }, + 'log': {'level': 'trace'} + } + }; + + expect(getDesiredCapabilities(Browser.firefox, true), expected); + }); + + test('Firefox with headless off', () { + final Map expected = { + 'acceptInsecureCerts': true, + 'browserName': 'firefox', + 'moz:firefoxOptions' : { + 'args': [], + 'prefs': { + 'dom.file.createInChild': true, + 'dom.timeout.background_throttling_max_budget': -1, + 'media.autoplay.default': 0, + 'media.gmp-manager.url': '', + 'media.gmp-provider.enabled': false, + 'network.captive-portal-service.enabled': false, + 'security.insecure_field_warning.contextual.enabled': false, + 'test.currentTimeOffsetSeconds': 11491200 + }, + 'log': {'level': 'trace'} + } + }; + + expect(getDesiredCapabilities(Browser.firefox, false), expected); + }); + + test('Edge', () { + final Map expected = { + 'acceptInsecureCerts': true, + 'browserName': 'edge', + }; + + expect(getDesiredCapabilities(Browser.edge, false), expected); + }); + + test('macOS Safari', () { + final Map expected = { + 'browserName': 'safari', + 'safari.options': { + 'skipExtensionInstallation': true, + 'cleanSession': true + } + }; + + expect(getDesiredCapabilities(Browser.safari, false), expected); + }); + + test('iOS Safari', () { + final Map expected = { + 'platformName': 'ios', + 'browserName': 'safari', + 'safari:useSimulator': true + }; + + expect(getDesiredCapabilities(Browser.iosSafari, false), expected); + }); + }); +} diff --git a/packages/flutter_driver/test/src/web_tests/web_extension_test.dart b/packages/flutter_driver/test/src/web_tests/web_extension_test.dart new file mode 100644 index 0000000000..432ca13cda --- /dev/null +++ b/packages/flutter_driver/test/src/web_tests/web_extension_test.dart @@ -0,0 +1,26 @@ +// Copyright 2014 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'dart:js' as js; + +import 'package:flutter_driver/src/extension/web_extension.dart'; +import 'package:flutter_test/flutter_test.dart'; + +void main() { + group('test web_extension', () { + Future> Function(Map) call; + + setUp(() { + call = (Map args) async { + return Future>.value(args); + }; + }); + + test('web_extension should register a function', () { + expect(() => registerWebServiceExtension(call), + returnsNormally); + expect(js.context.hasProperty('\$flutterDriver'), true); + }); + }); +} diff --git a/packages/flutter_tools/lib/src/commands/drive.dart b/packages/flutter_tools/lib/src/commands/drive.dart index cce1022c67..5245c611e1 100644 --- a/packages/flutter_tools/lib/src/commands/drive.dart +++ b/packages/flutter_tools/lib/src/commands/drive.dart @@ -69,6 +69,34 @@ class DriveCommand extends RunCommandBase { ..addFlag('build', defaultsTo: true, help: 'Build the app before running.', + ) + ..addOption('driver-port', + defaultsTo: '4444', + help: 'The port where Webdriver server is launched at. Defaults to 4444.', + valueHelp: '4444' + ) + ..addFlag('headless', + defaultsTo: true, + help: 'Whether the driver browser is going to be launched in headless mode. Defaults to true.', + ) + ..addOption('browser-name', + defaultsTo: 'chrome', + help: 'Name of browser where tests will be executed. \n' + 'Following browsers are supported: \n' + 'Chrome, Firefox, Safari (macOS and iOS) and Edge. Defaults to Chrome.', + allowed: [ + 'chrome', + 'edge', + 'firefox', + 'ios-safari', + 'safari', + ] + ) + ..addOption('browser-dimension', + defaultsTo: '1600,1024', + help: 'The dimension of browser when running Flutter Web test. \n' + 'This will affect screenshot and all offset-related actions. \n' + 'By default. it is set to 1600,1024 (1600 by 1024).', ); } @@ -133,8 +161,16 @@ class DriveCommand extends RunCommandBase { Cache.releaseLockEarly(); + final Map environment = { + 'VM_SERVICE_URL': observatoryUri, + 'SELENIUM_PORT': argResults['driver-port'].toString(), + 'BROWSER_NAME': argResults['browser-name'].toString(), + 'BROWSER_DIMENSION': argResults['browser-dimension'].toString(), + 'HEADLESS': argResults['headless'].toString(), + }; + try { - await testRunner([testFile], observatoryUri); + await testRunner([testFile], environment); } catch (error, stackTrace) { if (error is ToolExit) { rethrow; @@ -291,13 +327,13 @@ Future _startApp(DriveCommand command) async { } /// Runs driver tests. -typedef TestRunner = Future Function(List testArgs, String observatoryUri); +typedef TestRunner = Future Function(List testArgs, Map environment); TestRunner testRunner = _runTests; void restoreTestRunner() { testRunner = _runTests; } -Future _runTests(List testArgs, String observatoryUri) async { +Future _runTests(List testArgs, Map environment) async { printTrace('Running driver tests.'); PackageMap.globalPackagesPath = fs.path.normalize(fs.path.absolute(PackageMap.globalPackagesPath)); @@ -310,7 +346,7 @@ Future _runTests(List testArgs, String observatoryUri) async { '--packages=${PackageMap.globalPackagesPath}', '-rexpanded', ], - environment: {'VM_SERVICE_URL': observatoryUri}, + environment: environment, ); if (result != 0) { throwToolExit('Driver tests failed: $result', exitCode: result); diff --git a/packages/flutter_tools/pubspec.yaml b/packages/flutter_tools/pubspec.yaml index 374b48fc72..dee806add7 100644 --- a/packages/flutter_tools/pubspec.yaml +++ b/packages/flutter_tools/pubspec.yaml @@ -11,9 +11,9 @@ dependencies: # To update these, use "flutter update-packages --force-upgrade". archive: 2.0.11 args: 1.5.2 - dwds: 0.8.1 + dwds: 0.8.5 completion: 0.2.1+1 - coverage: 0.13.3+1 + coverage: 0.13.3+3 crypto: 2.1.3 file: 5.1.0 http: 0.12.0+2 @@ -46,7 +46,7 @@ dependencies: test_core: 0.2.15 # Code generation dependencies - build_runner_core: 4.2.0 + build_runner_core: 4.3.0 dart_style: 1.3.3 code_builder: 3.2.1 build: 1.2.2 @@ -118,7 +118,7 @@ dev_dependencies: test: 1.9.4 build_runner: 1.7.2 build_vm_compilers: 1.0.4 - build_test: 0.10.10 + build_test: 0.10.11 multi_server_socket: 1.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" node_preamble: 1.4.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -128,4 +128,4 @@ dartdoc: # Exclude this package from the hosted API docs. nodoc: true -# PUBSPEC CHECKSUM: de88 +# PUBSPEC CHECKSUM: 6e90 diff --git a/packages/flutter_tools/test/commands.shard/hermetic/drive_test.dart b/packages/flutter_tools/test/commands.shard/hermetic/drive_test.dart index cdf4ff5333..3e17f8f492 100644 --- a/packages/flutter_tools/test/commands.shard/hermetic/drive_test.dart +++ b/packages/flutter_tools/test/commands.shard/hermetic/drive_test.dart @@ -46,7 +46,7 @@ void main() { appStarter = (DriveCommand command) { throw 'Unexpected call to appStarter'; }; - testRunner = (List testArgs, String observatoryUri) { + testRunner = (List testArgs, Map environment) { throw 'Unexpected call to testRunner'; }; appStopper = (DriveCommand command) { @@ -171,8 +171,16 @@ void main() { appStarter = expectAsync1((DriveCommand command) async { return LaunchResult.succeeded(); }); - testRunner = expectAsync2((List testArgs, String observatoryUri) async { + testRunner = expectAsync2((List testArgs, Map environment) async { expect(testArgs, [testFile]); + // VM_SERVICE_URL is not set by drive command arguments + expect(environment, { + 'VM_SERVICE_URL': 'null', + 'SELENIUM_PORT': '4567', + 'BROWSER_NAME': 'firefox', + 'BROWSER_DIMENSION': '1024,768', + 'HEADLESS': 'false', + }); return null; }); appStopper = expectAsync1((DriveCommand command) async { @@ -187,6 +195,10 @@ void main() { 'drive', '--target=$testApp', '--no-pub', + '--no-headless', + '--driver-port=4567', + '--browser-name=firefox', + '--browser-dimension=1024,768', ]; await createTestCommandRunner(command).run(args); expect(testLogger.errorText, isEmpty); @@ -204,7 +216,7 @@ void main() { appStarter = expectAsync1((DriveCommand command) async { return LaunchResult.succeeded(); }); - testRunner = (List testArgs, String observatoryUri) async { + testRunner = (List testArgs, Map environment) async { throwToolExit(null, exitCode: 123); }; appStopper = expectAsync1((DriveCommand command) async { @@ -361,7 +373,7 @@ void main() { testApp = fs.path.join(tempDir.path, 'test', 'e2e.dart'); testFile = fs.path.join(tempDir.path, 'test_driver', 'e2e_test.dart'); - testRunner = (List testArgs, String observatoryUri) async { + testRunner = (List testArgs, Map environment) async { throwToolExit(null, exitCode: 123); }; appStopper = expectAsync1( @@ -494,7 +506,7 @@ void main() { testApp = fs.path.join(tempDir.path, 'test', 'e2e.dart'); testFile = fs.path.join(tempDir.path, 'test_driver', 'e2e_test.dart'); - testRunner = (List testArgs, String observatoryUri) async { + testRunner = (List testArgs, Map environment) async { throwToolExit(null, exitCode: 123); }; appStopper = expectAsync1( diff --git a/packages/fuchsia_remote_debug_protocol/pubspec.yaml b/packages/fuchsia_remote_debug_protocol/pubspec.yaml index 48c02e1360..82a6b83f3a 100644 --- a/packages/fuchsia_remote_debug_protocol/pubspec.yaml +++ b/packages/fuchsia_remote_debug_protocol/pubspec.yaml @@ -40,14 +40,16 @@ dependencies: stack_trace: 1.9.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" stream_channel: 2.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" string_scanner: 1.0.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + sync_http: 0.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" term_glyph: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" test_api: 0.2.11 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" typed_data: 1.1.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vector_math: 2.0.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vm_service_client: 0.2.6+2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + webdriver: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" xml: 3.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" dev_dependencies: mockito: 4.1.1 -# PUBSPEC CHECKSUM: a765 +# PUBSPEC CHECKSUM: 1daa