diff --git a/.cirrus.yml b/.cirrus.yml index 8120b79842d3..8c8cc624d1ee 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -7,7 +7,7 @@ task: cpu: 8 memory: 16G env: - E2E_PATH: "./packages/e2e" + INTEGRATION_TEST_PATH: "./packages/integration_test" upgrade_script: - flutter channel stable - flutter upgrade @@ -47,9 +47,9 @@ task: - if [[ "$CHANNEL" -eq "stable" ]]; then find . | grep _web$ | xargs rm -rf; fi - flutter channel $CHANNEL - ./script/build_all_plugins_app.sh apk - - name: e2e_web_smoke_test - # Tests e2e example test in web. - only_if: "changesInclude('.cirrus.yml', 'packages/e2e/**') || $CIRRUS_PR == ''" + - name: integration_web_smoke_test + # Tests integration example test in web. + only_if: "changesInclude('.cirrus.yml', 'packages/integration_test/**') || $CIRRUS_PR == ''" install_script: - flutter config --enable-web - git clone https://github.com/flutter/web_installers.git @@ -58,13 +58,15 @@ task: - dart lib/web_driver_installer.dart chromedriver --install-only - ./chromedriver/chromedriver --port=4444 & test_script: - - cd $E2E_PATH/example/ - - flutter drive -v --target=test_driver/example_e2e.dart -d web-server --release --browser-name=chrome + - cd $INTEGRATION_TEST_PATH/example/ + - flutter drive -v --target=test_driver/example_integration.dart -d web-server --release --browser-name=chrome - name: build-apks+java-test+firebase-test-lab env: matrix: - PLUGIN_SHARDING: "--shardIndex 0 --shardCount 2" - PLUGIN_SHARDING: "--shardIndex 1 --shardCount 2" + PLUGIN_SHARDING: "--shardIndex 0 --shardCount 4" + PLUGIN_SHARDING: "--shardIndex 1 --shardCount 4" + PLUGIN_SHARDING: "--shardIndex 2 --shardCount 4" + PLUGIN_SHARDING: "--shardIndex 3 --shardCount 4" matrix: CHANNEL: "master" CHANNEL: "stable" @@ -105,7 +107,7 @@ task: cpu: 8 memory: 16G env: - E2E_PATH: "./packages/e2e" + INTEGRATION_TEST_PATH: "./packages/integration_test" upgrade_script: - flutter channel stable - flutter upgrade @@ -157,7 +159,7 @@ task: - find . -name "*.podspec" | xargs grep -l "osx" | xargs rm # Skip the dummy podspecs used to placate the tool. - find . -name "*_web*.podspec" -o -name "*_mac*.podspec" | xargs rm - - ./script/incremental_build.sh podspecs --no-analyze camera --ignore-warnings camera + - ./script/incremental_build.sh podspecs - name: build-ipas+drive-examples env: PATH: $PATH:/usr/local/bin diff --git a/CODEOWNERS b/CODEOWNERS index 51a9407127c9..97f8bf388697 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -10,11 +10,11 @@ packages/battery/* @amirh @matthew-carroll packages/camera/* @bparrishMines packages/connectivity/* @cyanglaz @matthew-carroll packages/device_info/* @matthew-carroll -packages/e2e/* @collinjackson @digiter packages/espresso/* @collinjackson @adazh packages/google_maps_flutter/* @cyanglaz packages/google_sign_in/* @cyanglaz @mehmetf packages/image_picker/* @cyanglaz +packages/integration_test/* @dnfield packages/in_app_purchase/* @mklim @cyanglaz @LHLL packages/ios_platform_images/* @gaaclarke packages/package_info/* @cyanglaz @matthew-carroll diff --git a/README.md b/README.md index 026dd9d7739b..b2015a705e79 100644 --- a/README.md +++ b/README.md @@ -44,12 +44,13 @@ These are the available plugins in this repository. | [camera](./packages/camera/) | [![pub package](https://img.shields.io/pub/v/camera.svg)](https://pub.dev/packages/camera) | | [connectivity](./packages/connectivity/) | [![pub package](https://img.shields.io/pub/v/connectivity.svg)](https://pub.dev/packages/connectivity) | | [device_info](./packages/device_info/) | [![pub package](https://img.shields.io/pub/v/device_info.svg)](https://pub.dev/packages/device_info) | -| [e2e](./packages/e2e/) | [![pub package](https://img.shields.io/pub/v/e2e.svg)](https://pub.dev/packages/e2e) | +| [e2e (Discontinued, use integration_test)](./packages/e2e/) | [![pub package](https://img.shields.io/pub/v/e2e.svg)](https://pub.dev/packages/e2e) | | [espresso](./packages/espresso/) | [![pub package](https://img.shields.io/pub/v/espresso.svg)](https://pub.dev/packages/espresso) | | [flutter_plugin_android_lifecycle](./packages/flutter_plugin_android_lifecycle/) | [![pub package](https://img.shields.io/pub/v/flutter_plugin_android_lifecycle.svg)](https://pub.dev/packages/flutter_plugin_android_lifecycle) | | [google_maps_flutter](./packages/google_maps_flutter) | [![pub package](https://img.shields.io/pub/v/google_maps_flutter.svg)](https://pub.dev/packages/google_maps_flutter) | | [google_sign_in](./packages/google_sign_in/) | [![pub package](https://img.shields.io/pub/v/google_sign_in.svg)](https://pub.dev/packages/google_sign_in) | | [image_picker](./packages/image_picker/) | [![pub package](https://img.shields.io/pub/v/image_picker.svg)](https://pub.dev/packages/image_picker) | +| [integration_test](./packages/integration_test/) | [![pub package](https://img.shields.io/pub/v/integration_test.svg)](https://pub.dev/packages/integration_test) | | [in_app_purchase](./packages/in_app_purchase/) | [![pub package](https://img.shields.io/pub/v/in_app_purchase.svg)](https://pub.dev/packages/in_app_purchase) | | [ios_platform_images](./packages/ios_platform_images/) | [![pub package](https://img.shields.io/pub/v/ios_platform_images.svg)](https://pub.dev/packages/ios_platform_images) | | [local_auth](./packages/local_auth/) | [![pub package](https://img.shields.io/pub/v/local_auth.svg)](https://pub.dev/packages/local_auth) | diff --git a/packages/android_alarm_manager/CHANGELOG.md b/packages/android_alarm_manager/CHANGELOG.md index 689429dc08f2..faa2c731873d 100644 --- a/packages/android_alarm_manager/CHANGELOG.md +++ b/packages/android_alarm_manager/CHANGELOG.md @@ -1,3 +1,8 @@ +## 0.4.5+12 + +* Update package:e2e reference to use the local version in the flutter/plugins + repository. + ## 0.4.5+11 * Update lower bound of dart dependency to 2.1.0. diff --git a/packages/android_alarm_manager/example/android/app/src/androidTest/java/io/plugins/androidalarmmanager/MainActivityTest.java b/packages/android_alarm_manager/example/android/app/src/androidTest/java/io/plugins/androidalarmmanager/MainActivityTest.java index 04aef18888a9..373e770697d5 100644 --- a/packages/android_alarm_manager/example/android/app/src/androidTest/java/io/plugins/androidalarmmanager/MainActivityTest.java +++ b/packages/android_alarm_manager/example/android/app/src/androidTest/java/io/plugins/androidalarmmanager/MainActivityTest.java @@ -5,7 +5,7 @@ package io.flutter.plugins.androidalarmmanagerexample; import androidx.test.rule.ActivityTestRule; -import dev.flutter.plugins.e2e.FlutterTestRunner; +import dev.flutter.plugins.integration_test.FlutterTestRunner; import io.flutter.embedding.android.FlutterActivity; import org.junit.Rule; import org.junit.runner.RunWith; diff --git a/packages/android_alarm_manager/example/pubspec.yaml b/packages/android_alarm_manager/example/pubspec.yaml index 2fc191881c10..93cbc57d8de5 100644 --- a/packages/android_alarm_manager/example/pubspec.yaml +++ b/packages/android_alarm_manager/example/pubspec.yaml @@ -7,7 +7,8 @@ dependencies: android_alarm_manager: path: ../ shared_preferences: ^0.5.6 - e2e: 0.3.0 + integration_test: + path: ../../integration_test path_provider: ^1.3.1 dev_dependencies: diff --git a/packages/android_alarm_manager/example/test_driver/android_alarm_manager_e2e.dart b/packages/android_alarm_manager/example/test_driver/android_alarm_manager_e2e.dart index a5bc1ac0ba48..4d2e3201eecf 100644 --- a/packages/android_alarm_manager/example/test_driver/android_alarm_manager_e2e.dart +++ b/packages/android_alarm_manager/example/test_driver/android_alarm_manager_e2e.dart @@ -6,7 +6,7 @@ import 'dart:async'; import 'dart:io'; import 'package:android_alarm_manager_example/main.dart' as app; import 'package:android_alarm_manager/android_alarm_manager.dart'; -import 'package:e2e/e2e.dart'; +import 'package:integration_test/integration_test.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_driver/driver_extension.dart'; import 'package:path_provider/path_provider.dart'; @@ -55,7 +55,7 @@ void appMain() { } void main() { - E2EWidgetsFlutterBinding.ensureInitialized(); + IntegrationTestWidgetsFlutterBinding.ensureInitialized(); setUp(() async { await AndroidAlarmManager.initialize(); diff --git a/packages/android_alarm_manager/example/test_driver/android_alarm_manager_e2e_test.dart b/packages/android_alarm_manager/example/test_driver/android_alarm_manager_e2e_test.dart index eea5e8abc15f..4e32b483f8d7 100644 --- a/packages/android_alarm_manager/example/test_driver/android_alarm_manager_e2e_test.dart +++ b/packages/android_alarm_manager/example/test_driver/android_alarm_manager_e2e_test.dart @@ -3,6 +3,7 @@ // BSD-style license that can be found in the LICENSE file. import 'dart:async'; +import 'dart:convert'; import 'dart:io'; import 'package:flutter_driver/flutter_driver.dart'; @@ -33,9 +34,12 @@ Future main() async { // for this plugin will need to be resumed for the test to pass. final StreamSubscription subscription = await resumeIsolatesOnPause(driver); - final String result = - await driver.requestData(null, timeout: const Duration(minutes: 5)); + final String data = await driver.requestData( + null, + timeout: const Duration(minutes: 1), + ); await driver.close(); await subscription.cancel(); - exit(result == 'pass' ? 0 : 1); + final Map result = jsonDecode(data); + exit(result['result'] == 'true' ? 0 : 1); } diff --git a/packages/android_intent/example/android/app/src/androidTestDebug/java/io/flutter/plugins/androidintentexample/EmbeddingV1ActivityTest.java b/packages/android_intent/example/android/app/src/androidTestDebug/java/io/flutter/plugins/androidintentexample/EmbeddingV1ActivityTest.java index db000f0f995c..7ab0e87e7c5a 100644 --- a/packages/android_intent/example/android/app/src/androidTestDebug/java/io/flutter/plugins/androidintentexample/EmbeddingV1ActivityTest.java +++ b/packages/android_intent/example/android/app/src/androidTestDebug/java/io/flutter/plugins/androidintentexample/EmbeddingV1ActivityTest.java @@ -1,11 +1,11 @@ package io.flutter.plugins.androidintentexample; import androidx.test.rule.ActivityTestRule; -import dev.flutter.plugins.e2e.FlutterRunner; +import dev.flutter.plugins.integration_test.FlutterTestRunner; import org.junit.Rule; import org.junit.runner.RunWith; -@RunWith(FlutterRunner.class) +@RunWith(FlutterTestRunner.class) public class EmbeddingV1ActivityTest { @Rule public ActivityTestRule rule = diff --git a/packages/android_intent/example/android/app/src/androidTestDebug/java/io/flutter/plugins/androidintentexample/MainActivityTest.java b/packages/android_intent/example/android/app/src/androidTestDebug/java/io/flutter/plugins/androidintentexample/MainActivityTest.java index d390dcd74997..619dbcd853e7 100644 --- a/packages/android_intent/example/android/app/src/androidTestDebug/java/io/flutter/plugins/androidintentexample/MainActivityTest.java +++ b/packages/android_intent/example/android/app/src/androidTestDebug/java/io/flutter/plugins/androidintentexample/MainActivityTest.java @@ -1,11 +1,11 @@ package io.flutter.plugins.androidintentexample; import androidx.test.rule.ActivityTestRule; -import dev.flutter.plugins.e2e.FlutterRunner; +import dev.flutter.plugins.integration_test.FlutterTestRunner; import org.junit.Rule; import org.junit.runner.RunWith; -@RunWith(FlutterRunner.class) +@RunWith(FlutterTestRunner.class) public class MainActivityTest { @Rule public ActivityTestRule rule = new ActivityTestRule<>(MainActivity.class); } diff --git a/packages/android_intent/example/pubspec.yaml b/packages/android_intent/example/pubspec.yaml index 22ff833f8198..31d434e8c038 100644 --- a/packages/android_intent/example/pubspec.yaml +++ b/packages/android_intent/example/pubspec.yaml @@ -8,7 +8,8 @@ dependencies: path: ../ dev_dependencies: - e2e: "^0.2.1" + integration_test: + path: ../../integration_test flutter_driver: sdk: flutter pedantic: ^1.8.0 diff --git a/packages/android_intent/example/test_driver/android_intent_e2e.dart b/packages/android_intent/example/test_driver/android_intent_e2e.dart index 880e7efee76c..78a667b27a09 100644 --- a/packages/android_intent/example/test_driver/android_intent_e2e.dart +++ b/packages/android_intent/example/test_driver/android_intent_e2e.dart @@ -2,7 +2,7 @@ import 'dart:io'; import 'package:android_intent/android_intent.dart'; import 'package:android_intent_example/main.dart'; -import 'package:e2e/e2e.dart'; +import 'package:integration_test/integration_test.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; @@ -12,7 +12,7 @@ import 'package:flutter_test/flutter_test.dart'; /// possible to meaningfully test it through its Dart interface currently. There /// are more useful unit tests for the platform logic under android/src/test/. void main() { - E2EWidgetsFlutterBinding.ensureInitialized(); + IntegrationTestWidgetsFlutterBinding.ensureInitialized(); testWidgets('Embedding example app loads', (WidgetTester tester) async { // Build our app and trigger a frame. await tester.pumpWidget(MyApp()); diff --git a/packages/android_intent/example/test_driver/android_intent_e2e_test.dart b/packages/android_intent/example/test_driver/android_intent_e2e_test.dart index 6147d44df2ec..34483b996049 100644 --- a/packages/android_intent/example/test_driver/android_intent_e2e_test.dart +++ b/packages/android_intent/example/test_driver/android_intent_e2e_test.dart @@ -1,12 +1,16 @@ import 'dart:async'; +import 'dart:convert'; import 'dart:io'; import 'package:flutter_driver/flutter_driver.dart'; Future main() async { final FlutterDriver driver = await FlutterDriver.connect(); - final String result = - await driver.requestData(null, timeout: const Duration(minutes: 1)); + final String data = await driver.requestData( + null, + timeout: const Duration(minutes: 1), + ); await driver.close(); - exit(result == 'pass' ? 0 : 1); + final Map result = jsonDecode(data); + exit(result['result'] == 'true' ? 0 : 1); } diff --git a/packages/battery/CHANGELOG.md b/packages/battery/CHANGELOG.md index 2229fb13f291..c47879ce0419 100644 --- a/packages/battery/CHANGELOG.md +++ b/packages/battery/CHANGELOG.md @@ -1,3 +1,13 @@ +## 1.0.3 + +* Update package:e2e to use package:integration_test + + +## 1.0.2 + +* Update package:e2e reference to use the local version in the flutter/plugins + repository. + ## 1.0.1 * Update lower bound of dart dependency to 2.1.0. diff --git a/packages/battery/example/android/app/src/androidTest/java/io/flutter/plugins/battery/EmbedderV1ActivityTest.java b/packages/battery/example/android/app/src/androidTest/java/io/flutter/plugins/battery/EmbedderV1ActivityTest.java index ef6e5d9fe246..1bd860eb147c 100644 --- a/packages/battery/example/android/app/src/androidTest/java/io/flutter/plugins/battery/EmbedderV1ActivityTest.java +++ b/packages/battery/example/android/app/src/androidTest/java/io/flutter/plugins/battery/EmbedderV1ActivityTest.java @@ -5,11 +5,11 @@ package io.flutter.plugins.batteryexample; import androidx.test.rule.ActivityTestRule; -import dev.flutter.plugins.e2e.FlutterRunner; +import dev.flutter.plugins.integration_test.FlutterTestRunner; import org.junit.Rule; import org.junit.runner.RunWith; -@RunWith(FlutterRunner.class) +@RunWith(FlutterTestRunner.class) public class EmbedderV1ActivityTest { @Rule public ActivityTestRule rule = diff --git a/packages/battery/example/android/app/src/androidTest/java/io/flutter/plugins/battery/FlutterActivityTest.java b/packages/battery/example/android/app/src/androidTest/java/io/flutter/plugins/battery/FlutterActivityTest.java index 1986d0a55c32..636c716d7a91 100644 --- a/packages/battery/example/android/app/src/androidTest/java/io/flutter/plugins/battery/FlutterActivityTest.java +++ b/packages/battery/example/android/app/src/androidTest/java/io/flutter/plugins/battery/FlutterActivityTest.java @@ -5,12 +5,12 @@ package io.flutter.plugins.batteryexample; import androidx.test.rule.ActivityTestRule; -import dev.flutter.plugins.e2e.FlutterRunner; +import dev.flutter.plugins.integration_test.FlutterTestRunner; import io.flutter.embedding.android.FlutterActivity; import org.junit.Rule; import org.junit.runner.RunWith; -@RunWith(FlutterRunner.class) +@RunWith(FlutterTestRunner.class) public class FlutterActivityTest { @Rule public ActivityTestRule rule = new ActivityTestRule<>(FlutterActivity.class); diff --git a/packages/battery/example/android/app/src/main/java/io/flutter/plugins/batteryexample/EmbedderV1Activity.java b/packages/battery/example/android/app/src/main/java/io/flutter/plugins/batteryexample/EmbedderV1Activity.java index 7ccc9c1e2fd3..5fa885cdd9d8 100644 --- a/packages/battery/example/android/app/src/main/java/io/flutter/plugins/batteryexample/EmbedderV1Activity.java +++ b/packages/battery/example/android/app/src/main/java/io/flutter/plugins/batteryexample/EmbedderV1Activity.java @@ -5,7 +5,7 @@ package io.flutter.plugins.batteryexample; import android.os.Bundle; -import dev.flutter.plugins.e2e.E2EPlugin; +import dev.flutter.plugins.integration_test.IntegrationTestPlugin; import io.flutter.app.FlutterActivity; import io.flutter.plugins.battery.BatteryPlugin; @@ -14,6 +14,7 @@ public class EmbedderV1Activity extends FlutterActivity { protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); BatteryPlugin.registerWith(registrarFor("io.flutter.plugins.battery.BatteryPlugin")); - E2EPlugin.registerWith(registrarFor("dev.flutter.plugins.e2e.E2EPlugin")); + IntegrationTestPlugin.registerWith( + registrarFor("dev.flutter.plugins.integration_test.IntegrationTestPlugin")); } } diff --git a/packages/battery/example/pubspec.yaml b/packages/battery/example/pubspec.yaml index 0788d02a9431..5ec38f6ce5c2 100644 --- a/packages/battery/example/pubspec.yaml +++ b/packages/battery/example/pubspec.yaml @@ -10,7 +10,8 @@ dependencies: dev_dependencies: flutter_driver: sdk: flutter - e2e: ^0.2.1 + integration_test: + path: ../../integration_test pedantic: ^1.8.0 flutter: diff --git a/packages/battery/pubspec.yaml b/packages/battery/pubspec.yaml index 6ad8fcfad97a..7a02f37bab85 100644 --- a/packages/battery/pubspec.yaml +++ b/packages/battery/pubspec.yaml @@ -2,7 +2,7 @@ name: battery description: Flutter plugin for accessing information about the battery state (full, charging, discharging) on Android and iOS. homepage: https://github.com/flutter/plugins/tree/master/packages/battery -version: 1.0.1 +version: 1.0.3 flutter: plugin: @@ -24,7 +24,8 @@ dev_dependencies: mockito: 3.0.0 flutter_test: sdk: flutter - e2e: ^0.2.1 + integration_test: + path: ../integration_test pedantic: ^1.8.0 environment: diff --git a/packages/battery/test/battery_e2e.dart b/packages/battery/test/battery_e2e.dart index 6ffc7e6541fb..ed7b6fe5a0e4 100644 --- a/packages/battery/test/battery_e2e.dart +++ b/packages/battery/test/battery_e2e.dart @@ -4,10 +4,10 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:battery/battery.dart'; -import 'package:e2e/e2e.dart'; +import 'package:integration_test/integration_test.dart'; void main() { - E2EWidgetsFlutterBinding.ensureInitialized(); + IntegrationTestWidgetsFlutterBinding.ensureInitialized(); testWidgets('Can get battery level', (WidgetTester tester) async { final Battery battery = Battery(); diff --git a/packages/camera/CHANGELOG.md b/packages/camera/CHANGELOG.md index 43e5f463604c..2cf34dd55588 100644 --- a/packages/camera/CHANGELOG.md +++ b/packages/camera/CHANGELOG.md @@ -1,6 +1,14 @@ +## 0.5.8+5 + +* Fix compilation/availability issues on iOS. + +## 0.5.8+4 + +* Fixed bug caused by casting a `CameraAccessException` on Android. + ## 0.5.8+3 -* Fix bug in usage example in README.md +* Fix bug in usage example in README.md ## 0.5.8+2 diff --git a/packages/camera/android/src/main/java/io/flutter/plugins/camera/MethodCallHandlerImpl.java b/packages/camera/android/src/main/java/io/flutter/plugins/camera/MethodCallHandlerImpl.java index cb58d19a9a02..132075555f26 100644 --- a/packages/camera/android/src/main/java/io/flutter/plugins/camera/MethodCallHandlerImpl.java +++ b/packages/camera/android/src/main/java/io/flutter/plugins/camera/MethodCallHandlerImpl.java @@ -167,8 +167,10 @@ private void instantiateCamera(MethodCall call, Result result) throws CameraAcce private void handleException(Exception exception, Result result) { if (exception instanceof CameraAccessException) { result.error("CameraAccess", exception.getMessage(), null); + return; } + // CameraAccessException can not be cast to a RuntimeException. throw (RuntimeException) exception; } } diff --git a/packages/camera/example/android/app/src/androidTestDebug/java/io/flutter/plugins/cameraexample/EmbeddingV1ActivityTest.java b/packages/camera/example/android/app/src/androidTestDebug/java/io/flutter/plugins/cameraexample/EmbeddingV1ActivityTest.java index 95b5f4373b62..3149191b478d 100644 --- a/packages/camera/example/android/app/src/androidTestDebug/java/io/flutter/plugins/cameraexample/EmbeddingV1ActivityTest.java +++ b/packages/camera/example/android/app/src/androidTestDebug/java/io/flutter/plugins/cameraexample/EmbeddingV1ActivityTest.java @@ -1,11 +1,11 @@ package io.flutter.plugins.cameraexample; import androidx.test.rule.ActivityTestRule; -import dev.flutter.plugins.e2e.FlutterRunner; +import dev.flutter.plugins.integration_test.FlutterTestRunner; import org.junit.Rule; import org.junit.runner.RunWith; -@RunWith(FlutterRunner.class) +@RunWith(FlutterTestRunner.class) public class EmbeddingV1ActivityTest { @Rule public ActivityTestRule rule = diff --git a/packages/camera/example/android/app/src/androidTestDebug/java/io/flutter/plugins/cameraexample/FlutterActivityTest.java b/packages/camera/example/android/app/src/androidTestDebug/java/io/flutter/plugins/cameraexample/FlutterActivityTest.java index 474e3b7e19c6..c90c66defc32 100644 --- a/packages/camera/example/android/app/src/androidTestDebug/java/io/flutter/plugins/cameraexample/FlutterActivityTest.java +++ b/packages/camera/example/android/app/src/androidTestDebug/java/io/flutter/plugins/cameraexample/FlutterActivityTest.java @@ -1,12 +1,12 @@ package io.flutter.plugins.cameraexample; import androidx.test.rule.ActivityTestRule; -import dev.flutter.plugins.e2e.FlutterRunner; +import dev.flutter.plugins.integration_test.FlutterTestRunner; import io.flutter.embedding.android.FlutterActivity; import org.junit.Rule; import org.junit.runner.RunWith; -@RunWith(FlutterRunner.class) +@RunWith(FlutterTestRunner.class) public class FlutterActivityTest { @Rule public ActivityTestRule rule = new ActivityTestRule<>(FlutterActivity.class); diff --git a/packages/camera/example/android/app/src/main/java/io/flutter/plugins/cameraexample/EmbeddingV1Activity.java b/packages/camera/example/android/app/src/main/java/io/flutter/plugins/cameraexample/EmbeddingV1Activity.java index 76f47c500bcf..c0ef7d891bfc 100644 --- a/packages/camera/example/android/app/src/main/java/io/flutter/plugins/cameraexample/EmbeddingV1Activity.java +++ b/packages/camera/example/android/app/src/main/java/io/flutter/plugins/cameraexample/EmbeddingV1Activity.java @@ -1,7 +1,7 @@ package io.flutter.plugins.cameraexample; import android.os.Bundle; -import dev.flutter.plugins.e2e.E2EPlugin; +import dev.flutter.plugins.integration_test.IntegrationTestPlugin; import io.flutter.app.FlutterActivity; import io.flutter.plugins.camera.CameraPlugin; import io.flutter.plugins.pathprovider.PathProviderPlugin; @@ -12,7 +12,8 @@ public class EmbeddingV1Activity extends FlutterActivity { protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); CameraPlugin.registerWith(registrarFor("io.flutter.plugins.camera.CameraPlugin")); - E2EPlugin.registerWith(registrarFor("dev.flutter.plugins.e2e.E2EPlugin")); + IntegrationTestPlugin.registerWith( + registrarFor("dev.flutter.plugins.integration_test.IntegrationTestPlugin")); PathProviderPlugin.registerWith( registrarFor("io.flutter.plugins.pathprovider.PathProviderPlugin")); VideoPlayerPlugin.registerWith( diff --git a/packages/camera/example/pubspec.yaml b/packages/camera/example/pubspec.yaml index a066129eebd4..bc33087a5877 100644 --- a/packages/camera/example/pubspec.yaml +++ b/packages/camera/example/pubspec.yaml @@ -8,7 +8,8 @@ dependencies: flutter: sdk: flutter video_player: ^0.10.0 - e2e: "^0.2.0" + integration_test: + path: ../../integration_test dev_dependencies: flutter_test: diff --git a/packages/camera/example/test_driver/camera_e2e.dart b/packages/camera/example/test_driver/camera_e2e.dart index a1cc8ad9ca02..ef4646f5ced9 100644 --- a/packages/camera/example/test_driver/camera_e2e.dart +++ b/packages/camera/example/test_driver/camera_e2e.dart @@ -7,12 +7,12 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:camera/camera.dart'; import 'package:path_provider/path_provider.dart'; import 'package:video_player/video_player.dart'; -import 'package:e2e/e2e.dart'; +import 'package:integration_test/integration_test.dart'; void main() { Directory testDir; - E2EWidgetsFlutterBinding.ensureInitialized(); + IntegrationTestWidgetsFlutterBinding.ensureInitialized(); setUpAll(() async { final Directory extDir = await getTemporaryDirectory(); diff --git a/packages/camera/example/test_driver/camera_e2e_test.dart b/packages/camera/example/test_driver/camera_e2e_test.dart index 4963854dea72..1e6e3ba7941f 100644 --- a/packages/camera/example/test_driver/camera_e2e_test.dart +++ b/packages/camera/example/test_driver/camera_e2e_test.dart @@ -1,4 +1,5 @@ import 'dart:async'; +import 'dart:convert'; import 'dart:io'; import 'package:flutter_driver/flutter_driver.dart'; @@ -33,8 +34,10 @@ Future main() async { ]); print('Starting test.'); final FlutterDriver driver = await FlutterDriver.connect(); - final String result = - await driver.requestData(null, timeout: const Duration(minutes: 1)); + final String data = await driver.requestData( + null, + timeout: const Duration(minutes: 1), + ); await driver.close(); print('Test finished. Revoking camera permissions...'); Process.runSync('adb', [ @@ -51,5 +54,7 @@ Future main() async { _examplePackage, 'android.permission.RECORD_AUDIO' ]); - exit(result == 'pass' ? 0 : 1); + + final Map result = jsonDecode(data); + exit(result['result'] == 'true' ? 0 : 1); } diff --git a/packages/camera/ios/Classes/CameraPlugin.m b/packages/camera/ios/Classes/CameraPlugin.m index 42cdb6d5fdf9..525c1286717a 100644 --- a/packages/camera/ios/Classes/CameraPlugin.m +++ b/packages/camera/ios/Classes/CameraPlugin.m @@ -19,11 +19,6 @@ @interface FLTSavePhotoDelegate : NSObject @property(readonly, nonatomic) FlutterResult result; @property(readonly, nonatomic) CMMotionManager *motionManager; @property(readonly, nonatomic) AVCaptureDevicePosition cameraPosition; - -- initWithPath:(NSString *)filename - result:(FlutterResult)result - motionManager:(CMMotionManager *)motionManager - cameraPosition:(AVCaptureDevicePosition)cameraPosition; @end @interface FLTImageStreamHandler : NSObject @@ -68,7 +63,7 @@ - (void)captureOutput:(AVCapturePhotoOutput *)output previewPhotoSampleBuffer:(CMSampleBufferRef)previewPhotoSampleBuffer resolvedSettings:(AVCaptureResolvedPhotoSettings *)resolvedSettings bracketSettings:(AVCaptureBracketedStillImageSettings *)bracketSettings - error:(NSError *)error { + error:(NSError *)error API_AVAILABLE(ios(10)) { selfReference = nil; if (error) { _result(getFlutterError(error)); @@ -160,14 +155,14 @@ @interface FLTCam : NSObject @property(readonly, nonatomic) int64_t textureId; -@property(nonatomic, copy) void (^onFrameAvailable)(); +@property(nonatomic, copy) void (^onFrameAvailable)(void); @property BOOL enableAudio; @property(nonatomic) FlutterEventChannel *eventChannel; @property(nonatomic) FLTImageStreamHandler *imageStreamHandler; @property(nonatomic) FlutterEventSink eventSink; @property(readonly, nonatomic) AVCaptureSession *captureSession; @property(readonly, nonatomic) AVCaptureDevice *captureDevice; -@property(readonly, nonatomic) AVCapturePhotoOutput *capturePhotoOutput; +@property(readonly, nonatomic) AVCapturePhotoOutput *capturePhotoOutput API_AVAILABLE(ios(10)); @property(readonly, nonatomic) AVCaptureVideoDataOutput *captureVideoOutput; @property(readonly, nonatomic) AVCaptureInput *captureVideoInput; @property(readonly) CVPixelBufferRef volatile latestPixelBuffer; @@ -192,19 +187,6 @@ @interface FLTCam : NSObject *)messenger; -- (void)stopImageStream; -- (void)captureToFile:(NSString *)filename result:(FlutterResult)result; @end @implementation FLTCam { @@ -254,9 +236,12 @@ - (instancetype)initWithCameraName:(NSString *)cameraName [_captureSession addInputWithNoConnections:_captureVideoInput]; [_captureSession addOutputWithNoConnections:_captureVideoOutput]; [_captureSession addConnection:connection]; - _capturePhotoOutput = [AVCapturePhotoOutput new]; - [_capturePhotoOutput setHighResolutionCaptureEnabled:YES]; - [_captureSession addOutput:_capturePhotoOutput]; + + if (@available(iOS 10.0, *)) { + _capturePhotoOutput = [AVCapturePhotoOutput new]; + [_capturePhotoOutput setHighResolutionCaptureEnabled:YES]; + [_captureSession addOutput:_capturePhotoOutput]; + } _motionManager = [[CMMotionManager alloc] init]; [_motionManager startAccelerometerUpdates]; @@ -272,7 +257,7 @@ - (void)stop { [_captureSession stopRunning]; } -- (void)captureToFile:(NSString *)path result:(FlutterResult)result { +- (void)captureToFile:(NSString *)path result:(FlutterResult)result API_AVAILABLE(ios(10)) { AVCapturePhotoSettings *settings = [AVCapturePhotoSettings photoSettings]; if (_resolutionPreset == max) { [settings setHighResolutionPhotoEnabled:YES]; @@ -288,6 +273,14 @@ - (void)captureToFile:(NSString *)path result:(FlutterResult)result { - (void)setCaptureSessionPreset:(ResolutionPreset)resolutionPreset { switch (resolutionPreset) { case max: + case ultraHigh: + if (@available(iOS 9.0, *)) { + if ([_captureSession canSetSessionPreset:AVCaptureSessionPreset3840x2160]) { + _captureSession.sessionPreset = AVCaptureSessionPreset3840x2160; + _previewSize = CGSizeMake(3840, 2160); + break; + } + } if ([_captureSession canSetSessionPreset:AVCaptureSessionPresetHigh]) { _captureSession.sessionPreset = AVCaptureSessionPresetHigh; _previewSize = @@ -295,12 +288,6 @@ - (void)setCaptureSessionPreset:(ResolutionPreset)resolutionPreset { _captureDevice.activeFormat.highResolutionStillImageDimensions.height); break; } - case ultraHigh: - if ([_captureSession canSetSessionPreset:AVCaptureSessionPreset3840x2160]) { - _captureSession.sessionPreset = AVCaptureSessionPreset3840x2160; - _previewSize = CGSizeMake(3840, 2160); - break; - } case veryHigh: if ([_captureSession canSetSessionPreset:AVCaptureSessionPreset1920x1080]) { _captureSession.sessionPreset = AVCaptureSessionPreset1920x1080; @@ -495,7 +482,7 @@ - (void)captureOutput:(AVCaptureOutput *)output } } -- (CMSampleBufferRef)adjustTime:(CMSampleBufferRef)sample by:(CMTime)offset { +- (CMSampleBufferRef)adjustTime:(CMSampleBufferRef)sample by:(CMTime)offset CF_RETURNS_RETAINED { CMItemCount count; CMSampleBufferGetSampleTimingInfoArray(sample, 0, nil, &count); CMSampleTimingInfo *pInfo = malloc(sizeof(CMSampleTimingInfo) * count); @@ -801,33 +788,37 @@ - (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result - (void)handleMethodCallAsync:(FlutterMethodCall *)call result:(FlutterResult)result { if ([@"availableCameras" isEqualToString:call.method]) { - AVCaptureDeviceDiscoverySession *discoverySession = [AVCaptureDeviceDiscoverySession - discoverySessionWithDeviceTypes:@[ AVCaptureDeviceTypeBuiltInWideAngleCamera ] - mediaType:AVMediaTypeVideo - position:AVCaptureDevicePositionUnspecified]; - NSArray *devices = discoverySession.devices; - NSMutableArray *> *reply = - [[NSMutableArray alloc] initWithCapacity:devices.count]; - for (AVCaptureDevice *device in devices) { - NSString *lensFacing; - switch ([device position]) { - case AVCaptureDevicePositionBack: - lensFacing = @"back"; - break; - case AVCaptureDevicePositionFront: - lensFacing = @"front"; - break; - case AVCaptureDevicePositionUnspecified: - lensFacing = @"external"; - break; + if (@available(iOS 10.0, *)) { + AVCaptureDeviceDiscoverySession *discoverySession = [AVCaptureDeviceDiscoverySession + discoverySessionWithDeviceTypes:@[ AVCaptureDeviceTypeBuiltInWideAngleCamera ] + mediaType:AVMediaTypeVideo + position:AVCaptureDevicePositionUnspecified]; + NSArray *devices = discoverySession.devices; + NSMutableArray *> *reply = + [[NSMutableArray alloc] initWithCapacity:devices.count]; + for (AVCaptureDevice *device in devices) { + NSString *lensFacing; + switch ([device position]) { + case AVCaptureDevicePositionBack: + lensFacing = @"back"; + break; + case AVCaptureDevicePositionFront: + lensFacing = @"front"; + break; + case AVCaptureDevicePositionUnspecified: + lensFacing = @"external"; + break; + } + [reply addObject:@{ + @"name" : [device uniqueID], + @"lensFacing" : lensFacing, + @"sensorOrientation" : @90, + }]; } - [reply addObject:@{ - @"name" : [device uniqueID], - @"lensFacing" : lensFacing, - @"sensorOrientation" : @90, - }]; + result(reply); + } else { + result(FlutterMethodNotImplemented); } - result(reply); } else if ([@"initialize" isEqualToString:call.method]) { NSString *cameraName = call.arguments[@"cameraName"]; NSString *resolutionPreset = call.arguments[@"resolutionPreset"]; @@ -846,8 +837,9 @@ - (void)handleMethodCallAsync:(FlutterMethodCall *)call result:(FlutterResult)re } int64_t textureId = [_registry registerTexture:cam]; _camera = cam; + __weak CameraPlugin *weakSelf = self; cam.onFrameAvailable = ^{ - [_registry textureFrameAvailable:textureId]; + [weakSelf.registry textureFrameAvailable:textureId]; }; FlutterEventChannel *eventChannel = [FlutterEventChannel eventChannelWithName:[NSString @@ -880,9 +872,12 @@ - (void)handleMethodCallAsync:(FlutterMethodCall *)call result:(FlutterResult)re } else { NSDictionary *argsMap = call.arguments; NSUInteger textureId = ((NSNumber *)argsMap[@"textureId"]).unsignedIntegerValue; - if ([@"takePicture" isEqualToString:call.method]) { - [_camera captureToFile:call.arguments[@"path"] result:result]; + if (@available(iOS 10.0, *)) { + [_camera captureToFile:call.arguments[@"path"] result:result]; + } else { + result(FlutterMethodNotImplemented); + } } else if ([@"dispose" isEqualToString:call.method]) { [_registry unregisterTexture:textureId]; [_camera close]; diff --git a/packages/camera/ios/camera.podspec b/packages/camera/ios/camera.podspec index dfe566ca79cc..960f102e7706 100644 --- a/packages/camera/ios/camera.podspec +++ b/packages/camera/ios/camera.podspec @@ -4,19 +4,21 @@ Pod::Spec.new do |s| s.name = 'camera' s.version = '0.0.1' - s.summary = 'A new flutter plugin project.' + s.summary = 'Flutter Camera' s.description = <<-DESC -A new flutter plugin project. +A Flutter plugin to use the camera from your Flutter app. DESC - s.homepage = 'http://example.com' - s.license = { :file => '../LICENSE' } - s.author = { 'Your Company' => 'email@example.com' } - s.source = { :path => '.' } + s.homepage = 'https://github.com/flutter/plugins' + s.license = { :type => 'BSD', :file => '../LICENSE' } + s.author = { 'Flutter Dev Team' => 'flutter-dev@googlegroups.com' } + s.source = { :http => 'https://github.com/flutter/plugins/tree/master/packages/camera' } + s.documentation_url = 'https://pub.dev/packages/camera' s.source_files = 'Classes/**/*' s.public_header_files = 'Classes/**/*.h' s.dependency 'Flutter' + s.platform = :ios, '8.0' - s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'VALID_ARCHS' => 'armv7 arm64 x86_64' } + s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'VALID_ARCHS[sdk=iphonesimulator*]' => 'x86_64' } s.test_spec 'Tests' do |test_spec| test_spec.source_files = 'Tests/**/*' diff --git a/packages/camera/pubspec.yaml b/packages/camera/pubspec.yaml index a1ce42370191..01c7907792b2 100644 --- a/packages/camera/pubspec.yaml +++ b/packages/camera/pubspec.yaml @@ -2,7 +2,7 @@ name: camera description: A Flutter plugin for getting information about and controlling the camera on Android and iOS. Supports previewing the camera feed, capturing images, capturing video, and streaming image buffers to dart. -version: 0.5.8+3 +version: 0.5.8+5 homepage: https://github.com/flutter/plugins/tree/master/packages/camera diff --git a/packages/connectivity/connectivity/CHANGELOG.md b/packages/connectivity/connectivity/CHANGELOG.md index 3bb777104c0e..27a1bb100e74 100644 --- a/packages/connectivity/connectivity/CHANGELOG.md +++ b/packages/connectivity/connectivity/CHANGELOG.md @@ -1,3 +1,12 @@ +## 0.4.9+2 + +* Update package:e2e to use package:integration_test + +## 0.4.9+1 + +* Update package:e2e reference to use the local version in the flutter/plugins + repository. + ## 0.4.9 * Add support for `web` (by endorsing `connectivity_for_web` 0.3.0) diff --git a/packages/connectivity/connectivity/example/android/app/src/main/java/io/flutter/plugins/connectivityexample/EmbeddingV1ActivityTest.java b/packages/connectivity/connectivity/example/android/app/src/main/java/io/flutter/plugins/connectivityexample/EmbeddingV1ActivityTest.java index a34755399117..048da070991e 100644 --- a/packages/connectivity/connectivity/example/android/app/src/main/java/io/flutter/plugins/connectivityexample/EmbeddingV1ActivityTest.java +++ b/packages/connectivity/connectivity/example/android/app/src/main/java/io/flutter/plugins/connectivityexample/EmbeddingV1ActivityTest.java @@ -5,11 +5,11 @@ package io.flutter.plugins.connectivityexample; import androidx.test.rule.ActivityTestRule; -import dev.flutter.plugins.e2e.FlutterRunner; +import dev.flutter.plugins.integration_test.FlutterTestRunner; import org.junit.Rule; import org.junit.runner.RunWith; -@RunWith(FlutterRunner.class) +@RunWith(FlutterTestRunner.class) public class EmbeddingV1ActivityTest { @Rule public ActivityTestRule rule = diff --git a/packages/connectivity/connectivity/example/android/app/src/main/java/io/flutter/plugins/connectivityexample/FlutterActivityTest.java b/packages/connectivity/connectivity/example/android/app/src/main/java/io/flutter/plugins/connectivityexample/FlutterActivityTest.java index 35391fd5e0a0..0f0dcf2555f3 100644 --- a/packages/connectivity/connectivity/example/android/app/src/main/java/io/flutter/plugins/connectivityexample/FlutterActivityTest.java +++ b/packages/connectivity/connectivity/example/android/app/src/main/java/io/flutter/plugins/connectivityexample/FlutterActivityTest.java @@ -5,12 +5,12 @@ package io.flutter.plugins.connectivityexample; import androidx.test.rule.ActivityTestRule; -import dev.flutter.plugins.e2e.FlutterRunner; +import dev.flutter.plugins.integration_test.FlutterTestRunner; import io.flutter.embedding.android.FlutterActivity; import org.junit.Rule; import org.junit.runner.RunWith; -@RunWith(FlutterRunner.class) +@RunWith(FlutterTestRunner.class) public class FlutterActivityTest { @Rule public ActivityTestRule rule = new ActivityTestRule<>(FlutterActivity.class); diff --git a/packages/connectivity/connectivity/example/pubspec.yaml b/packages/connectivity/connectivity/example/pubspec.yaml index a16e60442736..1d07f7d19e60 100644 --- a/packages/connectivity/connectivity/example/pubspec.yaml +++ b/packages/connectivity/connectivity/example/pubspec.yaml @@ -11,7 +11,8 @@ dev_dependencies: flutter_driver: sdk: flutter test: any - e2e: ^0.2.0 + integration_test: + path: ../../../integration_test pedantic: ^1.8.0 flutter: diff --git a/packages/connectivity/connectivity/example/test_driver/test/connectivity_e2e.dart b/packages/connectivity/connectivity/example/test_driver/test/connectivity_e2e.dart index 10c4bda34e0d..54a67337285a 100644 --- a/packages/connectivity/connectivity/example/test_driver/test/connectivity_e2e.dart +++ b/packages/connectivity/connectivity/example/test_driver/test/connectivity_e2e.dart @@ -3,12 +3,12 @@ // found in the LICENSE file. import 'dart:io'; -import 'package:e2e/e2e.dart'; +import 'package:integration_test/integration_test.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:connectivity/connectivity.dart'; void main() { - E2EWidgetsFlutterBinding.ensureInitialized(); + IntegrationTestWidgetsFlutterBinding.ensureInitialized(); group('Connectivity test driver', () { Connectivity _connectivity; diff --git a/packages/connectivity/connectivity/example/test_driver/test/connectivity_e2e_test.dart b/packages/connectivity/connectivity/example/test_driver/test/connectivity_e2e_test.dart index 84b7ae6a47ab..c0cbdcab2fb6 100644 --- a/packages/connectivity/connectivity/example/test_driver/test/connectivity_e2e_test.dart +++ b/packages/connectivity/connectivity/example/test_driver/test/connectivity_e2e_test.dart @@ -2,13 +2,15 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import 'dart:convert'; import 'dart:io'; import 'package:flutter_driver/flutter_driver.dart'; Future main() async { final FlutterDriver driver = await FlutterDriver.connect(); - final String result = + final String data = await driver.requestData(null, timeout: const Duration(minutes: 1)); await driver.close(); - exit(result == 'pass' ? 0 : 1); + final Map result = jsonDecode(data); + exit(result['result'] == 'true' ? 0 : 1); } diff --git a/packages/connectivity/connectivity/pubspec.yaml b/packages/connectivity/connectivity/pubspec.yaml index c7ef8fe6e723..dc9d90827169 100644 --- a/packages/connectivity/connectivity/pubspec.yaml +++ b/packages/connectivity/connectivity/pubspec.yaml @@ -5,7 +5,7 @@ homepage: https://github.com/flutter/plugins/tree/master/packages/connectivity/c # 0.4.y+z is compatible with 1.0.0, if you land a breaking change bump # the version to 2.0.0. # See more details: https://github.com/flutter/flutter/wiki/Package-migration-to-1.0.0 -version: 0.4.9 +version: 0.4.9+2 flutter: plugin: @@ -34,7 +34,8 @@ dev_dependencies: flutter_driver: sdk: flutter test: any - e2e: ^0.2.0 + integration_test: + path: ../../integration_test mockito: ^4.1.1 plugin_platform_interface: ^1.0.0 pedantic: ^1.8.0 diff --git a/packages/connectivity/connectivity/test/connectivity_e2e.dart b/packages/connectivity/connectivity/test/connectivity_e2e.dart index 10c4bda34e0d..54a67337285a 100644 --- a/packages/connectivity/connectivity/test/connectivity_e2e.dart +++ b/packages/connectivity/connectivity/test/connectivity_e2e.dart @@ -3,12 +3,12 @@ // found in the LICENSE file. import 'dart:io'; -import 'package:e2e/e2e.dart'; +import 'package:integration_test/integration_test.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:connectivity/connectivity.dart'; void main() { - E2EWidgetsFlutterBinding.ensureInitialized(); + IntegrationTestWidgetsFlutterBinding.ensureInitialized(); group('Connectivity test driver', () { Connectivity _connectivity; diff --git a/packages/connectivity/connectivity_for_web/CHANGELOG.md b/packages/connectivity/connectivity_for_web/CHANGELOG.md index 83dc386a0314..4c10ee64e855 100644 --- a/packages/connectivity/connectivity_for_web/CHANGELOG.md +++ b/packages/connectivity/connectivity_for_web/CHANGELOG.md @@ -1,3 +1,12 @@ +## 0.3.1+2 + +* Update package:e2e to use package:integration_test + +## 0.3.1+1 + +* Update package:e2e reference to use the local version in the flutter/plugins + repository. + ## 0.3.1 * Use NetworkInformation API from dart:html, instead of the JS-interop version. diff --git a/packages/connectivity/connectivity_for_web/pubspec.yaml b/packages/connectivity/connectivity_for_web/pubspec.yaml index e1142a75c91f..adba1f4f9a47 100644 --- a/packages/connectivity/connectivity_for_web/pubspec.yaml +++ b/packages/connectivity/connectivity_for_web/pubspec.yaml @@ -1,6 +1,6 @@ name: connectivity_for_web description: An implementation for the web platform of the Flutter `connectivity` plugin. This uses the NetworkInformation Web API, with a fallback to Navigator.onLine. -version: 0.3.1 +version: 0.3.1+2 homepage: https://github.com/ditman/plugins/tree/connectivity-web/packages/connectivity/experimental_connectivity_web flutter: @@ -23,7 +23,8 @@ dev_dependencies: sdk: flutter flutter_test: sdk: flutter - e2e: ^0.2.4+3 + integration_test: + path: ../../integration_test mockito: ^4.1.1 environment: diff --git a/packages/connectivity/connectivity_for_web/test/lib/main.dart b/packages/connectivity/connectivity_for_web/test/lib/main.dart index 93b9a73cf31b..e3473532553e 100644 --- a/packages/connectivity/connectivity_for_web/test/lib/main.dart +++ b/packages/connectivity/connectivity_for_web/test/lib/main.dart @@ -1,4 +1,4 @@ -import 'package:e2e/e2e.dart'; +import 'package:integration_test/integration_test.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:connectivity_platform_interface/connectivity_platform_interface.dart'; import 'package:connectivity_for_web/src/network_information_api_connectivity_plugin.dart'; @@ -8,7 +8,7 @@ import 'package:mockito/mockito.dart'; import 'src/connectivity_mocks.dart'; void main() { - E2EWidgetsFlutterBinding.ensureInitialized(); + IntegrationTestWidgetsFlutterBinding.ensureInitialized(); group('checkConnectivity', () { void testCheckConnectivity({ diff --git a/packages/connectivity/connectivity_for_web/test/pubspec.yaml b/packages/connectivity/connectivity_for_web/test/pubspec.yaml index 44f4b552b443..512b7df8c26e 100644 --- a/packages/connectivity/connectivity_for_web/test/pubspec.yaml +++ b/packages/connectivity/connectivity_for_web/test/pubspec.yaml @@ -1,6 +1,5 @@ name: connectivity_web_example -description: Example web app for the connectivity plugin -version: 0.1.1 +description: Example web app for the connectivity plugin homepage: https://github.com/flutter/plugins/tree/master/packages/connectivity/connectivity_web dependencies: @@ -17,7 +16,8 @@ dev_dependencies: sdk: flutter flutter_driver: sdk: flutter - e2e: ^0.2.4+3 + integration_test: + path: ../../../integration_test mockito: ^4.1.1 environment: diff --git a/packages/connectivity/connectivity_macos/CHANGELOG.md b/packages/connectivity/connectivity_macos/CHANGELOG.md index 637be001518b..ac12b21b531a 100644 --- a/packages/connectivity/connectivity_macos/CHANGELOG.md +++ b/packages/connectivity/connectivity_macos/CHANGELOG.md @@ -1,3 +1,8 @@ +## 0.1.0+5 + +* Update package:e2e reference to use the local version in the flutter/plugins + repository. + ## 0.1.0+4 * Remove Android folder from `connectivity_macos`. diff --git a/packages/connectivity/connectivity_macos/example/android/app/src/main/java/io/flutter/plugins/connectivityexample/EmbeddingV1ActivityTest.java b/packages/connectivity/connectivity_macos/example/android/app/src/main/java/io/flutter/plugins/connectivityexample/EmbeddingV1ActivityTest.java index a34755399117..048da070991e 100644 --- a/packages/connectivity/connectivity_macos/example/android/app/src/main/java/io/flutter/plugins/connectivityexample/EmbeddingV1ActivityTest.java +++ b/packages/connectivity/connectivity_macos/example/android/app/src/main/java/io/flutter/plugins/connectivityexample/EmbeddingV1ActivityTest.java @@ -5,11 +5,11 @@ package io.flutter.plugins.connectivityexample; import androidx.test.rule.ActivityTestRule; -import dev.flutter.plugins.e2e.FlutterRunner; +import dev.flutter.plugins.integration_test.FlutterTestRunner; import org.junit.Rule; import org.junit.runner.RunWith; -@RunWith(FlutterRunner.class) +@RunWith(FlutterTestRunner.class) public class EmbeddingV1ActivityTest { @Rule public ActivityTestRule rule = diff --git a/packages/connectivity/connectivity_macos/example/android/app/src/main/java/io/flutter/plugins/connectivityexample/FlutterActivityTest.java b/packages/connectivity/connectivity_macos/example/android/app/src/main/java/io/flutter/plugins/connectivityexample/FlutterActivityTest.java index 35391fd5e0a0..0f0dcf2555f3 100644 --- a/packages/connectivity/connectivity_macos/example/android/app/src/main/java/io/flutter/plugins/connectivityexample/FlutterActivityTest.java +++ b/packages/connectivity/connectivity_macos/example/android/app/src/main/java/io/flutter/plugins/connectivityexample/FlutterActivityTest.java @@ -5,12 +5,12 @@ package io.flutter.plugins.connectivityexample; import androidx.test.rule.ActivityTestRule; -import dev.flutter.plugins.e2e.FlutterRunner; +import dev.flutter.plugins.integration_test.FlutterTestRunner; import io.flutter.embedding.android.FlutterActivity; import org.junit.Rule; import org.junit.runner.RunWith; -@RunWith(FlutterRunner.class) +@RunWith(FlutterTestRunner.class) public class FlutterActivityTest { @Rule public ActivityTestRule rule = new ActivityTestRule<>(FlutterActivity.class); diff --git a/packages/connectivity/connectivity_macos/example/pubspec.yaml b/packages/connectivity/connectivity_macos/example/pubspec.yaml index 877250021f9a..7faf3e2f67e7 100644 --- a/packages/connectivity/connectivity_macos/example/pubspec.yaml +++ b/packages/connectivity/connectivity_macos/example/pubspec.yaml @@ -12,7 +12,8 @@ dev_dependencies: flutter_driver: sdk: flutter test: any - e2e: ^0.2.0 + integration_test: + path: ../../../integration_test pedantic: ^1.8.0 flutter: diff --git a/packages/connectivity/connectivity_macos/example/test_driver/test/connectivity_e2e.dart b/packages/connectivity/connectivity_macos/example/test_driver/test/connectivity_e2e.dart index 10c4bda34e0d..54a67337285a 100644 --- a/packages/connectivity/connectivity_macos/example/test_driver/test/connectivity_e2e.dart +++ b/packages/connectivity/connectivity_macos/example/test_driver/test/connectivity_e2e.dart @@ -3,12 +3,12 @@ // found in the LICENSE file. import 'dart:io'; -import 'package:e2e/e2e.dart'; +import 'package:integration_test/integration_test.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:connectivity/connectivity.dart'; void main() { - E2EWidgetsFlutterBinding.ensureInitialized(); + IntegrationTestWidgetsFlutterBinding.ensureInitialized(); group('Connectivity test driver', () { Connectivity _connectivity; diff --git a/packages/connectivity/connectivity_macos/example/test_driver/test/connectivity_e2e_test.dart b/packages/connectivity/connectivity_macos/example/test_driver/test/connectivity_e2e_test.dart index 84b7ae6a47ab..c0cbdcab2fb6 100644 --- a/packages/connectivity/connectivity_macos/example/test_driver/test/connectivity_e2e_test.dart +++ b/packages/connectivity/connectivity_macos/example/test_driver/test/connectivity_e2e_test.dart @@ -2,13 +2,15 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import 'dart:convert'; import 'dart:io'; import 'package:flutter_driver/flutter_driver.dart'; Future main() async { final FlutterDriver driver = await FlutterDriver.connect(); - final String result = + final String data = await driver.requestData(null, timeout: const Duration(minutes: 1)); await driver.close(); - exit(result == 'pass' ? 0 : 1); + final Map result = jsonDecode(data); + exit(result['result'] == 'true' ? 0 : 1); } diff --git a/packages/device_info/CHANGELOG.md b/packages/device_info/device_info/CHANGELOG.md similarity index 92% rename from packages/device_info/CHANGELOG.md rename to packages/device_info/device_info/CHANGELOG.md index 057638d01cac..4f5e1d927c10 100644 --- a/packages/device_info/CHANGELOG.md +++ b/packages/device_info/device_info/CHANGELOG.md @@ -1,3 +1,16 @@ +## 0.4.2+7 + +* Port device_info plugin to use platform interface. + +## 0.4.2+6 + +* Moved everything from device_info to device_info/device_info + +## 0.4.2+5 + +* Update package:e2e reference to use the local version in the flutter/plugins + repository. + ## 0.4.2+4 Update lower bound of dart dependency to 2.1.0. diff --git a/packages/device_info/LICENSE b/packages/device_info/device_info/LICENSE similarity index 100% rename from packages/device_info/LICENSE rename to packages/device_info/device_info/LICENSE diff --git a/packages/device_info/README.md b/packages/device_info/device_info/README.md similarity index 100% rename from packages/device_info/README.md rename to packages/device_info/device_info/README.md diff --git a/packages/device_info/android/build.gradle b/packages/device_info/device_info/android/build.gradle similarity index 100% rename from packages/device_info/android/build.gradle rename to packages/device_info/device_info/android/build.gradle diff --git a/packages/device_info/android/gradle.properties b/packages/device_info/device_info/android/gradle.properties similarity index 100% rename from packages/device_info/android/gradle.properties rename to packages/device_info/device_info/android/gradle.properties diff --git a/packages/device_info/android/settings.gradle b/packages/device_info/device_info/android/settings.gradle similarity index 100% rename from packages/device_info/android/settings.gradle rename to packages/device_info/device_info/android/settings.gradle diff --git a/packages/device_info/android/src/main/AndroidManifest.xml b/packages/device_info/device_info/android/src/main/AndroidManifest.xml similarity index 100% rename from packages/device_info/android/src/main/AndroidManifest.xml rename to packages/device_info/device_info/android/src/main/AndroidManifest.xml diff --git a/packages/device_info/android/src/main/java/io/flutter/plugins/deviceinfo/DeviceInfoPlugin.java b/packages/device_info/device_info/android/src/main/java/io/flutter/plugins/deviceinfo/DeviceInfoPlugin.java similarity index 100% rename from packages/device_info/android/src/main/java/io/flutter/plugins/deviceinfo/DeviceInfoPlugin.java rename to packages/device_info/device_info/android/src/main/java/io/flutter/plugins/deviceinfo/DeviceInfoPlugin.java diff --git a/packages/device_info/android/src/main/java/io/flutter/plugins/deviceinfo/MethodCallHandlerImpl.java b/packages/device_info/device_info/android/src/main/java/io/flutter/plugins/deviceinfo/MethodCallHandlerImpl.java similarity index 100% rename from packages/device_info/android/src/main/java/io/flutter/plugins/deviceinfo/MethodCallHandlerImpl.java rename to packages/device_info/device_info/android/src/main/java/io/flutter/plugins/deviceinfo/MethodCallHandlerImpl.java diff --git a/packages/device_info/example/README.md b/packages/device_info/device_info/example/README.md similarity index 100% rename from packages/device_info/example/README.md rename to packages/device_info/device_info/example/README.md diff --git a/packages/device_info/example/android/app/build.gradle b/packages/device_info/device_info/example/android/app/build.gradle similarity index 100% rename from packages/device_info/example/android/app/build.gradle rename to packages/device_info/device_info/example/android/app/build.gradle diff --git a/packages/device_info/example/android/app/gradle/wrapper/gradle-wrapper.properties b/packages/device_info/device_info/example/android/app/gradle/wrapper/gradle-wrapper.properties similarity index 100% rename from packages/device_info/example/android/app/gradle/wrapper/gradle-wrapper.properties rename to packages/device_info/device_info/example/android/app/gradle/wrapper/gradle-wrapper.properties diff --git a/packages/device_info/example/android/app/src/main/AndroidManifest.xml b/packages/device_info/device_info/example/android/app/src/main/AndroidManifest.xml similarity index 100% rename from packages/device_info/example/android/app/src/main/AndroidManifest.xml rename to packages/device_info/device_info/example/android/app/src/main/AndroidManifest.xml diff --git a/packages/device_info/example/android/app/src/main/java/io/flutter/plugins/deviceinfoexample/EmbeddingV1Activity.java b/packages/device_info/device_info/example/android/app/src/main/java/io/flutter/plugins/deviceinfoexample/EmbeddingV1Activity.java similarity index 100% rename from packages/device_info/example/android/app/src/main/java/io/flutter/plugins/deviceinfoexample/EmbeddingV1Activity.java rename to packages/device_info/device_info/example/android/app/src/main/java/io/flutter/plugins/deviceinfoexample/EmbeddingV1Activity.java diff --git a/packages/device_info/example/android/app/src/main/java/io/flutter/plugins/deviceinfoexample/EmbeddingV1ActivityTest.java b/packages/device_info/device_info/example/android/app/src/main/java/io/flutter/plugins/deviceinfoexample/EmbeddingV1ActivityTest.java similarity index 76% rename from packages/device_info/example/android/app/src/main/java/io/flutter/plugins/deviceinfoexample/EmbeddingV1ActivityTest.java rename to packages/device_info/device_info/example/android/app/src/main/java/io/flutter/plugins/deviceinfoexample/EmbeddingV1ActivityTest.java index 2bec9fb8e254..797c06aa50b2 100644 --- a/packages/device_info/example/android/app/src/main/java/io/flutter/plugins/deviceinfoexample/EmbeddingV1ActivityTest.java +++ b/packages/device_info/device_info/example/android/app/src/main/java/io/flutter/plugins/deviceinfoexample/EmbeddingV1ActivityTest.java @@ -1,11 +1,11 @@ package io.flutter.plugins.deviceinfoexample; import androidx.test.rule.ActivityTestRule; -import dev.flutter.plugins.e2e.FlutterRunner; +import dev.flutter.plugins.integration_test.FlutterTestRunner; import org.junit.Rule; import org.junit.runner.RunWith; -@RunWith(FlutterRunner.class) +@RunWith(FlutterTestRunner.class) public class EmbeddingV1ActivityTest { @Rule public ActivityTestRule rule = diff --git a/packages/device_info/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/packages/device_info/device_info/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png similarity index 100% rename from packages/device_info/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png rename to packages/device_info/device_info/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png diff --git a/packages/device_info/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/packages/device_info/device_info/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png similarity index 100% rename from packages/device_info/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png rename to packages/device_info/device_info/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png diff --git a/packages/device_info/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/packages/device_info/device_info/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png similarity index 100% rename from packages/device_info/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png rename to packages/device_info/device_info/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png diff --git a/packages/device_info/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/packages/device_info/device_info/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png similarity index 100% rename from packages/device_info/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png rename to packages/device_info/device_info/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png diff --git a/packages/device_info/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/packages/device_info/device_info/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png similarity index 100% rename from packages/device_info/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png rename to packages/device_info/device_info/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png diff --git a/packages/device_info/example/android/build.gradle b/packages/device_info/device_info/example/android/build.gradle similarity index 100% rename from packages/device_info/example/android/build.gradle rename to packages/device_info/device_info/example/android/build.gradle diff --git a/packages/device_info/example/android/gradle.properties b/packages/device_info/device_info/example/android/gradle.properties similarity index 100% rename from packages/device_info/example/android/gradle.properties rename to packages/device_info/device_info/example/android/gradle.properties diff --git a/packages/device_info/example/android/gradle/wrapper/gradle-wrapper.properties b/packages/device_info/device_info/example/android/gradle/wrapper/gradle-wrapper.properties similarity index 100% rename from packages/device_info/example/android/gradle/wrapper/gradle-wrapper.properties rename to packages/device_info/device_info/example/android/gradle/wrapper/gradle-wrapper.properties diff --git a/packages/device_info/example/android/settings.gradle b/packages/device_info/device_info/example/android/settings.gradle similarity index 100% rename from packages/device_info/example/android/settings.gradle rename to packages/device_info/device_info/example/android/settings.gradle diff --git a/packages/device_info/example/ios/Flutter/AppFrameworkInfo.plist b/packages/device_info/device_info/example/ios/Flutter/AppFrameworkInfo.plist similarity index 100% rename from packages/device_info/example/ios/Flutter/AppFrameworkInfo.plist rename to packages/device_info/device_info/example/ios/Flutter/AppFrameworkInfo.plist diff --git a/packages/device_info/example/ios/Flutter/Debug.xcconfig b/packages/device_info/device_info/example/ios/Flutter/Debug.xcconfig similarity index 100% rename from packages/device_info/example/ios/Flutter/Debug.xcconfig rename to packages/device_info/device_info/example/ios/Flutter/Debug.xcconfig diff --git a/packages/device_info/example/ios/Flutter/Release.xcconfig b/packages/device_info/device_info/example/ios/Flutter/Release.xcconfig similarity index 100% rename from packages/device_info/example/ios/Flutter/Release.xcconfig rename to packages/device_info/device_info/example/ios/Flutter/Release.xcconfig diff --git a/packages/device_info/example/ios/Runner.xcodeproj/project.pbxproj b/packages/device_info/device_info/example/ios/Runner.xcodeproj/project.pbxproj similarity index 100% rename from packages/device_info/example/ios/Runner.xcodeproj/project.pbxproj rename to packages/device_info/device_info/example/ios/Runner.xcodeproj/project.pbxproj diff --git a/packages/device_info/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/packages/device_info/device_info/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata similarity index 100% rename from packages/device_info/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata rename to packages/device_info/device_info/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata diff --git a/packages/device_info/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/packages/device_info/device_info/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme similarity index 100% rename from packages/device_info/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme rename to packages/device_info/device_info/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme diff --git a/packages/device_info/example/ios/Runner.xcworkspace/contents.xcworkspacedata b/packages/device_info/device_info/example/ios/Runner.xcworkspace/contents.xcworkspacedata similarity index 100% rename from packages/device_info/example/ios/Runner.xcworkspace/contents.xcworkspacedata rename to packages/device_info/device_info/example/ios/Runner.xcworkspace/contents.xcworkspacedata diff --git a/packages/device_info/example/ios/Runner/AppDelegate.h b/packages/device_info/device_info/example/ios/Runner/AppDelegate.h similarity index 100% rename from packages/device_info/example/ios/Runner/AppDelegate.h rename to packages/device_info/device_info/example/ios/Runner/AppDelegate.h diff --git a/packages/device_info/example/ios/Runner/AppDelegate.m b/packages/device_info/device_info/example/ios/Runner/AppDelegate.m similarity index 100% rename from packages/device_info/example/ios/Runner/AppDelegate.m rename to packages/device_info/device_info/example/ios/Runner/AppDelegate.m diff --git a/packages/device_info/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/packages/device_info/device_info/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json similarity index 100% rename from packages/device_info/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json rename to packages/device_info/device_info/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json diff --git a/packages/device_info/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/packages/device_info/device_info/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png similarity index 100% rename from packages/device_info/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png rename to packages/device_info/device_info/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png diff --git a/packages/device_info/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/packages/device_info/device_info/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png similarity index 100% rename from packages/device_info/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png rename to packages/device_info/device_info/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png diff --git a/packages/device_info/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/packages/device_info/device_info/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png similarity index 100% rename from packages/device_info/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png rename to packages/device_info/device_info/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png diff --git a/packages/device_info/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/packages/device_info/device_info/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png similarity index 100% rename from packages/device_info/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png rename to packages/device_info/device_info/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png diff --git a/packages/device_info/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/packages/device_info/device_info/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png similarity index 100% rename from packages/device_info/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png rename to packages/device_info/device_info/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png diff --git a/packages/device_info/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/packages/device_info/device_info/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png similarity index 100% rename from packages/device_info/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png rename to packages/device_info/device_info/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png diff --git a/packages/device_info/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/packages/device_info/device_info/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png similarity index 100% rename from packages/device_info/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png rename to packages/device_info/device_info/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png diff --git a/packages/device_info/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/packages/device_info/device_info/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png similarity index 100% rename from packages/device_info/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png rename to packages/device_info/device_info/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png diff --git a/packages/device_info/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/packages/device_info/device_info/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png similarity index 100% rename from packages/device_info/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png rename to packages/device_info/device_info/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png diff --git a/packages/device_info/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/packages/device_info/device_info/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png similarity index 100% rename from packages/device_info/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png rename to packages/device_info/device_info/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png diff --git a/packages/device_info/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/packages/device_info/device_info/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png similarity index 100% rename from packages/device_info/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png rename to packages/device_info/device_info/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png diff --git a/packages/device_info/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/packages/device_info/device_info/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png similarity index 100% rename from packages/device_info/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png rename to packages/device_info/device_info/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png diff --git a/packages/device_info/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/packages/device_info/device_info/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png similarity index 100% rename from packages/device_info/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png rename to packages/device_info/device_info/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png diff --git a/packages/device_info/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/packages/device_info/device_info/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png similarity index 100% rename from packages/device_info/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png rename to packages/device_info/device_info/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png diff --git a/packages/device_info/example/ios/Runner/Base.lproj/LaunchScreen.storyboard b/packages/device_info/device_info/example/ios/Runner/Base.lproj/LaunchScreen.storyboard similarity index 100% rename from packages/device_info/example/ios/Runner/Base.lproj/LaunchScreen.storyboard rename to packages/device_info/device_info/example/ios/Runner/Base.lproj/LaunchScreen.storyboard diff --git a/packages/device_info/example/ios/Runner/Base.lproj/Main.storyboard b/packages/device_info/device_info/example/ios/Runner/Base.lproj/Main.storyboard similarity index 100% rename from packages/device_info/example/ios/Runner/Base.lproj/Main.storyboard rename to packages/device_info/device_info/example/ios/Runner/Base.lproj/Main.storyboard diff --git a/packages/device_info/example/ios/Runner/Info.plist b/packages/device_info/device_info/example/ios/Runner/Info.plist similarity index 100% rename from packages/device_info/example/ios/Runner/Info.plist rename to packages/device_info/device_info/example/ios/Runner/Info.plist diff --git a/packages/device_info/example/ios/Runner/main.m b/packages/device_info/device_info/example/ios/Runner/main.m similarity index 100% rename from packages/device_info/example/ios/Runner/main.m rename to packages/device_info/device_info/example/ios/Runner/main.m diff --git a/packages/device_info/example/lib/main.dart b/packages/device_info/device_info/example/lib/main.dart similarity index 100% rename from packages/device_info/example/lib/main.dart rename to packages/device_info/device_info/example/lib/main.dart diff --git a/packages/device_info/example/pubspec.yaml b/packages/device_info/device_info/example/pubspec.yaml similarity index 82% rename from packages/device_info/example/pubspec.yaml rename to packages/device_info/device_info/example/pubspec.yaml index dc63d8b66126..e22f6026ba69 100644 --- a/packages/device_info/example/pubspec.yaml +++ b/packages/device_info/device_info/example/pubspec.yaml @@ -10,7 +10,8 @@ dependencies: dev_dependencies: flutter_driver: sdk: flutter - e2e: ^0.2.0 + integration_test: + path: ../../../integration_test pedantic: ^1.8.0 flutter: diff --git a/packages/device_info/example/test_driver/device_info_e2e.dart b/packages/device_info/device_info/example/test_driver/device_info_e2e.dart similarity index 88% rename from packages/device_info/example/test_driver/device_info_e2e.dart rename to packages/device_info/device_info/example/test_driver/device_info_e2e.dart index db8a73f579c1..2fd1d9a9a491 100644 --- a/packages/device_info/example/test_driver/device_info_e2e.dart +++ b/packages/device_info/device_info/example/test_driver/device_info_e2e.dart @@ -5,10 +5,10 @@ import 'dart:io'; import 'package:flutter_test/flutter_test.dart'; import 'package:device_info/device_info.dart'; -import 'package:e2e/e2e.dart'; +import 'package:integration_test/integration_test.dart'; void main() { - E2EWidgetsFlutterBinding.ensureInitialized(); + IntegrationTestWidgetsFlutterBinding.ensureInitialized(); IosDeviceInfo iosInfo; AndroidDeviceInfo androidInfo; diff --git a/packages/device_info/example/test_driver/device_info_e2e_test.dart b/packages/device_info/device_info/example/test_driver/device_info_e2e_test.dart similarity index 77% rename from packages/device_info/example/test_driver/device_info_e2e_test.dart rename to packages/device_info/device_info/example/test_driver/device_info_e2e_test.dart index f3aa9e218d82..7a2c21338786 100644 --- a/packages/device_info/example/test_driver/device_info_e2e_test.dart +++ b/packages/device_info/device_info/example/test_driver/device_info_e2e_test.dart @@ -3,13 +3,15 @@ // BSD-style license that can be found in the LICENSE file. import 'dart:async'; +import 'dart:convert'; import 'dart:io'; import 'package:flutter_driver/flutter_driver.dart'; Future main() async { final FlutterDriver driver = await FlutterDriver.connect(); - final String result = + final String data = await driver.requestData(null, timeout: const Duration(minutes: 1)); await driver.close(); - exit(result == 'pass' ? 0 : 1); + final Map result = jsonDecode(data); + exit(result['result'] == 'true' ? 0 : 1); } diff --git a/packages/device_info/ios/Assets/.gitkeep b/packages/device_info/device_info/ios/Assets/.gitkeep similarity index 100% rename from packages/device_info/ios/Assets/.gitkeep rename to packages/device_info/device_info/ios/Assets/.gitkeep diff --git a/packages/device_info/ios/Classes/FLTDeviceInfoPlugin.h b/packages/device_info/device_info/ios/Classes/FLTDeviceInfoPlugin.h similarity index 100% rename from packages/device_info/ios/Classes/FLTDeviceInfoPlugin.h rename to packages/device_info/device_info/ios/Classes/FLTDeviceInfoPlugin.h diff --git a/packages/device_info/ios/Classes/FLTDeviceInfoPlugin.m b/packages/device_info/device_info/ios/Classes/FLTDeviceInfoPlugin.m similarity index 100% rename from packages/device_info/ios/Classes/FLTDeviceInfoPlugin.m rename to packages/device_info/device_info/ios/Classes/FLTDeviceInfoPlugin.m diff --git a/packages/device_info/ios/device_info.podspec b/packages/device_info/device_info/ios/device_info.podspec similarity index 100% rename from packages/device_info/ios/device_info.podspec rename to packages/device_info/device_info/ios/device_info.podspec diff --git a/packages/device_info/device_info/lib/device_info.dart b/packages/device_info/device_info/lib/device_info.dart new file mode 100644 index 000000000000..f63730c4323f --- /dev/null +++ b/packages/device_info/device_info/lib/device_info.dart @@ -0,0 +1,35 @@ +// Copyright 2017 The Chromium 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:device_info_platform_interface/device_info_platform_interface.dart'; + +export 'package:device_info_platform_interface/device_info_platform_interface.dart' + show AndroidBuildVersion, AndroidDeviceInfo, IosDeviceInfo, IosUtsname; + +/// Provides device and operating system information. +class DeviceInfoPlugin { + /// No work is done when instantiating the plugin. It's safe to call this + /// repeatedly or in performance-sensitive blocks. + DeviceInfoPlugin(); + + /// This information does not change from call to call. Cache it. + AndroidDeviceInfo _cachedAndroidDeviceInfo; + + /// Information derived from `android.os.Build`. + /// + /// See: https://developer.android.com/reference/android/os/Build.html + Future get androidInfo async => + _cachedAndroidDeviceInfo ??= + await DeviceInfoPlatform.instance.androidInfo(); + + /// This information does not change from call to call. Cache it. + IosDeviceInfo _cachedIosDeviceInfo; + + /// Information derived from `UIDevice`. + /// + /// See: https://developer.apple.com/documentation/uikit/uidevice + Future get iosInfo async => + _cachedIosDeviceInfo ??= await DeviceInfoPlatform.instance.iosInfo(); +} diff --git a/packages/device_info/pubspec.yaml b/packages/device_info/device_info/pubspec.yaml similarity index 93% rename from packages/device_info/pubspec.yaml rename to packages/device_info/device_info/pubspec.yaml index 8ad768a3c031..8cb058751fd1 100644 --- a/packages/device_info/pubspec.yaml +++ b/packages/device_info/device_info/pubspec.yaml @@ -5,7 +5,7 @@ homepage: https://github.com/flutter/plugins/tree/master/packages/device_info # 0.4.y+z is compatible with 1.0.0, if you land a breaking change bump # the version to 2.0.0. # See more details: https://github.com/flutter/flutter/wiki/Package-migration-to-1.0.0 -version: 0.4.2+4 +version: 0.4.2+7 flutter: plugin: @@ -19,12 +19,12 @@ flutter: dependencies: flutter: sdk: flutter + device_info_platform_interface: ^1.0.0 dev_dependencies: test: ^1.3.0 flutter_test: sdk: flutter - e2e: ^0.2.0 pedantic: ^1.8.0 environment: diff --git a/packages/device_info/device_info_android.iml b/packages/device_info/device_info_android.iml deleted file mode 100644 index 462b903e05b6..000000000000 --- a/packages/device_info/device_info_android.iml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - diff --git a/packages/device_info/device_info_platform_interface/CHANGELOG.md b/packages/device_info/device_info_platform_interface/CHANGELOG.md new file mode 100644 index 000000000000..6fadda91b380 --- /dev/null +++ b/packages/device_info/device_info_platform_interface/CHANGELOG.md @@ -0,0 +1,3 @@ +## 1.0.0 + +- Initial open-source release. diff --git a/packages/device_info/device_info_platform_interface/LICENSE b/packages/device_info/device_info_platform_interface/LICENSE new file mode 100644 index 000000000000..c89293372cf3 --- /dev/null +++ b/packages/device_info/device_info_platform_interface/LICENSE @@ -0,0 +1,27 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/packages/device_info/device_info_platform_interface/README.md b/packages/device_info/device_info_platform_interface/README.md new file mode 100644 index 000000000000..1391ffded5ee --- /dev/null +++ b/packages/device_info/device_info_platform_interface/README.md @@ -0,0 +1,26 @@ +# device_info_platform_interface + +A common platform interface for the [`device_info`][1] plugin. + +This interface allows platform-specific implementations of the `device_info` +plugin, as well as the plugin itself, to ensure they are supporting the +same interface. + +# Usage + +To implement a new platform-specific implementation of `device_info`, extend +[`DeviceInfoPlatform`][2] with an implementation that performs the +platform-specific behavior, and when you register your plugin, set the default +`DeviceInfoPlatform` by calling +`DeviceInfoPlatform.instance = MyPlatformDeviceInfo()`. + +# Note on breaking changes + +Strongly prefer non-breaking changes (such as adding a method to the interface) +over breaking changes for this package. + +See https://flutter.dev/go/platform-interface-breaking-changes for a discussion +on why a less-clean interface is preferable to a breaking change. + +[1]: ../device_info +[2]: lib/device_info_platform_interface.dart diff --git a/packages/device_info/device_info_platform_interface/lib/device_info_platform_interface.dart b/packages/device_info/device_info_platform_interface/lib/device_info_platform_interface.dart new file mode 100644 index 000000000000..253d6d036123 --- /dev/null +++ b/packages/device_info/device_info_platform_interface/lib/device_info_platform_interface.dart @@ -0,0 +1,55 @@ +// Copyright 2017 The Chromium 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:plugin_platform_interface/plugin_platform_interface.dart'; + +import 'method_channel/method_channel_device_info.dart'; + +import 'model/android_device_info.dart'; +import 'model/ios_device_info.dart'; + +export 'model/android_device_info.dart'; +export 'model/ios_device_info.dart'; + +/// The interface that implementations of device_info must implement. +/// +/// Platform implementations should extend this class rather than implement it as `device_info` +/// does not consider newly added methods to be breaking changes. Extending this class +/// (using `extends`) ensures that the subclass will get the default implementation, while +/// platform implementations that `implements` this interface will be broken by newly added +/// [DeviceInfoPlatform] methods. +abstract class DeviceInfoPlatform extends PlatformInterface { + /// Constructs a UrlLauncherPlatform. + DeviceInfoPlatform() : super(token: _token); + + static final Object _token = Object(); + + static DeviceInfoPlatform _instance = MethodChannelDeviceInfo(); + + /// The default instance of [DeviceInfoPlatform] to use. + /// + /// Defaults to [MethodChannelDeviceInfo]. + static DeviceInfoPlatform get instance => _instance; + + /// Platform-specific plugins should set this with their own platform-specific + /// class that extends [DeviceInfoPlatform] when they register themselves. + static set instance(DeviceInfoPlatform instance) { + PlatformInterface.verifyToken(instance, _token); + _instance = instance; + } + + // Gets the Android device information. + // ignore: public_member_api_docs + Future androidInfo() { + throw UnimplementedError('androidInfo() has not been implemented.'); + } + + // Gets the iOS device information. + // ignore: public_member_api_docs + Future iosInfo() { + throw UnimplementedError('iosInfo() has not been implemented.'); + } +} diff --git a/packages/device_info/device_info_platform_interface/lib/method_channel/method_channel_device_info.dart b/packages/device_info/device_info_platform_interface/lib/method_channel/method_channel_device_info.dart new file mode 100644 index 000000000000..7bd02e97436d --- /dev/null +++ b/packages/device_info/device_info_platform_interface/lib/method_channel/method_channel_device_info.dart @@ -0,0 +1,28 @@ +import 'dart:async'; + +import 'package:flutter/services.dart'; +import 'package:meta/meta.dart'; + +import 'package:device_info_platform_interface/device_info_platform_interface.dart'; + +/// An implementation of [DeviceInfoPlatform] that uses method channels. +class MethodChannelDeviceInfo extends DeviceInfoPlatform { + /// The method channel used to interact with the native platform. + @visibleForTesting + MethodChannel channel = MethodChannel('plugins.flutter.io/device_info'); + + // Method channel for Android devices + Future androidInfo() async { + return AndroidDeviceInfo.fromMap( + (await channel.invokeMethod('getAndroidDeviceInfo')) + .cast(), + ); + } + + // Method channel for iOS devices + Future iosInfo() async { + return IosDeviceInfo.fromMap( + (await channel.invokeMethod('getIosDeviceInfo')).cast(), + ); + } +} diff --git a/packages/device_info/lib/device_info.dart b/packages/device_info/device_info_platform_interface/lib/model/android_device_info.dart similarity index 59% rename from packages/device_info/lib/device_info.dart rename to packages/device_info/device_info_platform_interface/lib/model/android_device_info.dart index 25b7d46cdb11..5b326cc5350a 100644 --- a/packages/device_info/lib/device_info.dart +++ b/packages/device_info/device_info_platform_interface/lib/model/android_device_info.dart @@ -2,46 +2,12 @@ // 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/services.dart'; - -/// Provides device and operating system information. -class DeviceInfoPlugin { - /// No work is done when instantiating the plugin. It's safe to call this - /// repeatedly or in performance-sensitive blocks. - DeviceInfoPlugin(); - - /// Channel used to communicate to native code. - static const MethodChannel channel = - MethodChannel('plugins.flutter.io/device_info'); - - /// This information does not change from call to call. Cache it. - AndroidDeviceInfo _cachedAndroidDeviceInfo; - - /// Information derived from `android.os.Build`. - /// - /// See: https://developer.android.com/reference/android/os/Build.html - Future get androidInfo async => - _cachedAndroidDeviceInfo ??= AndroidDeviceInfo._fromMap(await channel - .invokeMapMethod('getAndroidDeviceInfo')); - - /// This information does not change from call to call. Cache it. - IosDeviceInfo _cachedIosDeviceInfo; - - /// Information derived from `UIDevice`. - /// - /// See: https://developer.apple.com/documentation/uikit/uidevice - Future get iosInfo async => - _cachedIosDeviceInfo ??= IosDeviceInfo._fromMap( - await channel.invokeMapMethod('getIosDeviceInfo')); -} - /// Information derived from `android.os.Build`. /// /// See: https://developer.android.com/reference/android/os/Build.html class AndroidDeviceInfo { - AndroidDeviceInfo._({ + /// Android device Info class. + AndroidDeviceInfo({ this.version, this.board, this.bootloader, @@ -145,10 +111,10 @@ class AndroidDeviceInfo { final List systemFeatures; /// Deserializes from the message received from [_kChannel]. - static AndroidDeviceInfo _fromMap(Map map) { - return AndroidDeviceInfo._( - version: - AndroidBuildVersion._fromMap(map['version']?.cast()), + static AndroidDeviceInfo fromMap(Map map) { + return AndroidDeviceInfo( + version: AndroidBuildVersion._fromMap( + map['version']?.cast() ?? {}), board: map['board'], bootloader: map['bootloader'], brand: map['brand'], @@ -161,14 +127,14 @@ class AndroidDeviceInfo { manufacturer: map['manufacturer'], model: map['model'], product: map['product'], - supported32BitAbis: _fromList(map['supported32BitAbis']), - supported64BitAbis: _fromList(map['supported64BitAbis']), - supportedAbis: _fromList(map['supportedAbis']), + supported32BitAbis: _fromList(map['supported32BitAbis'] ?? []), + supported64BitAbis: _fromList(map['supported64BitAbis'] ?? []), + supportedAbis: _fromList(map['supportedAbis'] ?? []), tags: map['tags'], type: map['type'], isPhysicalDevice: map['isPhysicalDevice'], androidId: map['androidId'], - systemFeatures: _fromList(map['systemFeatures']), + systemFeatures: _fromList(map['systemFeatures'] ?? []), ); } @@ -230,95 +196,3 @@ class AndroidBuildVersion { ); } } - -/// Information derived from `UIDevice`. -/// -/// See: https://developer.apple.com/documentation/uikit/uidevice -class IosDeviceInfo { - IosDeviceInfo._({ - this.name, - this.systemName, - this.systemVersion, - this.model, - this.localizedModel, - this.identifierForVendor, - this.isPhysicalDevice, - this.utsname, - }); - - /// Device name. - final String name; - - /// The name of the current operating system. - final String systemName; - - /// The current operating system version. - final String systemVersion; - - /// Device model. - final String model; - - /// Localized name of the device model. - final String localizedModel; - - /// Unique UUID value identifying the current device. - final String identifierForVendor; - - /// `false` if the application is running in a simulator, `true` otherwise. - final bool isPhysicalDevice; - - /// Operating system information derived from `sys/utsname.h`. - final IosUtsname utsname; - - /// Deserializes from the map message received from [_kChannel]. - static IosDeviceInfo _fromMap(Map map) { - return IosDeviceInfo._( - name: map['name'], - systemName: map['systemName'], - systemVersion: map['systemVersion'], - model: map['model'], - localizedModel: map['localizedModel'], - identifierForVendor: map['identifierForVendor'], - isPhysicalDevice: map['isPhysicalDevice'] == 'true', - utsname: IosUtsname._fromMap(map['utsname']?.cast()), - ); - } -} - -/// Information derived from `utsname`. -/// See http://pubs.opengroup.org/onlinepubs/7908799/xsh/sysutsname.h.html for details. -class IosUtsname { - IosUtsname._({ - this.sysname, - this.nodename, - this.release, - this.version, - this.machine, - }); - - /// Operating system name. - final String sysname; - - /// Network node name. - final String nodename; - - /// Release level. - final String release; - - /// Version level. - final String version; - - /// Hardware type (e.g. 'iPhone7,1' for iPhone 6 Plus). - final String machine; - - /// Deserializes from the map message received from [_kChannel]. - static IosUtsname _fromMap(Map map) { - return IosUtsname._( - sysname: map['sysname'], - nodename: map['nodename'], - release: map['release'], - version: map['version'], - machine: map['machine'], - ); - } -} diff --git a/packages/device_info/device_info_platform_interface/lib/model/ios_device_info.dart b/packages/device_info/device_info_platform_interface/lib/model/ios_device_info.dart new file mode 100644 index 000000000000..d41202492101 --- /dev/null +++ b/packages/device_info/device_info_platform_interface/lib/model/ios_device_info.dart @@ -0,0 +1,97 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +/// Information derived from `UIDevice`. +/// +/// See: https://developer.apple.com/documentation/uikit/uidevice +class IosDeviceInfo { + /// IOS device info class. + IosDeviceInfo({ + this.name, + this.systemName, + this.systemVersion, + this.model, + this.localizedModel, + this.identifierForVendor, + this.isPhysicalDevice, + this.utsname, + }); + + /// Device name. + final String name; + + /// The name of the current operating system. + final String systemName; + + /// The current operating system version. + final String systemVersion; + + /// Device model. + final String model; + + /// Localized name of the device model. + final String localizedModel; + + /// Unique UUID value identifying the current device. + final String identifierForVendor; + + /// `false` if the application is running in a simulator, `true` otherwise. + final bool isPhysicalDevice; + + /// Operating system information derived from `sys/utsname.h`. + final IosUtsname utsname; + + /// Deserializes from the map message received from [_kChannel]. + static IosDeviceInfo fromMap(Map map) { + return IosDeviceInfo( + name: map['name'], + systemName: map['systemName'], + systemVersion: map['systemVersion'], + model: map['model'], + localizedModel: map['localizedModel'], + identifierForVendor: map['identifierForVendor'], + isPhysicalDevice: map['isPhysicalDevice'] == 'true', + utsname: + IosUtsname._fromMap(map['utsname']?.cast() ?? {}), + ); + } +} + +/// Information derived from `utsname`. +/// See http://pubs.opengroup.org/onlinepubs/7908799/xsh/sysutsname.h.html for details. +class IosUtsname { + IosUtsname._({ + this.sysname, + this.nodename, + this.release, + this.version, + this.machine, + }); + + /// Operating system name. + final String sysname; + + /// Network node name. + final String nodename; + + /// Release level. + final String release; + + /// Version level. + final String version; + + /// Hardware type (e.g. 'iPhone7,1' for iPhone 6 Plus). + final String machine; + + /// Deserializes from the map message received from [_kChannel]. + static IosUtsname _fromMap(Map map) { + return IosUtsname._( + sysname: map['sysname'], + nodename: map['nodename'], + release: map['release'], + version: map['version'], + machine: map['machine'], + ); + } +} diff --git a/packages/device_info/device_info_platform_interface/pubspec.yaml b/packages/device_info/device_info_platform_interface/pubspec.yaml new file mode 100644 index 000000000000..3adfb93fa27a --- /dev/null +++ b/packages/device_info/device_info_platform_interface/pubspec.yaml @@ -0,0 +1,22 @@ +name: device_info_platform_interface +description: A common platform interface for the device_info plugin. +homepage: https://github.com/flutter/plugins/tree/master/packages/device_info +# NOTE: We strongly prefer non-breaking changes, even at the expense of a +# less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes +version: 1.0.0 + +dependencies: + flutter: + sdk: flutter + meta: ^1.1.8 + plugin_platform_interface: ^1.0.2 + +dev_dependencies: + flutter_test: + sdk: flutter + mockito: ^4.1.1 + pedantic: ^1.8.0 + +environment: + sdk: ">=2.7.0 <3.0.0" + flutter: ">=1.9.1+hotfix.4 <2.0.0" diff --git a/packages/device_info/device_info_platform_interface/test/method_channel_device_info_test.dart b/packages/device_info/device_info_platform_interface/test/method_channel_device_info_test.dart new file mode 100644 index 000000000000..1da52e2cf39f --- /dev/null +++ b/packages/device_info/device_info_platform_interface/test/method_channel_device_info_test.dart @@ -0,0 +1,49 @@ +// Copyright 2017 The Chromium 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/services.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import 'package:device_info_platform_interface/device_info_platform_interface.dart'; + +import 'package:device_info_platform_interface/method_channel/method_channel_device_info.dart'; + +void main() { + TestWidgetsFlutterBinding.ensureInitialized(); + + group("$MethodChannelDeviceInfo", () { + MethodChannelDeviceInfo methodChannelDeviceInfo; + + setUp(() async { + methodChannelDeviceInfo = MethodChannelDeviceInfo(); + + methodChannelDeviceInfo.channel + .setMockMethodCallHandler((MethodCall methodCall) async { + switch (methodCall.method) { + case 'getAndroidDeviceInfo': + return ({ + "brand": "Google", + }); + case 'getIosDeviceInfo': + return ({ + "name": "iPhone 10", + }); + default: + return null; + } + }); + }); + + test("androidInfo", () async { + final AndroidDeviceInfo result = + await methodChannelDeviceInfo.androidInfo(); + expect(result.brand, "Google"); + }); + + test("iosInfo", () async { + final IosDeviceInfo result = await methodChannelDeviceInfo.iosInfo(); + expect(result.name, "iPhone 10"); + }); + }); +} diff --git a/packages/device_info/example/android.iml b/packages/device_info/example/android.iml deleted file mode 100644 index 462b903e05b6..000000000000 --- a/packages/device_info/example/android.iml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - diff --git a/packages/device_info/example/device_info_example.iml b/packages/device_info/example/device_info_example.iml deleted file mode 100644 index 9d5dae19540c..000000000000 --- a/packages/device_info/example/device_info_example.iml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/packages/device_info/example/device_info_example_android.iml b/packages/device_info/example/device_info_example_android.iml deleted file mode 100644 index 462b903e05b6..000000000000 --- a/packages/device_info/example/device_info_example_android.iml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - diff --git a/packages/e2e/README.md b/packages/e2e/README.md index 76440bbd079e..7f211900db70 100644 --- a/packages/e2e/README.md +++ b/packages/e2e/README.md @@ -1,11 +1,15 @@ -# e2e +# e2e (deprecated) + +## DEPRECATED + +This package has been moved to [integration_test](https://github.com/flutter/plugins/tree/master/packages/integration_test). + +## Old instructions This package enables self-driving testing of Flutter code on devices and emulators. It adapts flutter_test results into a format that is compatible with `flutter drive` and native Android instrumentation testing. -iOS support is not available yet, but is planned in the future. - ## Usage Add a dependency on the `e2e` package in the @@ -130,10 +134,12 @@ documentation](https://firebase.google.com/docs/test-lab/?gclid=EAIaIQobChMIs5qV to set up a project. To run an e2e test on Android devices using Firebase Test Lab, use gradle commands to build an -instrumentation test for Android. +instrumentation test for Android, after creating `androidTest` as suggested in the last section. -``` +```bash pushd android +# flutter build generates files in android/ for building the app +flutter build apk ./gradlew app:assembleAndroidTest ./gradlew app:assembleDebug -Ptarget=.dart popd @@ -142,7 +148,7 @@ popd Upload the build apks Firebase Test Lab, making sure to replace , , , and with your values. -``` +```bash gcloud auth activate-service-account --key-file= gcloud --quiet config set project gcloud firebase test android run --type instrumentation \ diff --git a/packages/e2e/android/settings.gradle b/packages/e2e/android/settings.gradle deleted file mode 100644 index e5d17d080b60..000000000000 --- a/packages/e2e/android/settings.gradle +++ /dev/null @@ -1 +0,0 @@ -rootProject.name = 'e2e' diff --git a/packages/e2e/example/ios/RunnerTests/RunnerTests.m b/packages/e2e/example/ios/RunnerTests/RunnerTests.m deleted file mode 100644 index 9614c6598b15..000000000000 --- a/packages/e2e/example/ios/RunnerTests/RunnerTests.m +++ /dev/null @@ -1,4 +0,0 @@ -#import -#import - -E2E_IOS_RUNNER(RunnerTests) diff --git a/packages/e2e/example/macos/Flutter/GeneratedPluginRegistrant.swift b/packages/e2e/example/macos/Flutter/GeneratedPluginRegistrant.swift deleted file mode 100644 index 2b7c33cf9b20..000000000000 --- a/packages/e2e/example/macos/Flutter/GeneratedPluginRegistrant.swift +++ /dev/null @@ -1,12 +0,0 @@ -// -// Generated file. Do not edit. -// - -import FlutterMacOS -import Foundation - -import e2e_macos - -func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { - E2EPlugin.register(with: registry.registrar(forPlugin: "E2EPlugin")) -} diff --git a/packages/e2e/example/test_driver/example_e2e_test.dart b/packages/e2e/example/test_driver/example_e2e_test.dart deleted file mode 100644 index 983c3863dea5..000000000000 --- a/packages/e2e/example/test_driver/example_e2e_test.dart +++ /dev/null @@ -1,5 +0,0 @@ -import 'dart:async'; - -import 'package:e2e/e2e_driver.dart' as e2e; - -Future main() async => e2e.main(); diff --git a/packages/e2e/ios/Classes/E2EIosTest.h b/packages/e2e/ios/Classes/E2EIosTest.h deleted file mode 100644 index 1d7651459419..000000000000 --- a/packages/e2e/ios/Classes/E2EIosTest.h +++ /dev/null @@ -1,22 +0,0 @@ -#import - -@interface E2EIosTest : NSObject - -- (BOOL)testE2E:(NSString **)testResult; - -@end - -#define E2E_IOS_RUNNER(__test_class) \ - @interface __test_class : XCTestCase \ - @end \ - \ - @implementation __test_class \ - \ - -(void)testE2E { \ - NSString *testResult; \ - E2EIosTest *e2eIosTest = [[E2EIosTest alloc] init]; \ - BOOL testPass = [e2eIosTest testE2E:&testResult]; \ - XCTAssertTrue(testPass, @"%@", testResult); \ - } \ - \ - @end diff --git a/packages/e2e/lib/e2e_driver.dart b/packages/e2e/lib/e2e_driver.dart deleted file mode 100644 index 2e43c5a36e55..000000000000 --- a/packages/e2e/lib/e2e_driver.dart +++ /dev/null @@ -1,21 +0,0 @@ -import 'dart:async'; -import 'dart:io'; - -import 'package:e2e/common.dart' as e2e; -import 'package:flutter_driver/flutter_driver.dart'; - -Future main() async { - final FlutterDriver driver = await FlutterDriver.connect(); - final String jsonResult = - await driver.requestData(null, timeout: const Duration(minutes: 1)); - final e2e.Response response = e2e.Response.fromJson(jsonResult); - await driver.close(); - - if (response.allTestsPassed) { - print('All tests passed.'); - exit(0); - } else { - print('Failure Details:\n${response.formattedFailureDetails}'); - exit(1); - } -} diff --git a/packages/e2e/test/binding_test.dart b/packages/e2e/test/binding_test.dart deleted file mode 100644 index 8c97e161b0fe..000000000000 --- a/packages/e2e/test/binding_test.dart +++ /dev/null @@ -1,41 +0,0 @@ -import 'package:flutter/material.dart'; - -import 'package:e2e/e2e.dart'; -import 'package:e2e/common.dart'; -import 'package:flutter_test/flutter_test.dart'; - -void main() async { - Future> request; - - group('Test E2E binding', () { - final WidgetsBinding binding = E2EWidgetsFlutterBinding.ensureInitialized(); - assert(binding is E2EWidgetsFlutterBinding); - final E2EWidgetsFlutterBinding e2ebinding = - binding as E2EWidgetsFlutterBinding; - - setUp(() { - request = e2ebinding.callback({ - 'command': 'request_data', - }); - }); - - testWidgets('Run E2E app', (WidgetTester tester) async { - runApp(MaterialApp( - home: Text('Test'), - )); - expect(tester.binding, e2ebinding); - e2ebinding.reportData = {'answer': 42}; - }); - }); - - tearDownAll(() async { - // This part is outside the group so that `request` has been compeleted as - // part of the `tearDownAll` registerred in the group during - // `E2EWidgetsFlutterBinding` initialization. - final Map response = - (await request)['response'] as Map; - final String message = response['message'] as String; - Response result = Response.fromJson(message); - assert(result.data['answer'] == 42); - }); -} diff --git a/packages/flutter_plugin_android_lifecycle/example/android/app/src/androidTest/java/io/flutter/plugins/flutter_plugin_android_lifecycle/EmbeddingV1ActivityTest.java b/packages/flutter_plugin_android_lifecycle/example/android/app/src/androidTest/java/io/flutter/plugins/flutter_plugin_android_lifecycle/EmbeddingV1ActivityTest.java index a5ad2176b4d0..4f1435fb1b33 100644 --- a/packages/flutter_plugin_android_lifecycle/example/android/app/src/androidTest/java/io/flutter/plugins/flutter_plugin_android_lifecycle/EmbeddingV1ActivityTest.java +++ b/packages/flutter_plugin_android_lifecycle/example/android/app/src/androidTest/java/io/flutter/plugins/flutter_plugin_android_lifecycle/EmbeddingV1ActivityTest.java @@ -5,11 +5,11 @@ package io.flutter.plugins.flutter_plugin_android_lifecycle_example; import androidx.test.rule.ActivityTestRule; -import dev.flutter.plugins.e2e.FlutterRunner; +import dev.flutter.plugins.integration_test.FlutterTestRunner; import org.junit.Rule; import org.junit.runner.RunWith; -@RunWith(FlutterRunner.class) +@RunWith(FlutterTestRunner.class) public class EmbeddingV1ActivityTest { @Rule public ActivityTestRule rule = diff --git a/packages/flutter_plugin_android_lifecycle/example/android/app/src/androidTest/java/io/flutter/plugins/flutter_plugin_android_lifecycle/MainActivityTest.java b/packages/flutter_plugin_android_lifecycle/example/android/app/src/androidTest/java/io/flutter/plugins/flutter_plugin_android_lifecycle/MainActivityTest.java index 05057c1a697e..4c3c9a247883 100644 --- a/packages/flutter_plugin_android_lifecycle/example/android/app/src/androidTest/java/io/flutter/plugins/flutter_plugin_android_lifecycle/MainActivityTest.java +++ b/packages/flutter_plugin_android_lifecycle/example/android/app/src/androidTest/java/io/flutter/plugins/flutter_plugin_android_lifecycle/MainActivityTest.java @@ -5,11 +5,11 @@ package io.flutter.plugins.flutter_plugin_android_lifecycle_example; import androidx.test.rule.ActivityTestRule; -import dev.flutter.plugins.e2e.FlutterRunner; +import dev.flutter.plugins.integration_test.FlutterTestRunner; import org.junit.Rule; import org.junit.runner.RunWith; -@RunWith(FlutterRunner.class) +@RunWith(FlutterTestRunner.class) public class MainActivityTest { @Rule public ActivityTestRule rule = new ActivityTestRule<>(MainActivity.class); } diff --git a/packages/flutter_plugin_android_lifecycle/example/android/app/src/main/java/io/flutter/plugins/flutter_plugin_android_lifecycle_example/EmbeddingV1Activity.java b/packages/flutter_plugin_android_lifecycle/example/android/app/src/main/java/io/flutter/plugins/flutter_plugin_android_lifecycle_example/EmbeddingV1Activity.java index 0eb8bb9ad407..63602ddb05e6 100644 --- a/packages/flutter_plugin_android_lifecycle/example/android/app/src/main/java/io/flutter/plugins/flutter_plugin_android_lifecycle_example/EmbeddingV1Activity.java +++ b/packages/flutter_plugin_android_lifecycle/example/android/app/src/main/java/io/flutter/plugins/flutter_plugin_android_lifecycle_example/EmbeddingV1Activity.java @@ -1,7 +1,7 @@ package io.flutter.plugins.flutter_plugin_android_lifecycle_example; import android.os.Bundle; -import dev.flutter.plugins.e2e.E2EPlugin; +import dev.flutter.plugins.integration_test.IntegrationTestPlugin; import io.flutter.app.FlutterActivity; import io.flutter.plugins.flutter_plugin_android_lifecycle.FlutterAndroidLifecyclePlugin; @@ -9,7 +9,8 @@ public class EmbeddingV1Activity extends FlutterActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - E2EPlugin.registerWith(registrarFor("dev.flutter.plugins.e2e.E2EPlugin")); + IntegrationTestPlugin.registerWith( + registrarFor("dev.flutter.plugins.integration_test.IntegrationTestPlugin")); FlutterAndroidLifecyclePlugin.registerWith( registrarFor( "io.flutter.plugins.flutter_plugin_android_lifecycle.FlutterAndroidLifecyclePlugin")); diff --git a/packages/flutter_plugin_android_lifecycle/example/android/app/src/main/java/io/flutter/plugins/flutter_plugin_android_lifecycle_example/MainActivity.java b/packages/flutter_plugin_android_lifecycle/example/android/app/src/main/java/io/flutter/plugins/flutter_plugin_android_lifecycle_example/MainActivity.java index 2ea33493eb3c..e2d2560e9105 100644 --- a/packages/flutter_plugin_android_lifecycle/example/android/app/src/main/java/io/flutter/plugins/flutter_plugin_android_lifecycle_example/MainActivity.java +++ b/packages/flutter_plugin_android_lifecycle/example/android/app/src/main/java/io/flutter/plugins/flutter_plugin_android_lifecycle_example/MainActivity.java @@ -6,7 +6,7 @@ import android.util.Log; import androidx.lifecycle.Lifecycle; -import dev.flutter.plugins.e2e.E2EPlugin; +import dev.flutter.plugins.integration_test.IntegrationTestPlugin; import io.flutter.embedding.android.FlutterActivity; import io.flutter.embedding.engine.FlutterEngine; import io.flutter.embedding.engine.plugins.FlutterPlugin; @@ -20,7 +20,7 @@ public class MainActivity extends FlutterActivity { @Override public void configureFlutterEngine(FlutterEngine flutterEngine) { flutterEngine.getPlugins().add(new TestPlugin()); - flutterEngine.getPlugins().add(new E2EPlugin()); + flutterEngine.getPlugins().add(new IntegrationTestPlugin()); } private static class TestPlugin implements FlutterPlugin, ActivityAware { diff --git a/packages/flutter_plugin_android_lifecycle/example/pubspec.yaml b/packages/flutter_plugin_android_lifecycle/example/pubspec.yaml index 379e0b804f4e..a040dbe95d92 100644 --- a/packages/flutter_plugin_android_lifecycle/example/pubspec.yaml +++ b/packages/flutter_plugin_android_lifecycle/example/pubspec.yaml @@ -8,7 +8,8 @@ environment: dependencies: flutter: sdk: flutter - e2e: "^0.2.1" + integration_test: + path: ../../integration_test dev_dependencies: flutter_test: diff --git a/packages/flutter_plugin_android_lifecycle/example/test_driver/flutter_plugin_android_lifecycle_e2e.dart b/packages/flutter_plugin_android_lifecycle/example/test_driver/flutter_plugin_android_lifecycle_e2e.dart index 5abead07d132..1405ab69153c 100644 --- a/packages/flutter_plugin_android_lifecycle/example/test_driver/flutter_plugin_android_lifecycle_e2e.dart +++ b/packages/flutter_plugin_android_lifecycle/example/test_driver/flutter_plugin_android_lifecycle_e2e.dart @@ -3,11 +3,11 @@ // BSD-style license that can be found in the LICENSE file. import 'package:flutter_test/flutter_test.dart'; -import 'package:e2e/e2e.dart'; +import 'package:integration_test/integration_test.dart'; import 'package:flutter_plugin_android_lifecycle_example/main.dart'; void main() { - E2EWidgetsFlutterBinding.ensureInitialized(); + IntegrationTestWidgetsFlutterBinding.ensureInitialized(); testWidgets('loads', (WidgetTester tester) async { await tester.pumpWidget(MyApp()); diff --git a/packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md b/packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md index 8ad0c02d3f77..02b257d6b168 100644 --- a/packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md +++ b/packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md @@ -1,3 +1,17 @@ +## 0.5.30 + +* Add a `dispose` method to the controller to let the native side know that we're done with said controller. +* Call `controller.dispose()` from the `dispose` method of the `GoogleMap` widget. + +## 0.5.29+1 + +* (ios) Pin dependency on GoogleMaps pod to `< 3.10`, to address https://github.com/flutter/flutter/issues/63447 + +## 0.5.29 + +* Pass a constant `_web_only_mapCreationId` to `platform.buildView`, so web can return a cached widget DOM when flutter attempts to repaint there. +* Modify some examples slightly so they're more web-friendly. + ## 0.5.28+2 * Move test introduced in #2449 to its right location. diff --git a/packages/google_maps_flutter/google_maps_flutter/example/android/app/src/androidTest/java/io/flutter/plugins/googlemaps/EmbeddingV1ActivityTest.java b/packages/google_maps_flutter/google_maps_flutter/example/android/app/src/androidTest/java/io/flutter/plugins/googlemaps/EmbeddingV1ActivityTest.java index ff39d1ddf55d..d8064e441fbd 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/android/app/src/androidTest/java/io/flutter/plugins/googlemaps/EmbeddingV1ActivityTest.java +++ b/packages/google_maps_flutter/google_maps_flutter/example/android/app/src/androidTest/java/io/flutter/plugins/googlemaps/EmbeddingV1ActivityTest.java @@ -1,12 +1,12 @@ package io.flutter.plugins.googlemaps; import androidx.test.rule.ActivityTestRule; -import dev.flutter.plugins.e2e.FlutterRunner; +import dev.flutter.plugins.integration_test.FlutterTestRunner; import io.flutter.plugins.googlemapsexample.*; import org.junit.Rule; import org.junit.runner.RunWith; -@RunWith(FlutterRunner.class) +@RunWith(FlutterTestRunner.class) public class EmbeddingV1ActivityTest { @Rule public ActivityTestRule rule = diff --git a/packages/google_maps_flutter/google_maps_flutter/example/android/app/src/androidTest/java/io/flutter/plugins/googlemaps/MainActivityTest.java b/packages/google_maps_flutter/google_maps_flutter/example/android/app/src/androidTest/java/io/flutter/plugins/googlemaps/MainActivityTest.java index 525d2da8d665..c70f16a17454 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/android/app/src/androidTest/java/io/flutter/plugins/googlemaps/MainActivityTest.java +++ b/packages/google_maps_flutter/google_maps_flutter/example/android/app/src/androidTest/java/io/flutter/plugins/googlemaps/MainActivityTest.java @@ -1,12 +1,12 @@ package io.flutter.plugins.googlemaps; import androidx.test.rule.ActivityTestRule; -import dev.flutter.plugins.e2e.FlutterRunner; +import dev.flutter.plugins.integration_test.FlutterTestRunner; import io.flutter.embedding.android.FlutterActivity; import org.junit.Rule; import org.junit.runner.RunWith; -@RunWith(FlutterRunner.class) +@RunWith(FlutterTestRunner.class) public class MainActivityTest { @Rule public ActivityTestRule rule = new ActivityTestRule<>(FlutterActivity.class); diff --git a/packages/google_maps_flutter/google_maps_flutter/example/android/app/src/main/java/io/flutter/plugins/googlemapsexample/EmbeddingV1Activity.java b/packages/google_maps_flutter/google_maps_flutter/example/android/app/src/main/java/io/flutter/plugins/googlemapsexample/EmbeddingV1Activity.java index 8d7b3054bf5f..18b107d47620 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/android/app/src/main/java/io/flutter/plugins/googlemapsexample/EmbeddingV1Activity.java +++ b/packages/google_maps_flutter/google_maps_flutter/example/android/app/src/main/java/io/flutter/plugins/googlemapsexample/EmbeddingV1Activity.java @@ -1,7 +1,7 @@ package io.flutter.plugins.googlemapsexample; import android.os.Bundle; -import dev.flutter.plugins.e2e.E2EPlugin; +import dev.flutter.plugins.integration_test.IntegrationTestPlugin; import io.flutter.app.FlutterActivity; import io.flutter.plugins.googlemaps.GoogleMapsPlugin; @@ -10,6 +10,7 @@ public class EmbeddingV1Activity extends FlutterActivity { protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); GoogleMapsPlugin.registerWith(registrarFor("io.flutter.plugins.googlemaps.GoogleMapsPlugin")); - E2EPlugin.registerWith(registrarFor("dev.flutter.plugins.e2e.E2EPlugin")); + IntegrationTestPlugin.registerWith( + registrarFor("dev.flutter.plugins.integration_test.IntegrationTestPlugin")); } } diff --git a/packages/google_maps_flutter/google_maps_flutter/example/lib/marker_icons.dart b/packages/google_maps_flutter/google_maps_flutter/example/lib/marker_icons.dart index e0fcc427c1d6..b62d898c3a3b 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/lib/marker_icons.dart +++ b/packages/google_maps_flutter/google_maps_flutter/example/lib/marker_icons.dart @@ -73,7 +73,7 @@ class MarkerIconsBodyState extends State { Future _createMarkerImageFromAsset(BuildContext context) async { if (_markerIcon == null) { final ImageConfiguration imageConfiguration = - createLocalImageConfiguration(context); + createLocalImageConfiguration(context, size: Size.square(48)); BitmapDescriptor.fromAssetImage( imageConfiguration, 'assets/red_square.png') .then(_updateBitmap); diff --git a/packages/google_maps_flutter/google_maps_flutter/example/lib/place_polyline.dart b/packages/google_maps_flutter/google_maps_flutter/example/lib/place_polyline.dart index 0c9da634faa7..35ffd33a53c2 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/lib/place_polyline.dart +++ b/packages/google_maps_flutter/google_maps_flutter/example/lib/place_polyline.dart @@ -4,8 +4,7 @@ // ignore_for_file: public_member_api_docs -import 'dart:io' show Platform; - +import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:google_maps_flutter/google_maps_flutter.dart'; @@ -202,7 +201,9 @@ class PlacePolylineBodyState extends State { @override Widget build(BuildContext context) { - final bool iOSorNotSelected = Platform.isIOS || (selectedPolyline == null); + final bool iOSorNotSelected = + (!kIsWeb && defaultTargetPlatform == TargetPlatform.iOS) || + (selectedPolyline == null); return Column( mainAxisAlignment: MainAxisAlignment.spaceEvenly, diff --git a/packages/google_maps_flutter/google_maps_flutter/example/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter/example/pubspec.yaml index c7b2c5ff6715..7bfc7a6feb9c 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/pubspec.yaml +++ b/packages/google_maps_flutter/google_maps_flutter/example/pubspec.yaml @@ -16,7 +16,8 @@ dev_dependencies: flutter_driver: sdk: flutter test: ^1.6.0 - e2e: ^0.2.1 + integration_test: + path: ../../../integration_test pedantic: ^1.8.0 # For information on the generic Dart part of this file, see the @@ -58,5 +59,5 @@ flutter: # - asset: fonts/TrajanPro_Bold.ttf # weight: 700 # - # For details regarding fonts from package dependencies, + # For details regarding fonts from package dependencies, # see https://flutter.io/custom-fonts/#from-packages diff --git a/packages/google_maps_flutter/google_maps_flutter/example/test_driver/google_maps_e2e.dart b/packages/google_maps_flutter/google_maps_flutter/example/test_driver/google_maps_e2e.dart index c47862b2b4d1..2a5bf80a4578 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/test_driver/google_maps_e2e.dart +++ b/packages/google_maps_flutter/google_maps_flutter/example/test_driver/google_maps_e2e.dart @@ -6,7 +6,7 @@ import 'dart:async'; import 'dart:io'; import 'dart:typed_data'; -import 'package:e2e/e2e.dart'; +import 'package:integration_test/integration_test.dart'; import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_test/flutter_test.dart'; @@ -20,7 +20,7 @@ const CameraPosition _kInitialCameraPosition = CameraPosition(target: _kInitialMapCenter, zoom: _kInitialZoomLevel); void main() { - E2EWidgetsFlutterBinding.ensureInitialized(); + IntegrationTestWidgetsFlutterBinding.ensureInitialized(); testWidgets('testCompassToggle', (WidgetTester tester) async { final Key key = GlobalKey(); @@ -424,6 +424,7 @@ void main() { }); testWidgets('testInitialCenterLocationAtCenter', (WidgetTester tester) async { + await tester.binding.setSurfaceSize(const Size(800.0, 600.0)); final Completer mapControllerCompleter = Completer(); final Key key = GlobalKey(); @@ -443,6 +444,7 @@ void main() { await mapControllerCompleter.future; await tester.pumpAndSettle(); + // TODO(cyanglaz): Remove this after we added `mapRendered` callback, and `mapControllerCompleter.complete(controller)` above should happen // in `mapRendered`. // https://github.com/flutter/flutter/issues/54758 @@ -468,6 +470,7 @@ void main() { tester.binding.window.devicePixelRatio) .round()); } + await tester.binding.setSurfaceSize(null); }); testWidgets('testGetVisibleRegion', (WidgetTester tester) async { diff --git a/packages/google_maps_flutter/google_maps_flutter/example/test_driver/google_maps_e2e_test.dart b/packages/google_maps_flutter/google_maps_flutter/example/test_driver/google_maps_e2e_test.dart index f3aa9e218d82..7a2c21338786 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/test_driver/google_maps_e2e_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter/example/test_driver/google_maps_e2e_test.dart @@ -3,13 +3,15 @@ // BSD-style license that can be found in the LICENSE file. import 'dart:async'; +import 'dart:convert'; import 'dart:io'; import 'package:flutter_driver/flutter_driver.dart'; Future main() async { final FlutterDriver driver = await FlutterDriver.connect(); - final String result = + final String data = await driver.requestData(null, timeout: const Duration(minutes: 1)); await driver.close(); - exit(result == 'pass' ? 0 : 1); + final Map result = jsonDecode(data); + exit(result['result'] == 'true' ? 0 : 1); } diff --git a/packages/google_maps_flutter/google_maps_flutter/ios/google_maps_flutter.podspec b/packages/google_maps_flutter/google_maps_flutter/ios/google_maps_flutter.podspec index 9a1f04d59759..021abfee71ab 100644 --- a/packages/google_maps_flutter/google_maps_flutter/ios/google_maps_flutter.podspec +++ b/packages/google_maps_flutter/google_maps_flutter/ios/google_maps_flutter.podspec @@ -17,7 +17,8 @@ Downloaded by pub (not CocoaPods). s.source_files = 'Classes/**/*' s.public_header_files = 'Classes/**/*.h' s.dependency 'Flutter' - s.dependency 'GoogleMaps' + # TODO: Unpin this once the fix for b/163474612 or b/163359804 rolls (avoid v3.10!) + s.dependency 'GoogleMaps', '< 3.10' s.static_framework = true s.platform = :ios, '8.0' s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'VALID_ARCHS[sdk=iphonesimulator*]' => 'x86_64' } diff --git a/packages/google_maps_flutter/google_maps_flutter/lib/src/controller.dart b/packages/google_maps_flutter/google_maps_flutter/lib/src/controller.dart index f5ee180ab1fd..f47b8e57b049 100644 --- a/packages/google_maps_flutter/google_maps_flutter/lib/src/controller.dart +++ b/packages/google_maps_flutter/google_maps_flutter/lib/src/controller.dart @@ -258,4 +258,9 @@ class GoogleMapController { Future takeSnapshot() { return _googleMapsFlutterPlatform.takeSnapshot(mapId: mapId); } + + /// Disposes of the platform resources + void dispose() { + _googleMapsFlutterPlatform.dispose(mapId: mapId); + } } diff --git a/packages/google_maps_flutter/google_maps_flutter/lib/src/google_map.dart b/packages/google_maps_flutter/google_maps_flutter/lib/src/google_map.dart index a45a1c8e3fe4..d7f0f1a4e280 100644 --- a/packages/google_maps_flutter/google_maps_flutter/lib/src/google_map.dart +++ b/packages/google_maps_flutter/google_maps_flutter/lib/src/google_map.dart @@ -10,6 +10,12 @@ part of google_maps_flutter; /// map is created. typedef void MapCreatedCallback(GoogleMapController controller); +// This counter is used to provide a stable "constant" initialization id +// to the buildView function, so the web implementation can use it as a +// cache key. This needs to be provided from the outside, because web +// views seem to re-render much more often that mobile platform views. +int _webOnlyMapId = 0; + /// A widget which displays a map with data obtained from the Google Maps service. class GoogleMap extends StatefulWidget { /// Creates a widget displaying data from Google Maps services. @@ -205,6 +211,8 @@ class GoogleMap extends StatefulWidget { } class _GoogleMapState extends State { + final _webOnlyMapCreationId = _webOnlyMapId++; + final Completer _controller = Completer(); @@ -223,7 +231,9 @@ class _GoogleMapState extends State { 'polygonsToAdd': serializePolygonSet(widget.polygons), 'polylinesToAdd': serializePolylineSet(widget.polylines), 'circlesToAdd': serializeCircleSet(widget.circles), + '_webOnlyMapCreationId': _webOnlyMapCreationId, }; + return _googleMapsFlutterPlatform.buildView( creationParams, widget.gestureRecognizers, @@ -241,6 +251,13 @@ class _GoogleMapState extends State { _circles = keyByCircleId(widget.circles); } + @override + void dispose() async { + super.dispose(); + GoogleMapController controller = await _controller.future; + controller.dispose(); + } + @override void didUpdateWidget(GoogleMap oldWidget) { super.didUpdateWidget(oldWidget); diff --git a/packages/google_maps_flutter/google_maps_flutter/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter/pubspec.yaml index 5e3cf226f03d..e7e3aeeb3327 100644 --- a/packages/google_maps_flutter/google_maps_flutter/pubspec.yaml +++ b/packages/google_maps_flutter/google_maps_flutter/pubspec.yaml @@ -1,13 +1,13 @@ name: google_maps_flutter description: A Flutter plugin for integrating Google Maps in iOS and Android applications. homepage: https://github.com/flutter/plugins/tree/master/packages/google_maps_flutter/google_maps_flutter -version: 0.5.28+2 +version: 0.5.30 dependencies: flutter: sdk: flutter flutter_plugin_android_lifecycle: ^1.0.0 - google_maps_flutter_platform_interface: ^1.0.1 + google_maps_flutter_platform_interface: ^1.0.4 dev_dependencies: flutter_test: @@ -19,6 +19,8 @@ dev_dependencies: sdk: flutter test: ^1.6.0 pedantic: ^1.8.0 + plugin_platform_interface: ^1.0.2 + mockito: ^4.1.1 flutter: plugin: diff --git a/packages/google_maps_flutter/google_maps_flutter/test/map_creation_test.dart b/packages/google_maps_flutter/google_maps_flutter/test/map_creation_test.dart new file mode 100644 index 000000000000..5ea9a679a1be --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter/test/map_creation_test.dart @@ -0,0 +1,121 @@ +// Copyright 2018 The Chromium 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/widgets.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:google_maps_flutter/google_maps_flutter.dart'; +import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart'; +import 'package:plugin_platform_interface/plugin_platform_interface.dart'; +import 'package:mockito/mockito.dart'; + +class MockGoogleMapsFlutterPlatform extends Mock + with MockPlatformInterfaceMixin + implements GoogleMapsFlutterPlatform {} + +void main() { + TestWidgetsFlutterBinding.ensureInitialized(); + final platform = MockGoogleMapsFlutterPlatform(); + + setUp(() { + // Use a mock platform so we never need to hit the MethodChannel code. + GoogleMapsFlutterPlatform.instance = platform; + resetMockitoState(); + _setupMock(platform); + }); + + testWidgets('_webOnlyMapCreationId increments with each GoogleMap widget', ( + WidgetTester tester, + ) async { + // Inject two map widgets... + await tester.pumpWidget( + Directionality( + textDirection: TextDirection.ltr, + child: Column( + children: const [ + GoogleMap( + initialCameraPosition: CameraPosition( + target: LatLng(43.362, -5.849), + ), + ), + GoogleMap( + initialCameraPosition: CameraPosition( + target: LatLng(47.649, -122.350), + ), + ), + ], + ), + ), + ); + + // Verify that each one was created with a different _webOnlyMapCreationId. + verifyInOrder([ + platform.buildView( + argThat(containsPair('_webOnlyMapCreationId', 0)), + any, + any, + ), + platform.buildView( + argThat(containsPair('_webOnlyMapCreationId', 1)), + any, + any, + ), + ]); + }); + + testWidgets('Calls platform.dispose when GoogleMap is disposed of', ( + WidgetTester tester, + ) async { + await tester.pumpWidget(GoogleMap( + initialCameraPosition: CameraPosition( + target: LatLng(43.3608, -5.8702), + ), + )); + + // Now dispose of the map... + await tester.pumpWidget(Container()); + + verify(platform.dispose(mapId: anyNamed('mapId'))); + }); +} + +// Some test setup classes below... + +class _MockStream extends Mock implements Stream {} + +typedef _CreationCallback = void Function(int); + +// Installs test mocks on the platform +void _setupMock(MockGoogleMapsFlutterPlatform platform) { + // Used to create the view of the map... + when(platform.buildView(any, any, any)).thenAnswer((realInvocation) { + // Call the onPlatformViewCreated callback so the controller gets created. + _CreationCallback onPlatformViewCreatedCb = + realInvocation.positionalArguments[2]; + onPlatformViewCreatedCb.call(0); + return Container(); + }); + // Used to create the Controller + when(platform.onCameraIdle(mapId: anyNamed('mapId'))) + .thenAnswer((_) => _MockStream()); + when(platform.onCameraMove(mapId: anyNamed('mapId'))) + .thenAnswer((_) => _MockStream()); + when(platform.onCameraMoveStarted(mapId: anyNamed('mapId'))) + .thenAnswer((_) => _MockStream()); + when(platform.onCircleTap(mapId: anyNamed('mapId'))) + .thenAnswer((_) => _MockStream()); + when(platform.onInfoWindowTap(mapId: anyNamed('mapId'))) + .thenAnswer((_) => _MockStream()); + when(platform.onLongPress(mapId: anyNamed('mapId'))) + .thenAnswer((_) => _MockStream()); + when(platform.onMarkerDragEnd(mapId: anyNamed('mapId'))) + .thenAnswer((_) => _MockStream()); + when(platform.onMarkerTap(mapId: anyNamed('mapId'))) + .thenAnswer((_) => _MockStream()); + when(platform.onPolygonTap(mapId: anyNamed('mapId'))) + .thenAnswer((_) => _MockStream()); + when(platform.onPolylineTap(mapId: anyNamed('mapId'))) + .thenAnswer((_) => _MockStream()); + when(platform.onTap(mapId: anyNamed('mapId'))) + .thenAnswer((_) => _MockStream()); +} diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/CHANGELOG.md b/packages/google_maps_flutter/google_maps_flutter_platform_interface/CHANGELOG.md index eca5c914a603..dc8eddf8b557 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/CHANGELOG.md +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/CHANGELOG.md @@ -1,3 +1,11 @@ +## 1.0.4 + +* Add a `dispose` method to the interface, so implementations may cleanup resources acquired on `init`. + +## 1.0.3 + +* Pass icon width/height if present on `fromAssetImage` BitmapDescriptors (web only) + ## 1.0.2 * Update lower bound of dart dependency to 2.1.0. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/method_channel/method_channel_google_maps_flutter.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/method_channel/method_channel_google_maps_flutter.dart index edbc51ab5afd..31392354d946 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/method_channel/method_channel_google_maps_flutter.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/method_channel/method_channel_google_maps_flutter.dart @@ -48,6 +48,12 @@ class MethodChannelGoogleMapsFlutter extends GoogleMapsFlutterPlatform { return channel.invokeMethod('map#waitForMap'); } + /// Dispose of the native resources. + @override + void dispose({int mapId}) { + // Noop! + } + // The controller we need to broadcast the different events coming // from handleMethodCall. // diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/platform_interface/google_maps_flutter_platform.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/platform_interface/google_maps_flutter_platform.dart index b89d3420c68e..a4f487740811 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/platform_interface/google_maps_flutter_platform.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/platform_interface/google_maps_flutter_platform.dart @@ -304,6 +304,11 @@ abstract class GoogleMapsFlutterPlatform extends PlatformInterface { throw UnimplementedError('onLongPress() has not been implemented.'); } + /// Dispose of whatever resources the `mapId` is holding on to. + void dispose({@required int mapId}) { + throw UnimplementedError('dispose() has not been implemented.'); + } + /// Returns a widget displaying the map view Widget buildView( Map creationParams, diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/bitmap.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/bitmap.dart index 40581b43e065..a6fdcc1b7e33 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/bitmap.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/bitmap.dart @@ -9,6 +9,8 @@ import 'package:flutter/material.dart' show ImageConfiguration, AssetImage, AssetBundleImageKey; import 'package:flutter/services.dart' show AssetBundle; +import 'package:flutter/foundation.dart' show kIsWeb; + /// Defines a bitmap image. For a marker, this class can be used to set the /// image of the marker icon. For a ground overlay, it can be used to set the /// image to place on the surface of the earth. @@ -100,6 +102,11 @@ class BitmapDescriptor { 'fromAssetImage', assetBundleImageKey.name, assetBundleImageKey.scale, + if (kIsWeb && configuration?.size != null) + [ + configuration.size.width, + configuration.size.height, + ], ]); } diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter_platform_interface/pubspec.yaml index b28b7f47652d..fd3a1c434960 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/pubspec.yaml +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/pubspec.yaml @@ -3,7 +3,7 @@ description: A common platform interface for the google_maps_flutter plugin. homepage: https://github.com/flutter/plugins/tree/master/packages/google_maps_flutter/google_maps_flutter_platform_interface # NOTE: We strongly prefer non-breaking changes, even at the expense of a # less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes -version: 1.0.2 +version: 1.0.4 dependencies: flutter: @@ -19,5 +19,5 @@ dev_dependencies: pedantic: ^1.8.0 environment: - sdk: ">=2.1.0 <3.0.0" + sdk: ">=2.3.0 <3.0.0" flutter: ">=1.9.1+hotfix.4 <2.0.0" diff --git a/packages/google_maps_flutter/google_maps_flutter_web/CHANGELOG.md b/packages/google_maps_flutter/google_maps_flutter_web/CHANGELOG.md new file mode 100644 index 000000000000..1c4272849c05 --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_web/CHANGELOG.md @@ -0,0 +1,7 @@ +## 0.1.0+1 + +* Port e2e tests to use the new integration_test package. + +## 0.1.0 + +* First open-source version diff --git a/packages/google_maps_flutter/google_maps_flutter_web/LICENSE b/packages/google_maps_flutter/google_maps_flutter_web/LICENSE new file mode 100644 index 000000000000..282a0f51aa4a --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_web/LICENSE @@ -0,0 +1,26 @@ +Copyright 2017, the Flutter project authors. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of Google Inc. nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/packages/google_maps_flutter/google_maps_flutter_web/README.md b/packages/google_maps_flutter/google_maps_flutter_web/README.md new file mode 100644 index 000000000000..e1c1a5330c56 --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_web/README.md @@ -0,0 +1,51 @@ +# google_maps_flutter_web + +This is an implementation of the [google_maps_flutter](https://pub.dev/packages/google_maps_flutter) plugin for web. Behind the scenes, it uses a14n's [google_maps](https://pub.dev/packages/google_maps) dart JS interop layer. + +## Usage + +### Depend on the package + +This package is not an endorsed implementation of the google_maps_flutter plugin yet, so you'll need to modify the `pubspec.yaml` file of your app to depend on this package: + +```yaml +dependencies: + google_maps_flutter: ^0.5.28 + google_maps_flutter_web: ^0.1.0 +``` + +### Modify web/index.html + +Get an API Key for Google Maps JavaScript API. Get started [here](https://developers.google.com/maps/documentation/javascript/get-api-key). + +Modify the `` tag of your `web/index.html` to load the Google Maps JavaScript API, like so: + +```html + + + + + + +``` + +Now you should be able to use the Google Maps plugin normally. + +## Limitations of the web version + +The following map options are not available in web, because the map doesn't rotate there: + +* `compassEnabled` +* `rotateGesturesEnabled` +* `tiltGesturesEnabled` + +There's no "Map Toolbar" in web, so the `mapToolbarEnabled` option is unused. + +There's no "My Location" widget in web ([tracking issue](https://github.com/flutter/flutter/issues/64073)), so the following options are ignored, for now: + +* `myLocationButtonEnabled` +* `myLocationEnabled` + +There's no `defaultMarkerWithHue` in web. If you need colored pins/markers, you may need to use your own asset images. + +Indoor and building layers are still not available on the web. Traffic is. diff --git a/packages/google_maps_flutter/google_maps_flutter_web/analysis_options.yaml b/packages/google_maps_flutter/google_maps_flutter_web/analysis_options.yaml new file mode 100644 index 000000000000..443b16551ec9 --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_web/analysis_options.yaml @@ -0,0 +1,10 @@ +# This is a temporary file to allow us to unblock the flutter/plugins repo CI. +# It disables some of lints that were disabled inline. Disabling lints inline +# is no longer possible, so this file is required. +# TODO(ditman) https://github.com/flutter/flutter/issues/55000 (clean this up) + +include: ../../../analysis_options.yaml + +analyzer: + errors: + undefined_prefixed_name: ignore diff --git a/packages/google_maps_flutter/google_maps_flutter_web/ios/google_maps_flutter_web.podspec b/packages/google_maps_flutter/google_maps_flutter_web/ios/google_maps_flutter_web.podspec new file mode 100644 index 000000000000..18db6ced01b6 --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_web/ios/google_maps_flutter_web.podspec @@ -0,0 +1,23 @@ +# +# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html. +# Run `pod lib lint google_maps_flutter_web.podspec' to validate before publishing. +# +Pod::Spec.new do |s| + s.name = 'google_maps_flutter_web' + s.version = '0.1.0' + s.summary = 'No-op implementation of google maps flutter web plugin to avoid build issues on iOS' + s.description = <<-DESC +temp fake google_maps_flutter_web plugin + DESC + s.homepage = 'https://github.com/flutter/plugins/tree/master/packages/google_maps_flutter/google_maps_flutter_web' + s.license = { :file => '../LICENSE' } + s.author = { 'Flutter Team' => 'flutter-dev@googlegroups.com' } + s.source = { :path => '.' } + s.source_files = 'Classes/**/*' + s.dependency 'Flutter' + s.platform = :ios, '8.0' + + # Flutter.framework does not contain a i386 slice. Only x86_64 simulators are supported. + s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'VALID_ARCHS[sdk=iphonesimulator*]' => 'x86_64' } + s.swift_version = '5.0' +end diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/google_maps_flutter_web.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/google_maps_flutter_web.dart new file mode 100644 index 000000000000..cf133fb9e533 --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/google_maps_flutter_web.dart @@ -0,0 +1,39 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +library google_maps_flutter_web; + +import 'dart:async'; +import 'dart:html'; +import 'dart:ui' as ui; +import 'dart:convert'; + +import 'package:flutter/rendering.dart'; +import 'package:flutter/widgets.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/foundation.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter/gestures.dart'; + +import 'package:sanitize_html/sanitize_html.dart'; + +import 'package:stream_transform/stream_transform.dart'; + +import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart'; +import 'package:flutter_web_plugins/flutter_web_plugins.dart'; +import 'package:google_maps/google_maps.dart' as gmaps; + +import 'src/types.dart'; + +part 'src/google_maps_flutter_web.dart'; +part 'src/google_maps_controller.dart'; +part 'src/circle.dart'; +part 'src/circles.dart'; +part 'src/polygon.dart'; +part 'src/polygons.dart'; +part 'src/polyline.dart'; +part 'src/polylines.dart'; +part 'src/marker.dart'; +part 'src/markers.dart'; +part 'src/convert.dart'; diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/circle.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/circle.dart new file mode 100644 index 000000000000..96f9be7aa001 --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/circle.dart @@ -0,0 +1,46 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +part of google_maps_flutter_web; + +/// The `CircleController` class wraps a [gmaps.Circle] and its `onTap` behavior. +class CircleController { + gmaps.Circle _circle; + + final bool _consumeTapEvents; + + /// Creates a `CircleController`, which wraps a [gmaps.Circle] object and its `onTap` behavior. + CircleController({ + @required gmaps.Circle circle, + bool consumeTapEvents = false, + ui.VoidCallback onTap, + }) : _circle = circle, + _consumeTapEvents = consumeTapEvents { + if (onTap != null) { + circle.onClick.listen((_) { + onTap.call(); + }); + } + } + + /// Returns the wrapped [gmaps.Circle]. Only used for testing. + @visibleForTesting + gmaps.Circle get circle => _circle; + + /// Returns `true` if this Controller will use its own `onTap` handler to consume events. + bool get consumeTapEvents => _consumeTapEvents; + + /// Updates the options of the wrapped [gmaps.Circle] object. + void update(gmaps.CircleOptions options) { + _circle.options = options; + } + + /// Disposes of the currently wrapped [gmaps.Circle]. + void remove() { + _circle.visible = false; + _circle.radius = 0; + _circle.map = null; + _circle = null; + } +} diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/circles.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/circles.dart new file mode 100644 index 000000000000..c7c33ed1811f --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/circles.dart @@ -0,0 +1,79 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +part of google_maps_flutter_web; + +/// This class manages all the [CircleController]s associated to a [GoogleMapController]. +class CirclesController extends GeometryController { + // A cache of [CircleController]s indexed by their [CircleId]. + final Map _circleIdToController; + + // The stream over which circles broadcast their events + StreamController _streamController; + + /// Initialize the cache. The [StreamController] comes from the [GoogleMapController], and is shared with other controllers. + CirclesController({ + @required StreamController stream, + }) : _streamController = stream, + _circleIdToController = Map(); + + /// Returns the cache of [CircleController]s. Test only. + @visibleForTesting + Map get circles => _circleIdToController; + + /// Adds a set of [Circle] objects to the cache. + /// + /// Wraps each [Circle] into its corresponding [CircleController]. + void addCircles(Set circlesToAdd) { + circlesToAdd?.forEach((circle) { + _addCircle(circle); + }); + } + + void _addCircle(Circle circle) { + if (circle == null) { + return; + } + + final populationOptions = _circleOptionsFromCircle(circle); + gmaps.Circle gmCircle = gmaps.Circle(populationOptions); + gmCircle.map = googleMap; + CircleController controller = CircleController( + circle: gmCircle, + consumeTapEvents: circle.consumeTapEvents, + onTap: () { + _onCircleTap(circle.circleId); + }); + _circleIdToController[circle.circleId] = controller; + } + + /// Updates a set of [Circle] objects with new options. + void changeCircles(Set circlesToChange) { + circlesToChange?.forEach((circleToChange) { + _changeCircle(circleToChange); + }); + } + + void _changeCircle(Circle circle) { + final circleController = _circleIdToController[circle?.circleId]; + circleController?.update(_circleOptionsFromCircle(circle)); + } + + /// Removes a set of [CircleId]s from the cache. + void removeCircles(Set circleIdsToRemove) { + circleIdsToRemove?.forEach((circleId) { + final CircleController circleController = _circleIdToController[circleId]; + circleController?.remove(); + _circleIdToController.remove(circleId); + }); + } + + // Handles the global onCircleTap function to funnel events from circles into the stream. + bool _onCircleTap(CircleId circleId) { + // Have you ended here on your debugging? Is this wrong? + // Comment here: https://github.com/flutter/flutter/issues/64084 + _streamController.add(CircleTapEvent(mapId, circleId)); + return _circleIdToController[circleId]?.consumeTapEvents ?? false; + } +} diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart new file mode 100644 index 000000000000..2eeaa0202995 --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart @@ -0,0 +1,544 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +part of google_maps_flutter_web; + +final _nullLatLng = LatLng(0, 0); +final _nullLatLngBounds = LatLngBounds( + northeast: _nullLatLng, + southwest: _nullLatLng, +); + +// Defaults taken from the Google Maps Platform SDK documentation. +final _defaultStrokeColor = Colors.black.value; +final _defaultFillColor = Colors.transparent.value; + +// Indices in the plugin side don't match with the ones +// in the gmaps lib. This translates from plugin -> gmaps. +final _mapTypeToMapTypeId = { + 0: gmaps.MapTypeId.ROADMAP, // "none" in the plugin + 1: gmaps.MapTypeId.ROADMAP, + 2: gmaps.MapTypeId.SATELLITE, + 3: gmaps.MapTypeId.TERRAIN, + 4: gmaps.MapTypeId.HYBRID, +}; + +// Converts options from the plugin into gmaps.MapOptions that can be used by the JS SDK. +// The following options are not handled here, for various reasons: +// The following are not available in web, because the map doesn't rotate there: +// compassEnabled +// rotateGesturesEnabled +// tiltGesturesEnabled +// mapToolbarEnabled is unused in web, there's no "map toolbar" +// myLocationButtonEnabled Widget not available in web yet, it needs to be built on top of the maps widget +// See: https://developers.google.com/maps/documentation/javascript/examples/control-custom +// myLocationEnabled needs to be built through dart:html navigator.geolocation +// See: https://api.dart.dev/stable/2.8.4/dart-html/Geolocation-class.html +// trafficEnabled is handled when creating the GMap object, since it needs to be added as a layer. +// trackCameraPosition is just a boolan value that indicates if the map has an onCameraMove handler. +// indoorViewEnabled seems to not have an equivalent in web +// buildingsEnabled seems to not have an equivalent in web +// padding seems to behave differently in web than mobile. You can't move UI elements in web. +gmaps.MapOptions _rawOptionsToGmapsOptions(Map rawOptions) { + Map optionsUpdate = rawOptions['options'] ?? {}; + + gmaps.MapOptions options = gmaps.MapOptions(); + + if (_mapTypeToMapTypeId.containsKey(optionsUpdate['mapType'])) { + options.mapTypeId = _mapTypeToMapTypeId[optionsUpdate['mapType']]; + } + + if (optionsUpdate['minMaxZoomPreference'] != null) { + options + ..minZoom = optionsUpdate['minMaxZoomPreference'][0] + ..maxZoom = optionsUpdate['minMaxZoomPreference'][1]; + } + + if (optionsUpdate['cameraTargetBounds'] != null) { + // Needs gmaps.MapOptions.restriction and gmaps.MapRestriction + // see: https://developers.google.com/maps/documentation/javascript/reference/map#MapOptions.restriction + } + + if (optionsUpdate['zoomControlsEnabled'] != null) { + options.zoomControl = optionsUpdate['zoomControlsEnabled']; + } + + if (optionsUpdate['styles'] != null) { + options.styles = optionsUpdate['styles']; + } + + if (optionsUpdate['scrollGesturesEnabled'] == false || + optionsUpdate['zoomGesturesEnabled'] == false) { + options.gestureHandling = 'none'; + } else { + options.gestureHandling = 'auto'; + } + + // These don't have any optionUpdate entry, but they seem to be off in the native maps. + options.mapTypeControl = false; + options.fullscreenControl = false; + options.streetViewControl = false; + + return options; +} + +gmaps.MapOptions _applyInitialPosition( + Map rawOptions, + gmaps.MapOptions options, +) { + // Adjust the initial position, if passed... + Map initialPosition = rawOptions['initialCameraPosition']; + if (initialPosition != null) { + final position = CameraPosition.fromMap(initialPosition); + options.zoom = position.zoom; + options.center = + gmaps.LatLng(position.target.latitude, position.target.longitude); + } + return options; +} + +// Extracts the status of the traffic layer from the rawOptions map. +bool _isTrafficLayerEnabled(Map rawOptions) { + if (rawOptions['options'] == null) { + return false; + } + return rawOptions['options']['trafficEnabled'] ?? false; +} + +// Coverts the incoming JSON object into a List of MapTypeStyler objects. +List _parseStylers(List stylerJsons) { + return stylerJsons?.map((styler) { + return gmaps.MapTypeStyler() + ..color = styler['color'] + ..gamma = styler['gamma'] + ..hue = styler['hue'] + ..invertLightness = styler['invertLightness'] + ..lightness = styler['lightness'] + ..saturation = styler['saturation'] + ..visibility = styler['visibility'] + ..weight = styler['weight']; + })?.toList(); +} + +// Converts a String to its corresponding MapTypeStyleElementType enum value. +final _elementTypeToEnum = { + 'all': gmaps.MapTypeStyleElementType.ALL, + 'geometry': gmaps.MapTypeStyleElementType.GEOMETRY, + 'geometry.fill': gmaps.MapTypeStyleElementType.GEOMETRY_FILL, + 'geometry.stroke': gmaps.MapTypeStyleElementType.GEOMETRY_STROKE, + 'labels': gmaps.MapTypeStyleElementType.LABELS, + 'labels.icon': gmaps.MapTypeStyleElementType.LABELS_ICON, + 'labels.text': gmaps.MapTypeStyleElementType.LABELS_TEXT, + 'labels.text.fill': gmaps.MapTypeStyleElementType.LABELS_TEXT_FILL, + 'labels.text.stroke': gmaps.MapTypeStyleElementType.LABELS_TEXT_STROKE, +}; + +// Converts a String to its corresponding MapTypeStyleFeatureType enum value. +final _featureTypeToEnum = { + 'administrative': gmaps.MapTypeStyleFeatureType.ADMINISTRATIVE, + 'administrative.country': + gmaps.MapTypeStyleFeatureType.ADMINISTRATIVE_COUNTRY, + 'administrative.land_parcel': + gmaps.MapTypeStyleFeatureType.ADMINISTRATIVE_LAND_PARCEL, + 'administrative.locality': + gmaps.MapTypeStyleFeatureType.ADMINISTRATIVE_LOCALITY, + 'administrative.neighborhood': + gmaps.MapTypeStyleFeatureType.ADMINISTRATIVE_NEIGHBORHOOD, + 'administrative.province': + gmaps.MapTypeStyleFeatureType.ADMINISTRATIVE_PROVINCE, + 'all': gmaps.MapTypeStyleFeatureType.ALL, + 'landscape': gmaps.MapTypeStyleFeatureType.LANDSCAPE, + 'landscape.man_made': gmaps.MapTypeStyleFeatureType.LANDSCAPE_MAN_MADE, + 'landscape.natural': gmaps.MapTypeStyleFeatureType.LANDSCAPE_NATURAL, + 'landscape.natural.landcover': + gmaps.MapTypeStyleFeatureType.LANDSCAPE_NATURAL_LANDCOVER, + 'landscape.natural.terrain': + gmaps.MapTypeStyleFeatureType.LANDSCAPE_NATURAL_TERRAIN, + 'poi': gmaps.MapTypeStyleFeatureType.POI, + 'poi.attraction': gmaps.MapTypeStyleFeatureType.POI_ATTRACTION, + 'poi.business': gmaps.MapTypeStyleFeatureType.POI_BUSINESS, + 'poi.government': gmaps.MapTypeStyleFeatureType.POI_GOVERNMENT, + 'poi.medical': gmaps.MapTypeStyleFeatureType.POI_MEDICAL, + 'poi.park': gmaps.MapTypeStyleFeatureType.POI_PARK, + 'poi.place_of_worship': gmaps.MapTypeStyleFeatureType.POI_PLACE_OF_WORSHIP, + 'poi.school': gmaps.MapTypeStyleFeatureType.POI_SCHOOL, + 'poi.sports_complex': gmaps.MapTypeStyleFeatureType.POI_SPORTS_COMPLEX, + 'road': gmaps.MapTypeStyleFeatureType.ROAD, + 'road.arterial': gmaps.MapTypeStyleFeatureType.ROAD_ARTERIAL, + 'road.highway': gmaps.MapTypeStyleFeatureType.ROAD_HIGHWAY, + 'road.highway.controlled_access': + gmaps.MapTypeStyleFeatureType.ROAD_HIGHWAY_CONTROLLED_ACCESS, + 'road.local': gmaps.MapTypeStyleFeatureType.ROAD_LOCAL, + 'transit': gmaps.MapTypeStyleFeatureType.TRANSIT, + 'transit.line': gmaps.MapTypeStyleFeatureType.TRANSIT_LINE, + 'transit.station': gmaps.MapTypeStyleFeatureType.TRANSIT_STATION, + 'transit.station.airport': + gmaps.MapTypeStyleFeatureType.TRANSIT_STATION_AIRPORT, + 'transit.station.bus': gmaps.MapTypeStyleFeatureType.TRANSIT_STATION_BUS, + 'transit.station.rail': gmaps.MapTypeStyleFeatureType.TRANSIT_STATION_RAIL, + 'water': gmaps.MapTypeStyleFeatureType.WATER, +}; + +// The keys we'd expect to see in a serialized MapTypeStyle JSON object. +final _mapStyleKeys = { + 'elementType', + 'featureType', + 'stylers', +}; + +// Checks if the passed in Map contains some of the _mapStyleKeys. +bool _isJsonMapStyle(Map value) { + return _mapStyleKeys.intersection(value.keys.toSet()).isNotEmpty; +} + +// Converts an incoming JSON-encoded Style info, into the correct gmaps array. +List _mapStyles(String mapStyleJson) { + List styles = []; + if (mapStyleJson != null) { + styles = json.decode(mapStyleJson, reviver: (key, value) { + if (value is Map && _isJsonMapStyle(value)) { + return gmaps.MapTypeStyle() + ..elementType = _elementTypeToEnum[value['elementType']] + ..featureType = _featureTypeToEnum[value['featureType']] + ..stylers = _parseStylers(value['stylers']); + } + return value; + }).cast(); + } + return styles; +} + +gmaps.LatLng _latLngToGmLatLng(LatLng latLng) { + if (latLng == null) return null; + return gmaps.LatLng(latLng.latitude, latLng.longitude); +} + +LatLng _gmLatLngToLatLng(gmaps.LatLng latLng) { + if (latLng == null) return _nullLatLng; + return LatLng(latLng.lat, latLng.lng); +} + +LatLngBounds _gmLatLngBoundsTolatLngBounds(gmaps.LatLngBounds latLngBounds) { + if (latLngBounds == null) { + return _nullLatLngBounds; + } + + return LatLngBounds( + southwest: _gmLatLngToLatLng(latLngBounds.southWest), + northeast: _gmLatLngToLatLng(latLngBounds.northEast), + ); +} + +CameraPosition _gmViewportToCameraPosition(gmaps.GMap map) { + return CameraPosition( + target: _gmLatLngToLatLng(map.center), + bearing: map.heading ?? 0, + tilt: map.tilt ?? 0, + zoom: map.zoom?.toDouble() ?? 10, + ); +} + +Set _rawOptionsToInitialMarkers(Map rawOptions) { + final List> list = rawOptions['markersToAdd']; + Set markers = {}; + markers.addAll(list?.map((rawMarker) { + Offset offset; + LatLng position; + InfoWindow infoWindow; + if (rawMarker['anchor'] != null) { + offset = Offset((rawMarker['anchor'][0]), (rawMarker['anchor'][1])); + } + if (rawMarker['position'] != null) { + position = LatLng.fromJson(rawMarker['position']); + } + if (rawMarker['infoWindow'] != null || rawMarker['snippet'] != null) { + String title = rawMarker['infoWindow'] != null + ? rawMarker['infoWindow']['title'] + : null; + infoWindow = InfoWindow( + title: title ?? '', + snippet: rawMarker['snippet'] ?? '', + ); + } + return Marker( + markerId: MarkerId(rawMarker['markerId']), + alpha: rawMarker['alpha'], + anchor: offset, + consumeTapEvents: rawMarker['consumeTapEvents'], + draggable: rawMarker['draggable'], + flat: rawMarker['flat'], + // TODO: Doesn't this support custom icons? + icon: BitmapDescriptor.defaultMarker, + infoWindow: infoWindow, + position: position ?? _nullLatLng, + rotation: rawMarker['rotation'], + visible: rawMarker['visible'], + zIndex: rawMarker['zIndex'], + ); + }) ?? + []); + return markers; +} + +Set _rawOptionsToInitialCircles(Map rawOptions) { + final List> list = rawOptions['circlesToAdd']; + Set circles = {}; + circles.addAll(list?.map((rawCircle) { + LatLng center; + if (rawCircle['center'] != null) { + center = LatLng.fromJson(rawCircle['center']); + } + return Circle( + circleId: CircleId(rawCircle['circleId']), + consumeTapEvents: rawCircle['consumeTapEvents'], + fillColor: Color(rawCircle['fillColor'] ?? _defaultFillColor), + center: center ?? _nullLatLng, + radius: rawCircle['radius'], + strokeColor: Color(rawCircle['strokeColor'] ?? _defaultStrokeColor), + strokeWidth: rawCircle['strokeWidth'], + visible: rawCircle['visible'], + zIndex: rawCircle['zIndex'], + ); + }) ?? + []); + return circles; +} + +// Unsupported on the web: endCap, jointType, patterns and startCap. +Set _rawOptionsToInitialPolylines(Map rawOptions) { + final List> list = rawOptions['polylinesToAdd']; + Set polylines = {}; + polylines.addAll(list?.map((rawPolyline) { + return Polyline( + polylineId: PolylineId(rawPolyline['polylineId']), + consumeTapEvents: rawPolyline['consumeTapEvents'], + color: Color(rawPolyline['color'] ?? _defaultStrokeColor), + geodesic: rawPolyline['geodesic'], + visible: rawPolyline['visible'], + zIndex: rawPolyline['zIndex'], + width: rawPolyline['width'], + points: rawPolyline['points'] + ?.map((rawPoint) => LatLng.fromJson(rawPoint)) + ?.toList(), + ); + }) ?? + []); + return polylines; +} + +Set _rawOptionsToInitialPolygons(Map rawOptions) { + final List> list = rawOptions['polygonsToAdd']; + Set polygons = {}; + + polygons.addAll(list?.map((rawPolygon) { + return Polygon( + polygonId: PolygonId(rawPolygon['polygonId']), + consumeTapEvents: rawPolygon['consumeTapEvents'], + fillColor: Color(rawPolygon['fillColor'] ?? _defaultFillColor), + geodesic: rawPolygon['geodesic'], + strokeColor: Color(rawPolygon['strokeColor'] ?? _defaultStrokeColor), + strokeWidth: rawPolygon['strokeWidth'], + visible: rawPolygon['visible'], + zIndex: rawPolygon['zIndex'], + points: rawPolygon['points'] + ?.map((rawPoint) => LatLng.fromJson(rawPoint)) + ?.toList(), + ); + }) ?? + []); + return polygons; +} + +// Convert plugin objects to gmaps.Options objects +// TODO: Move to their appropriate objects, maybe make these copy constructors: +// Marker.fromMarker(anotherMarker, moreOptions); + +gmaps.InfoWindowOptions _infoWindowOptionsFromMarker(Marker marker) { + if ((marker.infoWindow?.title?.isEmpty ?? true) && + (marker.infoWindow?.snippet?.isEmpty ?? true)) { + return null; + } + + final content = '

' + + sanitizeHtml(marker.infoWindow.title ?? "") + + '

' + + sanitizeHtml(marker.infoWindow.snippet ?? ""); + + return gmaps.InfoWindowOptions() + ..content = content + ..zIndex = marker.zIndex; + // TODO: Compute the pixelOffset of the infoWindow, from the size of the Marker, + // and the marker.infoWindow.anchor property. +} + +// Computes the options for a new [gmaps.Marker] from an incoming set of options +// [marker], and the existing marker registered with the map: [currentMarker]. +// Preserves the position from the [currentMarker], if set. +gmaps.MarkerOptions _markerOptionsFromMarker( + Marker marker, + gmaps.Marker currentMarker, +) { + final iconConfig = marker.icon.toJson() as List; + gmaps.Icon icon; + + if (iconConfig[0] == 'fromAssetImage') { + // iconConfig[2] contains the DPIs of the screen, but that information is + // already encoded in the iconConfig[1] + + icon = gmaps.Icon() + ..url = ui.webOnlyAssetManager.getAssetUrl(iconConfig[1]); + + // iconConfig[3] may contain the [width, height] of the image, if passed! + if (iconConfig.length >= 4 && iconConfig[3] != null) { + final size = gmaps.Size(iconConfig[3][0], iconConfig[3][1]); + icon + ..size = size + ..scaledSize = size; + } + } + return gmaps.MarkerOptions() + ..position = currentMarker?.position ?? + gmaps.LatLng( + marker.position.latitude, + marker.position.longitude, + ) + ..title = sanitizeHtml(marker.infoWindow?.title ?? "") + ..zIndex = marker.zIndex + ..visible = marker.visible + ..opacity = marker.alpha + ..draggable = marker.draggable + ..icon = icon; + // TODO: Compute anchor properly, otherwise infowindows attach to the wrong spot. + // Flat and Rotation are not supported directly on the web. +} + +gmaps.CircleOptions _circleOptionsFromCircle(Circle circle) { + final populationOptions = gmaps.CircleOptions() + ..strokeColor = '#' + circle.strokeColor.value.toRadixString(16) + ..strokeOpacity = 0.8 + ..strokeWeight = circle.strokeWidth + ..fillColor = '#' + circle.fillColor.value.toRadixString(16) + ..fillOpacity = 0.6 + ..center = gmaps.LatLng(circle.center.latitude, circle.center.longitude) + ..radius = circle.radius + ..visible = circle.visible; + return populationOptions; +} + +gmaps.PolygonOptions _polygonOptionsFromPolygon( + gmaps.GMap googleMap, Polygon polygon) { + List paths = []; + polygon.points.forEach((point) { + paths.add(_latLngToGmLatLng(point)); + }); + return gmaps.PolygonOptions() + ..paths = paths + ..strokeColor = '#' + polygon.strokeColor.value.toRadixString(16) + ..strokeOpacity = 0.8 + ..strokeWeight = polygon.strokeWidth + ..fillColor = '#' + polygon.fillColor.value.toRadixString(16) + ..fillOpacity = 0.35 + ..visible = polygon.visible + ..zIndex = polygon.zIndex + ..geodesic = polygon.geodesic; +} + +gmaps.PolylineOptions _polylineOptionsFromPolyline( + gmaps.GMap googleMap, Polyline polyline) { + List paths = []; + polyline.points.forEach((point) { + paths.add(_latLngToGmLatLng(point)); + }); + + return gmaps.PolylineOptions() + ..path = paths + ..strokeOpacity = 1.0 + ..strokeWeight = polyline.width + ..strokeColor = '#' + polyline.color.value.toRadixString(16).substring(0, 6) + ..visible = polyline.visible + ..zIndex = polyline.zIndex + ..geodesic = polyline.geodesic; +// this.endCap = Cap.buttCap, +// this.jointType = JointType.mitered, +// this.patterns = const [], +// this.startCap = Cap.buttCap, +// this.width = 10, +} + +// Translates a [CameraUpdate] into operations on a [gmaps.GMap]. +void _applyCameraUpdate(gmaps.GMap map, CameraUpdate update) { + final json = update.toJson(); + switch (json[0]) { + case 'newCameraPosition': + map.heading = json[1]['bearing']; + map.zoom = json[1]['zoom']; + map.panTo(gmaps.LatLng(json[1]['target'][0], json[1]['target'][1])); + map.tilt = json[1]['tilt']; + break; + case 'newLatLng': + map.panTo(gmaps.LatLng(json[1][0], json[1][1])); + break; + case 'newLatLngZoom': + map.zoom = json[2]; + map.panTo(gmaps.LatLng(json[1][0], json[1][1])); + break; + case 'newLatLngBounds': + map.fitBounds(gmaps.LatLngBounds( + gmaps.LatLng(json[1][0][0], json[1][0][1]), + gmaps.LatLng(json[1][1][0], json[1][1][1]))); + // padding = json[2]; + // Needs package:google_maps ^4.0.0 to adjust the padding in fitBounds + break; + case 'scrollBy': + map.panBy(json[1], json[2]); + break; + case 'zoomBy': + gmaps.LatLng focusLatLng; + double zoomDelta = json[1] ?? 0; + // Web only supports integer changes... + int newZoomDelta = zoomDelta < 0 ? zoomDelta.floor() : zoomDelta.ceil(); + if (json.length == 3) { + // With focus + try { + focusLatLng = _pixelToLatLng(map, json[2][0], json[2][1]); + } catch (e) { + // https://github.com/a14n/dart-google-maps/issues/87 + // print('Error computing new focus LatLng. JS Error: ' + e.toString()); + } + } + map.zoom = map.zoom + newZoomDelta; + if (focusLatLng != null) { + map.panTo(focusLatLng); + } + break; + case 'zoomIn': + map.zoom++; + break; + case 'zoomOut': + map.zoom--; + break; + case 'zoomTo': + map.zoom = json[1]; + break; + default: + throw UnimplementedError('Unimplemented CameraMove: ${json[0]}.'); + } +} + +// original JS by: Byron Singh (https://stackoverflow.com/a/30541162) +gmaps.LatLng _pixelToLatLng(gmaps.GMap map, int x, int y) { + final ne = map.bounds.northEast; + final sw = map.bounds.southWest; + final projection = map.projection; + + final topRight = projection.fromLatLngToPoint(ne); + final bottomLeft = projection.fromLatLngToPoint(sw); + + final scale = 1 << map.zoom; // 2 ^ zoom + + final point = + gmaps.Point((x / scale) + bottomLeft.x, (y / scale) + topRight.y); + + return projection.fromPointToLatLng(point); +} diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart new file mode 100644 index 000000000000..707af828e2c6 --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart @@ -0,0 +1,330 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +part of google_maps_flutter_web; + +/// Type used when passing an override to the _createMap function. +@visibleForTesting +typedef DebugCreateMapFunction = gmaps.GMap Function( + HtmlElement div, gmaps.MapOptions options); + +/// Encapsulates a [gmaps.GMap], its events, and where in the DOM it's rendered. +class GoogleMapController { + // The internal ID of the map. Used to broadcast events, DOM IDs and everything where a unique ID is needed. + final int _mapId; + + // The raw options passed by the user, before converting to gmaps. + // Caching this allows us to re-create the map faithfully when needed. + Map _rawOptions = { + 'options': {}, + }; + + // Creates the 'viewType' for the _widget + String _getViewType(int mapId) => 'plugins.flutter.io/google_maps_$mapId'; + + // The Flutter widget that contains the rendered Map. + HtmlElementView _widget; + HtmlElement _div; + + /// The Flutter widget that will contain the rendered Map. Used for caching. + HtmlElementView get widget { + if (_widget == null && !_streamController.isClosed) { + _widget = HtmlElementView( + viewType: _getViewType(_mapId), + ); + } + return _widget; + } + + // The currently-enabled traffic layer. + gmaps.TrafficLayer _trafficLayer; + + /// A getter for the current traffic layer. Only for tests. + @visibleForTesting + gmaps.TrafficLayer get trafficLayer => _trafficLayer; + + // The underlying GMap instance. This is the interface with the JS SDK. + gmaps.GMap _googleMap; + + // The StreamController used by this controller and the geometry ones. + final StreamController _streamController; + + /// The Stream over which this controller broadcasts events. + Stream get events => _streamController.stream; + + // Geometry controllers, for different features of the map. + CirclesController _circlesController; + PolygonsController _polygonsController; + PolylinesController _polylinesController; + MarkersController _markersController; + // Keeps track if _attachGeometryControllers has been called or not. + bool _controllersBoundToMap = false; + + // Keeps track if the map is moving or not. + bool _mapIsMoving = false; + + /// Initializes the GMap, and the sub-controllers related to it. Wires events. + GoogleMapController({ + @required int mapId, + @required StreamController streamController, + @required Map rawOptions, + }) : this._mapId = mapId, + this._streamController = streamController, + this._rawOptions = rawOptions { + _circlesController = CirclesController(stream: this._streamController); + _polygonsController = PolygonsController(stream: this._streamController); + _polylinesController = PolylinesController(stream: this._streamController); + _markersController = MarkersController(stream: this._streamController); + + // Register the view factory that will hold the `_div` that holds the map in the DOM. + // The `_div` needs to be created outside of the ViewFactory (and cached!) so we can + // use it to create the [gmaps.GMap] in the `init()` method of this class. + _div = DivElement()..id = _getViewType(mapId); + + ui.platformViewRegistry.registerViewFactory( + _getViewType(mapId), + (int viewId) => _div, + ); + } + + /// Overrides certain properties to install mocks defined during testing. + @visibleForTesting + void debugSetOverrides({ + DebugCreateMapFunction createMap, + MarkersController markers, + CirclesController circles, + PolygonsController polygons, + PolylinesController polylines, + }) { + _overrideCreateMap = createMap; + _markersController = markers ?? _markersController; + _circlesController = circles ?? _circlesController; + _polygonsController = polygons ?? _polygonsController; + _polylinesController = polylines ?? _polylinesController; + } + + DebugCreateMapFunction _overrideCreateMap; + + gmaps.GMap _createMap(HtmlElement div, gmaps.MapOptions options) { + if (_overrideCreateMap != null) { + return _overrideCreateMap(div, options); + } + return gmaps.GMap(div, options); + } + + /// Initializes the [gmaps.GMap] instance from the stored `rawOptions`. + /// + /// This method actually renders the GMap into the cached `_div`. This is + /// called by the [GoogleMapsPlugin.init] method when appropriate. + /// + /// Failure to call this method would result in the GMap not rendering at all, + /// and most of the public methods on this class no-op'ing. + void init() { + var options = _rawOptionsToGmapsOptions(_rawOptions); + // Initial position can only to be set here! + options = _applyInitialPosition(_rawOptions, options); + + // Create the map... + _googleMap = _createMap(_div, options); + + _attachMapEvents(_googleMap); + _attachGeometryControllers(_googleMap); + + _renderInitialGeometry( + markers: _rawOptionsToInitialMarkers(_rawOptions), + circles: _rawOptionsToInitialCircles(_rawOptions), + polygons: _rawOptionsToInitialPolygons(_rawOptions), + polylines: _rawOptionsToInitialPolylines(_rawOptions), + ); + + _setTrafficLayer(_googleMap, _isTrafficLayerEnabled(_rawOptions)); + } + + // Funnels map gmap events into the plugin's stream controller. + void _attachMapEvents(gmaps.GMap map) { + map.onClick.listen((event) { + _streamController.add( + MapTapEvent(_mapId, _gmLatLngToLatLng(event.latLng)), + ); + }); + map.onRightclick.listen((event) { + _streamController.add( + MapLongPressEvent(_mapId, _gmLatLngToLatLng(event.latLng)), + ); + }); + map.onBoundsChanged.listen((event) { + if (!_mapIsMoving) { + _mapIsMoving = true; + _streamController.add(CameraMoveStartedEvent(_mapId)); + } + _streamController.add( + CameraMoveEvent(_mapId, _gmViewportToCameraPosition(map)), + ); + }); + map.onIdle.listen((event) { + _mapIsMoving = false; + _streamController.add(CameraIdleEvent(_mapId)); + }); + } + + // Binds the Geometry controllers to a map instance + void _attachGeometryControllers(gmaps.GMap map) { + // Now we can add the initial geometry. + // And bind the (ready) map instance to the other geometry controllers. + _circlesController.bindToMap(_mapId, map); + _polygonsController.bindToMap(_mapId, map); + _polylinesController.bindToMap(_mapId, map); + _markersController.bindToMap(_mapId, map); + _controllersBoundToMap = true; + } + + // Renders the initial sets of geometry. + void _renderInitialGeometry({ + Set markers, + Set circles, + Set polygons, + Set polylines, + }) { + assert( + _controllersBoundToMap, + 'Geometry controllers must be bound to a map before any geometry can ' + + 'be added to them. Ensure _attachGeometryControllers is called first.'); + _markersController.addMarkers(markers); + _circlesController.addCircles(circles); + _polygonsController.addPolygons(polygons); + _polylinesController.addPolylines(polylines); + } + + // Merges new options coming from the plugin into the `key` entry of the _rawOptions map. + // + // By default: `key` is 'options'. + // + // Returns the updated _rawOptions object. + Map _mergeRawOptions( + Map newOptions, { + String key = 'options', + }) { + _rawOptions[key] = { + ...(_rawOptions[key] ?? {}), + ...newOptions, + }; + return _rawOptions; + } + + /// Updates the map options from a `Map`. + /// + /// This method converts the map into the proper [gmaps.MapOptions] + void updateRawOptions(Map optionsUpdate) { + final newOptions = _mergeRawOptions(optionsUpdate); + + _setOptions(_rawOptionsToGmapsOptions(newOptions)); + _setTrafficLayer(_googleMap, _isTrafficLayerEnabled(newOptions)); + } + + // Sets new [gmaps.MapOptions] on the wrapped map. + void _setOptions(gmaps.MapOptions options) { + _googleMap?.options = options; + } + + // Attaches/detaches a Traffic Layer on the passed `map` if `attach` is true/false. + void _setTrafficLayer(gmaps.GMap map, bool attach) { + if (attach && _trafficLayer == null) { + _trafficLayer = gmaps.TrafficLayer(); + _trafficLayer.set('map', map); + } + if (!attach && _trafficLayer != null) { + _trafficLayer.set('map', null); + _trafficLayer = null; + } + } + + // _googleMap manipulation + // Viewport + + /// Returns the [LatLngBounds] of the current viewport. + Future getVisibleRegion() async { + return _gmLatLngBoundsTolatLngBounds(await _googleMap.bounds); + } + + /// Returns the [ScreenCoordinate] for a given viewport [LatLng]. + Future getScreenCoordinate(LatLng latLng) async { + final point = + _googleMap.projection.fromLatLngToPoint(_latLngToGmLatLng(latLng)); + return ScreenCoordinate(x: point.x, y: point.y); + } + + /// Returns the [LatLng] for a `screenCoordinate` (in pixels) of the viewport. + Future getLatLng(ScreenCoordinate screenCoordinate) async { + final latLng = _googleMap.projection.fromPointToLatLng( + gmaps.Point(screenCoordinate.x, screenCoordinate.y), + ); + return _gmLatLngToLatLng(latLng); + } + + /// Applies a `cameraUpdate` to the current viewport. + Future moveCamera(CameraUpdate cameraUpdate) async { + return _applyCameraUpdate(_googleMap, cameraUpdate); + } + + /// Returns the zoom level of the current viewport. + Future getZoomLevel() async => _googleMap.zoom.toDouble(); + + // Geometry manipulation + + /// Applies [CircleUpdates] to the currently managed circles. + void updateCircles(CircleUpdates updates) { + _circlesController?.addCircles(updates.circlesToAdd); + _circlesController?.changeCircles(updates.circlesToChange); + _circlesController?.removeCircles(updates.circleIdsToRemove); + } + + /// Applies [PolygonUpdates] to the currently managed polygons. + void updatePolygons(PolygonUpdates updates) { + _polygonsController?.addPolygons(updates.polygonsToAdd); + _polygonsController?.changePolygons(updates.polygonsToChange); + _polygonsController?.removePolygons(updates.polygonIdsToRemove); + } + + /// Applies [PolylineUpdates] to the currently managed lines. + void updatePolylines(PolylineUpdates updates) { + _polylinesController?.addPolylines(updates.polylinesToAdd); + _polylinesController?.changePolylines(updates.polylinesToChange); + _polylinesController?.removePolylines(updates.polylineIdsToRemove); + } + + /// Applies [MarkerUpdates] to the currently managed markers. + void updateMarkers(MarkerUpdates updates) { + _markersController?.addMarkers(updates.markersToAdd); + _markersController?.changeMarkers(updates.markersToChange); + _markersController?.removeMarkers(updates.markerIdsToRemove); + } + + /// Shows the [InfoWindow] of the marker identified by its [MarkerId]. + void showInfoWindow(MarkerId markerId) { + _markersController?.showMarkerInfoWindow(markerId); + } + + /// Hides the [InfoWindow] of the marker identified by its [MarkerId]. + void hideInfoWindow(MarkerId markerId) { + _markersController?.hideMarkerInfoWindow(markerId); + } + + /// Returns true if the [InfoWindow] of the marker identified by [MarkerId] is shown. + bool isInfoWindowShown(MarkerId markerId) { + return _markersController?.isInfoWindowShown(markerId); + } + + // Cleanup + + /// Disposes of this controller and its resources. + void dispose() { + _widget = null; + _googleMap = null; + _circlesController = null; + _polygonsController = null; + _polylinesController = null; + _markersController = null; + _streamController.close(); + } +} diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_flutter_web.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_flutter_web.dart new file mode 100644 index 000000000000..cf549e8e375e --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_flutter_web.dart @@ -0,0 +1,291 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +part of google_maps_flutter_web; + +/// The web implementation of [GoogleMapsFlutterPlatform]. +/// +/// This class implements the `package:google_maps_flutter` functionality for the web. +class GoogleMapsPlugin extends GoogleMapsFlutterPlatform { + /// Registers this class as the default instance of [GoogleMapsFlutterPlatform]. + static void registerWith(Registrar registrar) { + GoogleMapsFlutterPlatform.instance = GoogleMapsPlugin(); + } + + // A cache of map controllers by map Id. + Map _mapById = Map(); + + /// Allows tests to inject controllers without going through the buildView flow. + @visibleForTesting + void debugSetMapById(Map mapById) { + _mapById = mapById; + } + + // Convenience getter for a stream of events filtered by their mapId. + Stream _events(int mapId) => _map(mapId).events; + + // Convenience getter for a map controller by its mapId. + GoogleMapController _map(int mapId) { + final controller = _mapById[mapId]; + assert(controller != null, + 'Maps cannot be retrieved before calling buildView!'); + return controller; + } + + @override + Future init(int mapId) async { + _map(mapId).init(); + } + + /// Updates the options of a given `mapId`. + /// + /// This attempts to merge the new `optionsUpdate` passed in, with the previous + /// options passed to the map (in other updates, or when creating it). + @override + Future updateMapOptions( + Map optionsUpdate, { + @required int mapId, + }) async { + _map(mapId).updateRawOptions(optionsUpdate); + } + + /// Applies the passed in `markerUpdates` to the `mapId`. + @override + Future updateMarkers( + MarkerUpdates markerUpdates, { + @required int mapId, + }) async { + _map(mapId).updateMarkers(markerUpdates); + } + + /// Applies the passed in `polygonUpdates` to the `mapId`. + @override + Future updatePolygons( + PolygonUpdates polygonUpdates, { + @required int mapId, + }) async { + _map(mapId).updatePolygons(polygonUpdates); + } + + /// Applies the passed in `polylineUpdates` to the `mapId`. + @override + Future updatePolylines( + PolylineUpdates polylineUpdates, { + @required int mapId, + }) async { + _map(mapId).updatePolylines(polylineUpdates); + } + + /// Applies the passed in `circleUpdates` to the `mapId`. + @override + Future updateCircles( + CircleUpdates circleUpdates, { + @required int mapId, + }) async { + _map(mapId).updateCircles(circleUpdates); + } + + /// Applies the given `cameraUpdate` to the current viewport (with animation). + @override + Future animateCamera( + CameraUpdate cameraUpdate, { + @required int mapId, + }) async { + return moveCamera(cameraUpdate, mapId: mapId); + } + + /// Applies the given `cameraUpdate` to the current viewport. + @override + Future moveCamera( + CameraUpdate cameraUpdate, { + @required int mapId, + }) async { + return _map(mapId).moveCamera(cameraUpdate); + } + + /// Sets the passed-in `mapStyle` to the map. + /// + /// This function just adds a 'styles' option to the current map options. + /// + /// Subsequent calls to this method override previous calls, you need to + /// pass full styles. + @override + Future setMapStyle( + String mapStyle, { + @required int mapId, + }) async { + _map(mapId).updateRawOptions({ + 'styles': _mapStyles(mapStyle), + }); + } + + /// Returns the bounds of the current viewport. + @override + Future getVisibleRegion({ + @required int mapId, + }) { + return _map(mapId).getVisibleRegion(); + } + + /// Returns the screen coordinate (in pixels) of a given `latLng`. + @override + Future getScreenCoordinate( + LatLng latLng, { + @required int mapId, + }) { + return _map(mapId).getScreenCoordinate(latLng); + } + + /// Returns the [LatLng] of a [ScreenCoordinate] of the viewport. + @override + Future getLatLng( + ScreenCoordinate screenCoordinate, { + @required int mapId, + }) { + return _map(mapId).getLatLng(screenCoordinate); + } + + /// Shows the [InfoWindow] (if any) of the [Marker] identified by `markerId`. + /// + /// See also: + /// * [hideMarkerInfoWindow] to hide the info window. + /// * [isMarkerInfoWindowShown] to check if the info window is visible/hidden. + @override + Future showMarkerInfoWindow( + MarkerId markerId, { + @required int mapId, + }) async { + _map(mapId).showInfoWindow(markerId); + } + + /// Hides the [InfoWindow] (if any) of the [Marker] identified by `markerId`. + /// + /// See also: + /// * [showMarkerInfoWindow] to show the info window. + /// * [isMarkerInfoWindowShown] to check if the info window is shown. + @override + Future hideMarkerInfoWindow( + MarkerId markerId, { + @required int mapId, + }) async { + _map(mapId).hideInfoWindow(markerId); + } + + /// Returns true if the [InfoWindow] of the [Marker] identified by `markerId` is shown. + /// + /// See also: + /// * [showMarkerInfoWindow] to show the info window. + /// * [hideMarkerInfoWindow] to hide the info window. + @override + Future isMarkerInfoWindowShown( + MarkerId markerId, { + @required int mapId, + }) async { + return _map(mapId).isInfoWindowShown(markerId); + } + + /// Returns the zoom level of the `mapId`. + @override + Future getZoomLevel({ + @required int mapId, + }) { + return _map(mapId).getZoomLevel(); + } + + // The following are the 11 possible streams of data from the native side + // into the plugin + + @override + Stream onCameraMoveStarted({@required int mapId}) { + return _events(mapId).whereType(); + } + + @override + Stream onCameraMove({@required int mapId}) { + return _events(mapId).whereType(); + } + + @override + Stream onCameraIdle({@required int mapId}) { + return _events(mapId).whereType(); + } + + @override + Stream onMarkerTap({@required int mapId}) { + return _events(mapId).whereType(); + } + + @override + Stream onInfoWindowTap({@required int mapId}) { + return _events(mapId).whereType(); + } + + @override + Stream onMarkerDragEnd({@required int mapId}) { + return _events(mapId).whereType(); + } + + @override + Stream onPolylineTap({@required int mapId}) { + return _events(mapId).whereType(); + } + + @override + Stream onPolygonTap({@required int mapId}) { + return _events(mapId).whereType(); + } + + @override + Stream onCircleTap({@required int mapId}) { + return _events(mapId).whereType(); + } + + @override + Stream onTap({@required int mapId}) { + return _events(mapId).whereType(); + } + + @override + Stream onLongPress({@required int mapId}) { + return _events(mapId).whereType(); + } + + /// Disposes of the current map. It can't be used afterwards! + @override + void dispose({@required int mapId}) { + _map(mapId)?.dispose(); + _mapById.remove(mapId); + } + + @override + Widget buildView( + Map creationParams, + Set> gestureRecognizers, + PlatformViewCreatedCallback onPlatformViewCreated) { + int mapId = creationParams.remove('_webOnlyMapCreationId'); + + assert(mapId != null, + 'buildView needs a `_webOnlyMapCreationId` in its creationParams to prevent widget reloads in web.'); + + // Bail fast if we've already rendered this mapId... + if (_mapById[mapId]?.widget != null) { + return _mapById[mapId].widget; + } + + final StreamController controller = + StreamController.broadcast(); + + final mapController = GoogleMapController( + mapId: mapId, + streamController: controller, + rawOptions: creationParams, + ); + + _mapById[mapId] = mapController; + + onPlatformViewCreated.call(mapId); + + return mapController.widget; + } +} diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/marker.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/marker.dart new file mode 100644 index 000000000000..a067e352732f --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/marker.dart @@ -0,0 +1,82 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +part of google_maps_flutter_web; + +/// The `MarkerController` class wraps a [gmaps.Marker], how it handles events, and its associated (optional) [gmaps.InfoWindow] widget. +class MarkerController { + gmaps.Marker _marker; + + final bool _consumeTapEvents; + + final gmaps.InfoWindow _infoWindow; + + bool _infoWindowShown = false; + + /// Creates a `MarkerController`, which wraps a [gmaps.Marker] object, its `onTap`/`onDrag` behavior, and its associated [gmaps.InfoWindow]. + MarkerController({ + @required gmaps.Marker marker, + gmaps.InfoWindow infoWindow, + bool consumeTapEvents = false, + LatLngCallback onDragEnd, + ui.VoidCallback onTap, + }) : _marker = marker, + _infoWindow = infoWindow, + _consumeTapEvents = consumeTapEvents { + if (onTap != null) { + _marker.onClick.listen((event) { + onTap.call(); + }); + } + if (onDragEnd != null) { + _marker.onDragend.listen((event) { + _marker.position = event.latLng; + onDragEnd.call(event.latLng); + }); + } + } + + /// Returns `true` if this Controller will use its own `onTap` handler to consume events. + bool get consumeTapEvents => _consumeTapEvents; + + /// Returns `true` if the [gmaps.InfoWindow] associated to this marker is being shown. + bool get infoWindowShown => _infoWindowShown; + + /// Returns the [gmaps.Marker] associated to this controller. + gmaps.Marker get marker => _marker; + + /// Updates the options of the wrapped [gmaps.Marker] object. + void update( + gmaps.MarkerOptions options, { + String newInfoWindowContent, + }) { + _marker.options = options; + if (_infoWindow != null && newInfoWindowContent != null) { + _infoWindow.content = newInfoWindowContent; + } + } + + /// Disposes of the currently wrapped [gmaps.Marker]. + void remove() { + _marker.visible = false; + _marker.map = null; + _marker = null; + } + + /// Hide the associated [gmaps.InfoWindow]. + void hideInfoWindow() { + if (_infoWindow != null) { + _infoWindow.close(); + _infoWindowShown = false; + } + } + + /// Show the associated [gmaps.InfoWindow]. + void showInfoWindow() { + if (_infoWindow != null) { + _infoWindow.open(_marker.map, _marker); + _infoWindowShown = true; + } + } +} diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/markers.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/markers.dart new file mode 100644 index 000000000000..ebb478d20b06 --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/markers.dart @@ -0,0 +1,144 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +part of google_maps_flutter_web; + +/// This class manages a set of [MarkerController]s associated to a [GoogleMapController]. +class MarkersController extends GeometryController { + // A cache of [MarkerController]s indexed by their [MarkerId]. + final Map _markerIdToController; + + // The stream over which markers broadcast their events + StreamController _streamController; + + /// Initialize the cache. The [StreamController] comes from the [GoogleMapController], and is shared with other controllers. + MarkersController({ + @required StreamController stream, + }) : _streamController = stream, + _markerIdToController = Map(); + + /// Returns the cache of [MarkerController]s. Test only. + @visibleForTesting + Map get markers => _markerIdToController; + + /// Adds a set of [Marker] objects to the cache. + /// + /// Wraps each [Marker] into its corresponding [MarkerController]. + void addMarkers(Set markersToAdd) { + markersToAdd?.forEach(_addMarker); + } + + void _addMarker(Marker marker) { + if (marker == null) { + return; + } + + final infoWindowOptions = _infoWindowOptionsFromMarker(marker); + gmaps.InfoWindow gmInfoWindow; + + if (infoWindowOptions != null) { + gmInfoWindow = gmaps.InfoWindow(infoWindowOptions) + ..addListener('click', () { + _onInfoWindowTap(marker.markerId); + }); + } + + final currentMarker = _markerIdToController[marker.markerId]?.marker; + + final populationOptions = _markerOptionsFromMarker(marker, currentMarker); + gmaps.Marker gmMarker = gmaps.Marker(populationOptions); + gmMarker.map = googleMap; + MarkerController controller = MarkerController( + marker: gmMarker, + infoWindow: gmInfoWindow, + consumeTapEvents: marker.consumeTapEvents, + onTap: () { + this.showMarkerInfoWindow(marker.markerId); + _onMarkerTap(marker.markerId); + }, + onDragEnd: (gmaps.LatLng latLng) { + _onMarkerDragEnd(marker.markerId, latLng); + }, + ); + _markerIdToController[marker.markerId] = controller; + } + + /// Updates a set of [Marker] objects with new options. + void changeMarkers(Set markersToChange) { + markersToChange?.forEach(_changeMarker); + } + + void _changeMarker(Marker marker) { + MarkerController markerController = _markerIdToController[marker?.markerId]; + if (markerController != null) { + final markerOptions = _markerOptionsFromMarker( + marker, + markerController.marker, + ); + final infoWindow = _infoWindowOptionsFromMarker(marker); + markerController.update( + markerOptions, + newInfoWindowContent: infoWindow?.content, + ); + } + } + + /// Removes a set of [MarkerId]s from the cache. + void removeMarkers(Set markerIdsToRemove) { + markerIdsToRemove?.forEach(_removeMarker); + } + + void _removeMarker(MarkerId markerId) { + final MarkerController markerController = _markerIdToController[markerId]; + markerController?.remove(); + _markerIdToController.remove(markerId); + } + + // InfoWindow... + + /// Shows the [InfoWindow] of a [MarkerId]. + /// + /// See also [hideMarkerInfoWindow] and [isInfoWindowShown]. + void showMarkerInfoWindow(MarkerId markerId) { + MarkerController markerController = _markerIdToController[markerId]; + markerController?.showInfoWindow(); + } + + /// Hides the [InfoWindow] of a [MarkerId]. + /// + /// See also [showMarkerInfoWindow] and [isInfoWindowShown]. + void hideMarkerInfoWindow(MarkerId markerId) { + MarkerController markerController = _markerIdToController[markerId]; + markerController?.hideInfoWindow(); + } + + /// Returns whether or not the [InfoWindow] of a [MarkerId] is shown. + /// + /// See also [showMarkerInfoWindow] and [hideMarkerInfoWindow]. + bool isInfoWindowShown(MarkerId markerId) { + MarkerController markerController = _markerIdToController[markerId]; + return markerController?.infoWindowShown ?? false; + } + + // Handle internal events + + bool _onMarkerTap(MarkerId markerId) { + // Have you ended here on your debugging? Is this wrong? + // Comment here: https://github.com/flutter/flutter/issues/64084 + _streamController.add(MarkerTapEvent(mapId, markerId)); + return _markerIdToController[markerId]?.consumeTapEvents ?? false; + } + + void _onInfoWindowTap(MarkerId markerId) { + _streamController.add(InfoWindowTapEvent(mapId, markerId)); + } + + void _onMarkerDragEnd(MarkerId markerId, gmaps.LatLng latLng) { + _streamController.add(MarkerDragEndEvent( + mapId, + _gmLatLngToLatLng(latLng), + markerId, + )); + } +} diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/polygon.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/polygon.dart new file mode 100644 index 000000000000..f4c692d2ee83 --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/polygon.dart @@ -0,0 +1,45 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +part of google_maps_flutter_web; + +/// The `PolygonController` class wraps a [gmaps.Polygon] and its `onTap` behavior. +class PolygonController { + gmaps.Polygon _polygon; + + final bool _consumeTapEvents; + + /// Creates a `PolygonController` that wraps a [gmaps.Polygon] object and its `onTap` behavior. + PolygonController({ + @required gmaps.Polygon polygon, + bool consumeTapEvents = false, + ui.VoidCallback onTap, + }) : _polygon = polygon, + _consumeTapEvents = consumeTapEvents { + if (onTap != null) { + polygon.onClick.listen((event) { + onTap.call(); + }); + } + } + + /// Returns the wrapped [gmaps.Polygon]. Only used for testing. + @visibleForTesting + gmaps.Polygon get polygon => _polygon; + + /// Returns `true` if this Controller will use its own `onTap` handler to consume events. + bool get consumeTapEvents => _consumeTapEvents; + + /// Updates the options of the wrapped [gmaps.Polygon] object. + void update(gmaps.PolygonOptions options) { + _polygon.options = options; + } + + /// Disposes of the currently wrapped [gmaps.Polygon]. + void remove() { + _polygon.visible = false; + _polygon.map = null; + _polygon = null; + } +} diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/polygons.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/polygons.dart new file mode 100644 index 000000000000..5c078ea0aa7a --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/polygons.dart @@ -0,0 +1,85 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +part of google_maps_flutter_web; + +/// This class manages a set of [PolygonController]s associated to a [GoogleMapController]. +class PolygonsController extends GeometryController { + // A cache of [PolygonController]s indexed by their [PolygonId]. + final Map _polygonIdToController; + + // The stream over which polygons broadcast events + StreamController _streamController; + + /// Initializes the cache. The [StreamController] comes from the [GoogleMapController], and is shared with other controllers. + PolygonsController({ + @required StreamController stream, + }) : _streamController = stream, + _polygonIdToController = Map(); + + /// Returns the cache of [PolygonController]s. Test only. + @visibleForTesting + Map get polygons => _polygonIdToController; + + /// Adds a set of [Polygon] objects to the cache. + /// + /// Wraps each Polygon into its corresponding [PolygonController]. + void addPolygons(Set polygonsToAdd) { + if (polygonsToAdd != null) { + polygonsToAdd.forEach((polygon) { + _addPolygon(polygon); + }); + } + } + + void _addPolygon(Polygon polygon) { + if (polygon == null) { + return; + } + + final populationOptions = _polygonOptionsFromPolygon(googleMap, polygon); + gmaps.Polygon gmPolygon = gmaps.Polygon(populationOptions); + gmPolygon.map = googleMap; + PolygonController controller = PolygonController( + polygon: gmPolygon, + consumeTapEvents: polygon.consumeTapEvents, + onTap: () { + _onPolygonTap(polygon.polygonId); + }); + _polygonIdToController[polygon.polygonId] = controller; + } + + /// Updates a set of [Polygon] objects with new options. + void changePolygons(Set polygonsToChange) { + if (polygonsToChange != null) { + polygonsToChange.forEach((polygonToChange) { + _changePolygon(polygonToChange); + }); + } + } + + void _changePolygon(Polygon polygon) { + PolygonController polygonController = + _polygonIdToController[polygon?.polygonId]; + polygonController?.update(_polygonOptionsFromPolygon(googleMap, polygon)); + } + + /// Removes a set of [PolygonId]s from the cache. + void removePolygons(Set polygonIdsToRemove) { + polygonIdsToRemove?.forEach((polygonId) { + final PolygonController polygonController = + _polygonIdToController[polygonId]; + polygonController?.remove(); + _polygonIdToController.remove(polygonId); + }); + } + + // Handle internal events + bool _onPolygonTap(PolygonId polygonId) { + // Have you ended here on your debugging? Is this wrong? + // Comment here: https://github.com/flutter/flutter/issues/64084 + _streamController.add(PolygonTapEvent(mapId, polygonId)); + return _polygonIdToController[polygonId]?.consumeTapEvents ?? false; + } +} diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/polyline.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/polyline.dart new file mode 100644 index 000000000000..f8ff2c62191d --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/polyline.dart @@ -0,0 +1,45 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +part of google_maps_flutter_web; + +/// The `PolygonController` class wraps a [gmaps.Polyline] and its `onTap` behavior. +class PolylineController { + gmaps.Polyline _polyline; + + final bool _consumeTapEvents; + + /// Creates a `PolylineController` that wraps a [gmaps.Polyline] object and its `onTap` behavior. + PolylineController({ + @required gmaps.Polyline polyline, + bool consumeTapEvents = false, + ui.VoidCallback onTap, + }) : _polyline = polyline, + _consumeTapEvents = consumeTapEvents { + if (onTap != null) { + polyline.onClick.listen((event) { + onTap.call(); + }); + } + } + + /// Returns the wrapped [gmaps.Polyline]. Only used for testing. + @visibleForTesting + gmaps.Polyline get line => _polyline; + + /// Returns `true` if this Controller will use its own `onTap` handler to consume events. + bool get consumeTapEvents => _consumeTapEvents; + + /// Updates the options of the wrapped [gmaps.Polyline] object. + void update(gmaps.PolylineOptions options) { + _polyline.options = options; + } + + /// Disposes of the currently wrapped [gmaps.Polyline]. + void remove() { + _polyline.visible = false; + _polyline.map = null; + _polyline = null; + } +} diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/polylines.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/polylines.dart new file mode 100644 index 000000000000..f24ca4b1bb42 --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/polylines.dart @@ -0,0 +1,83 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +part of google_maps_flutter_web; + +/// This class manages a set of [PolylinesController]s associated to a [GoogleMapController]. +class PolylinesController extends GeometryController { + // A cache of [PolylineController]s indexed by their [PolylineId]. + final Map _polylineIdToController; + + // The stream over which polylines broadcast their events + StreamController _streamController; + + /// Initializes the cache. The [StreamController] comes from the [GoogleMapController], and is shared with other controllers. + PolylinesController({ + @required StreamController stream, + }) : _streamController = stream, + _polylineIdToController = Map(); + + /// Returns the cache of [PolylineContrller]s. Test only. + @visibleForTesting + Map get lines => _polylineIdToController; + + /// Adds a set of [Polyline] objects to the cache. + /// + /// Wraps each line into its corresponding [PolylineController]. + void addPolylines(Set polylinesToAdd) { + polylinesToAdd?.forEach((polyline) { + _addPolyline(polyline); + }); + } + + void _addPolyline(Polyline polyline) { + if (polyline == null) { + return; + } + + final polylineOptions = _polylineOptionsFromPolyline(googleMap, polyline); + gmaps.Polyline gmPolyline = gmaps.Polyline(polylineOptions); + gmPolyline.map = googleMap; + PolylineController controller = PolylineController( + polyline: gmPolyline, + consumeTapEvents: polyline.consumeTapEvents, + onTap: () { + _onPolylineTap(polyline.polylineId); + }); + _polylineIdToController[polyline.polylineId] = controller; + } + + /// Updates a set of [Polyline] objects with new options. + void changePolylines(Set polylinesToChange) { + polylinesToChange?.forEach((polylineToChange) { + _changePolyline(polylineToChange); + }); + } + + void _changePolyline(Polyline polyline) { + PolylineController polylineController = + _polylineIdToController[polyline?.polylineId]; + polylineController + ?.update(_polylineOptionsFromPolyline(googleMap, polyline)); + } + + /// Removes a set of [PolylineId]s from the cache. + void removePolylines(Set polylineIdsToRemove) { + polylineIdsToRemove?.forEach((polylineId) { + final PolylineController polylineController = + _polylineIdToController[polylineId]; + polylineController?.remove(); + _polylineIdToController.remove(polylineId); + }); + } + + // Handle internal events + + bool _onPolylineTap(PolylineId polylineId) { + // Have you ended here on your debugging? Is this wrong? + // Comment here: https://github.com/flutter/flutter/issues/64084 + _streamController.add(PolylineTapEvent(mapId, polylineId)); + return _polylineIdToController[polylineId]?.consumeTapEvents ?? false; + } +} diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/types.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/types.dart new file mode 100644 index 000000000000..039cc473db5e --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/types.dart @@ -0,0 +1,30 @@ +// Copyright 2017 The Chromium 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:google_maps_flutter_web/google_maps_flutter_web.dart'; +import 'package:google_maps/google_maps.dart' as gmaps; + +/// A void function that handles a [gmaps.LatLng] as a parameter. +/// +/// Similar to [ui.VoidCallback], but specific for Marker drag events. +typedef LatLngCallback = void Function(gmaps.LatLng latLng); + +/// The base class for all "geometry" group controllers. +/// +/// This lets all Geometry controllers ([MarkersController], [CirclesController], +/// [PolygonsController], [PolylinesController]) to be bound to a [gmaps.GMap] +/// instance and our internal `mapId` value. +abstract class GeometryController { + /// The GMap instance that this controller operates on. + gmaps.GMap googleMap; + + /// The map ID for events. + int mapId; + + /// Binds a `mapId` and the [gmaps.GMap] instance to this controller. + void bindToMap(int mapId, gmaps.GMap googleMap) { + this.mapId = mapId; + this.googleMap = googleMap; + } +} diff --git a/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml new file mode 100644 index 000000000000..e916f7aa6590 --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml @@ -0,0 +1,35 @@ +name: google_maps_flutter_web +description: Web platform implementation of google_maps_flutter +homepage: https://github.com/flutter/plugins/tree/master/packages/google_maps_flutter +version: 0.1.0+1 + +flutter: + plugin: + platforms: + web: + pluginClass: GoogleMapsPlugin + fileName: google_maps_flutter_web.dart + +dependencies: + flutter: + sdk: flutter + flutter_web_plugins: + sdk: flutter + meta: ^1.1.7 + google_maps_flutter_platform_interface: ^1.0.4 + google_maps: ^3.0.0 + stream_transform: ^1.2.0 + sanitize_html: ^1.3.0 + +dev_dependencies: + flutter_test: + sdk: flutter + url_launcher: ^5.2.5 + pedantic: ^1.8.0 + mockito: ^4.1.1 + integration_test: + path: ../../integration_test + +environment: + sdk: ">=2.3.0 <3.0.0" + flutter: ">=1.10.0 <2.0.0" diff --git a/packages/google_maps_flutter/google_maps_flutter_web/test/README.md b/packages/google_maps_flutter/google_maps_flutter_web/test/README.md new file mode 100644 index 000000000000..7c48d024ba57 --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_web/test/README.md @@ -0,0 +1,17 @@ +# Running browser_tests + +Make sure you have updated to the latest Flutter master. + +1. Check what version of Chrome is running on the machine you're running tests on. + +2. Download and install driver for that version from here: + * + +3. Start the driver using `chromedriver --port=4444` + +4. Change into the `test` directory of your clone. + +5. Run tests: `flutter drive -d web-server --browser-name=chrome --target=test_driver/TEST_NAME_integration.dart`, or (in Linux): + + * Single: `./run_test test_driver/TEST_NAME_integration.dart` + * All: `./run_test` diff --git a/packages/google_maps_flutter/google_maps_flutter_web/test/lib/main.dart b/packages/google_maps_flutter/google_maps_flutter_web/test/lib/main.dart new file mode 100644 index 000000000000..10415204570c --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_web/test/lib/main.dart @@ -0,0 +1,22 @@ +// Copyright 2013 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/material.dart'; + +void main() { + runApp(MyApp()); +} + +/// App for testing +class MyApp extends StatefulWidget { + @override + _MyAppState createState() => _MyAppState(); +} + +class _MyAppState extends State { + @override + Widget build(BuildContext context) { + return Text('Testing... Look at the console output for results!'); + } +} diff --git a/packages/google_maps_flutter/google_maps_flutter_web/test/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter_web/test/pubspec.yaml new file mode 100644 index 000000000000..008cc0350430 --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_web/test/pubspec.yaml @@ -0,0 +1,23 @@ +name: regular_integration_tests +publish_to: none + +environment: + sdk: ">=2.2.2 <3.0.0" + +dependencies: + flutter: + sdk: flutter + +dev_dependencies: + google_maps: ^3.4.4 + flutter_driver: + sdk: flutter + flutter_test: + sdk: flutter + http: ^0.12.2 + mockito: ^4.1.1 + google_maps_flutter_web: + path: ../ + integration_test: + path: ../../../integration_test + diff --git a/packages/google_maps_flutter/google_maps_flutter_web/test/run_test b/packages/google_maps_flutter/google_maps_flutter_web/test/run_test new file mode 100755 index 000000000000..74a8526a0fa3 --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_web/test/run_test @@ -0,0 +1,17 @@ +#!/usr/bin/bash +if pgrep -lf chromedriver > /dev/null; then + echo "chromedriver is running." + + if [ $# -eq 0 ]; then + echo "No target specified, running all tests..." + find test_driver/ -iname *_integration.dart | xargs -n1 -i -t flutter drive -d web-server --web-port=7357 --browser-name=chrome --target='{}' + else + echo "Running test target: $1..." + set -x + flutter drive -d web-server --web-port=7357 --browser-name=chrome --target=$1 + fi + + else + echo "chromedriver is not running." +fi + diff --git a/packages/google_maps_flutter/google_maps_flutter_web/test/test_driver/google_maps_controller_integration.dart b/packages/google_maps_flutter/google_maps_flutter_web/test/test_driver/google_maps_controller_integration.dart new file mode 100644 index 000000000000..fc21476e9703 --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_web/test/test_driver/google_maps_controller_integration.dart @@ -0,0 +1,513 @@ +// Copyright 2017 The Chromium 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:integration_test/integration_test.dart'; +import 'package:google_maps/google_maps.dart' as gmaps; +import 'package:google_maps_flutter_web/google_maps_flutter_web.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:mockito/mockito.dart'; + +import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart'; + +class _MockCirclesController extends Mock implements CirclesController {} + +class _MockPolygonsController extends Mock implements PolygonsController {} + +class _MockPolylinesController extends Mock implements PolylinesController {} + +class _MockMarkersController extends Mock implements MarkersController {} + +class _MockGMap extends Mock implements gmaps.GMap { + final onClickController = StreamController.broadcast(); + @override + Stream get onClick => onClickController.stream; + + final onRightclickController = StreamController.broadcast(); + @override + Stream get onRightclick => onRightclickController.stream; + + final onBoundsChangedController = StreamController.broadcast(); + @override + Stream get onBoundsChanged => onBoundsChangedController.stream; + + final onIdleController = StreamController.broadcast(); + @override + Stream get onIdle => onIdleController.stream; +} + +/// Test Google Map Controller +void main() { + IntegrationTestWidgetsFlutterBinding.ensureInitialized(); + + group('GoogleMapController', () { + final int mapId = 33930; + GoogleMapController controller; + StreamController stream; + + // Creates a controller with the default mapId and stream controller, and any `options` needed. + GoogleMapController _createController({Map options}) { + return GoogleMapController( + mapId: mapId, + streamController: stream, + rawOptions: options ?? {}); + } + + setUp(() { + stream = StreamController.broadcast(); + }); + + group('construct/dispose', () { + setUp(() { + controller = _createController(); + }); + + testWidgets('constructor creates widget', (WidgetTester tester) async { + expect(controller.widget, isNotNull); + expect(controller.widget.viewType, endsWith('$mapId')); + }); + + testWidgets('widget is cached when reused', (WidgetTester tester) async { + final first = controller.widget; + final again = controller.widget; + expect(identical(first, again), isTrue); + }); + + testWidgets('dispose closes the stream and removes the widget', + (WidgetTester tester) async { + controller.dispose(); + expect(stream.isClosed, isTrue); + expect(controller.widget, isNull); + }); + }); + + group('init', () { + _MockCirclesController circles; + _MockMarkersController markers; + _MockPolygonsController polygons; + _MockPolylinesController polylines; + _MockGMap map; + + setUp(() { + circles = _MockCirclesController(); + markers = _MockMarkersController(); + polygons = _MockPolygonsController(); + polylines = _MockPolylinesController(); + map = _MockGMap(); + }); + + testWidgets('listens to map events', (WidgetTester tester) async { + controller = _createController(); + controller.debugSetOverrides( + createMap: (_, __) => map, + circles: circles, + markers: markers, + polygons: polygons, + polylines: polylines, + ); + + expect(map.onClickController.hasListener, isFalse); + expect(map.onRightclickController.hasListener, isFalse); + expect(map.onBoundsChangedController.hasListener, isFalse); + expect(map.onIdleController.hasListener, isFalse); + + controller.init(); + + expect(map.onClickController.hasListener, isTrue); + expect(map.onRightclickController.hasListener, isTrue); + expect(map.onBoundsChangedController.hasListener, isTrue); + expect(map.onIdleController.hasListener, isTrue); + }); + + testWidgets('binds geometry controllers to map\'s', + (WidgetTester tester) async { + controller = _createController(); + controller.debugSetOverrides( + createMap: (_, __) => map, + circles: circles, + markers: markers, + polygons: polygons, + polylines: polylines, + ); + + controller.init(); + + verify(circles.bindToMap(mapId, map)); + verify(markers.bindToMap(mapId, map)); + verify(polygons.bindToMap(mapId, map)); + verify(polylines.bindToMap(mapId, map)); + }); + + testWidgets('renders initial geometry', (WidgetTester tester) async { + controller = _createController(options: { + 'circlesToAdd': [ + {'circleId': 'circle-1'} + ], + 'markersToAdd': [ + {'markerId': 'marker-1'} + ], + 'polygonsToAdd': [ + {'polygonId': 'polygon-1'} + ], + 'polylinesToAdd': [ + {'polylineId': 'polyline-1'} + ], + }); + controller.debugSetOverrides( + circles: circles, + markers: markers, + polygons: polygons, + polylines: polylines, + ); + + controller.init(); + + final capturedCircles = + verify(circles.addCircles(captureAny)).captured[0] as Set; + final capturedMarkers = + verify(markers.addMarkers(captureAny)).captured[0] as Set; + final capturedPolygons = verify(polygons.addPolygons(captureAny)) + .captured[0] as Set; + final capturedPolylines = verify(polylines.addPolylines(captureAny)) + .captured[0] as Set; + + expect(capturedCircles.first.circleId.value, 'circle-1'); + expect(capturedMarkers.first.markerId.value, 'marker-1'); + expect(capturedPolygons.first.polygonId.value, 'polygon-1'); + expect(capturedPolylines.first.polylineId.value, 'polyline-1'); + }); + + group('Initialization options', () { + gmaps.MapOptions capturedOptions; + setUp(() { + capturedOptions = null; + }); + testWidgets('translates initial options', (WidgetTester tester) async { + controller = _createController(options: { + 'options': { + 'mapType': 2, + 'zoomControlsEnabled': true, + } + }); + controller.debugSetOverrides(createMap: (_, options) { + capturedOptions = options; + return map; + }); + + controller.init(); + + expect(capturedOptions, isNotNull); + expect(capturedOptions.mapTypeId, gmaps.MapTypeId.SATELLITE); + expect(capturedOptions.zoomControl, true); + expect(capturedOptions.gestureHandling, 'auto', + reason: + 'by default the map handles zoom/pan gestures internally'); + }); + + testWidgets('disables gestureHandling with scrollGesturesEnabled false', + (WidgetTester tester) async { + controller = _createController(options: { + 'options': { + 'scrollGesturesEnabled': false, + } + }); + controller.debugSetOverrides(createMap: (_, options) { + capturedOptions = options; + return map; + }); + + controller.init(); + + expect(capturedOptions, isNotNull); + expect(capturedOptions.gestureHandling, 'none', + reason: + 'disabling scroll gestures disables all gesture handling'); + }); + + testWidgets('disables gestureHandling with zoomGesturesEnabled false', + (WidgetTester tester) async { + controller = _createController(options: { + 'options': { + 'zoomGesturesEnabled': false, + } + }); + controller.debugSetOverrides(createMap: (_, options) { + capturedOptions = options; + return map; + }); + + controller.init(); + + expect(capturedOptions, isNotNull); + expect(capturedOptions.gestureHandling, 'none', + reason: + 'disabling scroll gestures disables all gesture handling'); + }); + + testWidgets('does not set initial position if absent', + (WidgetTester tester) async { + controller = _createController(); + controller.debugSetOverrides(createMap: (_, options) { + capturedOptions = options; + return map; + }); + + controller.init(); + + expect(capturedOptions, isNotNull); + expect(capturedOptions.zoom, isNull); + expect(capturedOptions.center, isNull); + }); + + testWidgets('sets initial position when passed', + (WidgetTester tester) async { + controller = _createController(options: { + 'initialCameraPosition': { + 'target': [43.308, -5.6910], + 'zoom': 12, + 'bearing': 0, + 'tilt': 0, + } + }); + controller.debugSetOverrides(createMap: (_, options) { + capturedOptions = options; + return map; + }); + + controller.init(); + + expect(capturedOptions, isNotNull); + expect(capturedOptions.zoom, 12); + expect(capturedOptions.center, isNotNull); + }); + }); + + group('Traffic Layer', () { + testWidgets('by default is disabled', (WidgetTester tester) async { + controller = _createController(); + controller.init(); + expect(controller.trafficLayer, isNull); + }); + + testWidgets('initializes with traffic layer', + (WidgetTester tester) async { + controller = _createController(options: { + 'options': { + 'trafficEnabled': true, + } + }); + controller.debugSetOverrides(createMap: (_, __) => map); + controller.init(); + expect(controller.trafficLayer, isNotNull); + }); + }); + }); + + // These are the methods that are delegated to the gmaps.GMap object, that we can mock... + group('Map control methods', () { + _MockGMap map; + + setUp(() { + map = _MockGMap(); + controller = _createController(); + controller.debugSetOverrides(createMap: (_, __) => map); + controller.init(); + }); + + group('updateRawOptions', () { + testWidgets('can update `options`', (WidgetTester tester) async { + controller.updateRawOptions({ + 'mapType': 2, + }); + final options = verify(map.options = captureAny).captured[0]; + + expect(options.mapTypeId, gmaps.MapTypeId.SATELLITE); + }); + + testWidgets('can turn on/off traffic', (WidgetTester tester) async { + expect(controller.trafficLayer, isNull); + + controller.updateRawOptions({ + 'trafficEnabled': true, + }); + + expect(controller.trafficLayer, isNotNull); + + controller.updateRawOptions({ + 'trafficEnabled': false, + }); + + expect(controller.trafficLayer, isNull); + }); + }); + + group('viewport getters', () { + testWidgets('getVisibleRegion', (WidgetTester tester) async { + await controller.getVisibleRegion(); + + verify(map.bounds); + }); + + testWidgets('getZoomLevel', (WidgetTester tester) async { + when(map.zoom).thenReturn(10); + + await controller.getZoomLevel(); + + verify(map.zoom); + }); + }); + + group('moveCamera', () { + testWidgets('newLatLngZoom', (WidgetTester tester) async { + await (controller + .moveCamera(CameraUpdate.newLatLngZoom(LatLng(19, 26), 12))); + + verify(map.zoom = 12); + final captured = verify(map.panTo(captureAny)).captured[0]; + expect(captured.lat, 19); + expect(captured.lng, 26); + }); + }); + + group('map.projection methods', () { + // These are too much for dart mockito, can't mock: + // map.projection.method() (in Javascript ;) ) + }); + }); + + // These are the methods that get forwarded to other controllers, so we just verify calls. + group('Pass-through methods', () { + setUp(() { + controller = _createController(); + }); + + testWidgets('updateCircles', (WidgetTester tester) async { + final mock = _MockCirclesController(); + controller.debugSetOverrides(circles: mock); + + final previous = { + Circle(circleId: CircleId('to-be-updated')), + Circle(circleId: CircleId('to-be-removed')), + }; + + final current = { + Circle(circleId: CircleId('to-be-updated'), visible: false), + Circle(circleId: CircleId('to-be-added')), + }; + + controller.updateCircles(CircleUpdates.from(previous, current)); + + verify(mock.removeCircles({ + CircleId('to-be-removed'), + })); + verify(mock.addCircles({ + Circle(circleId: CircleId('to-be-added')), + })); + verify(mock.changeCircles({ + Circle(circleId: CircleId('to-be-updated'), visible: false), + })); + }); + + testWidgets('updateMarkers', (WidgetTester tester) async { + final mock = _MockMarkersController(); + controller.debugSetOverrides(markers: mock); + + final previous = { + Marker(markerId: MarkerId('to-be-updated')), + Marker(markerId: MarkerId('to-be-removed')), + }; + + final current = { + Marker(markerId: MarkerId('to-be-updated'), visible: false), + Marker(markerId: MarkerId('to-be-added')), + }; + + controller.updateMarkers(MarkerUpdates.from(previous, current)); + + verify(mock.removeMarkers({ + MarkerId('to-be-removed'), + })); + verify(mock.addMarkers({ + Marker(markerId: MarkerId('to-be-added')), + })); + verify(mock.changeMarkers({ + Marker(markerId: MarkerId('to-be-updated'), visible: false), + })); + }); + + testWidgets('updatePolygons', (WidgetTester tester) async { + final mock = _MockPolygonsController(); + controller.debugSetOverrides(polygons: mock); + + final previous = { + Polygon(polygonId: PolygonId('to-be-updated')), + Polygon(polygonId: PolygonId('to-be-removed')), + }; + + final current = { + Polygon(polygonId: PolygonId('to-be-updated'), visible: false), + Polygon(polygonId: PolygonId('to-be-added')), + }; + + controller.updatePolygons(PolygonUpdates.from(previous, current)); + + verify(mock.removePolygons({ + PolygonId('to-be-removed'), + })); + verify(mock.addPolygons({ + Polygon(polygonId: PolygonId('to-be-added')), + })); + verify(mock.changePolygons({ + Polygon(polygonId: PolygonId('to-be-updated'), visible: false), + })); + }); + + testWidgets('updatePolylines', (WidgetTester tester) async { + final mock = _MockPolylinesController(); + controller.debugSetOverrides(polylines: mock); + + final previous = { + Polyline(polylineId: PolylineId('to-be-updated')), + Polyline(polylineId: PolylineId('to-be-removed')), + }; + + final current = { + Polyline(polylineId: PolylineId('to-be-updated'), visible: false), + Polyline(polylineId: PolylineId('to-be-added')), + }; + + controller.updatePolylines(PolylineUpdates.from(previous, current)); + + verify(mock.removePolylines({ + PolylineId('to-be-removed'), + })); + verify(mock.addPolylines({ + Polyline(polylineId: PolylineId('to-be-added')), + })); + verify(mock.changePolylines({ + Polyline(polylineId: PolylineId('to-be-updated'), visible: false), + })); + }); + + testWidgets('infoWindow visibility', (WidgetTester tester) async { + final mock = _MockMarkersController(); + controller.debugSetOverrides(markers: mock); + final markerId = MarkerId('marker-with-infowindow'); + + controller.showInfoWindow(markerId); + + verify(mock.showMarkerInfoWindow(markerId)); + + controller.hideInfoWindow(markerId); + + verify(mock.hideMarkerInfoWindow(markerId)); + + controller.isInfoWindowShown(markerId); + + verify(mock.isInfoWindowShown(markerId)); + }); + }); + }); +} diff --git a/packages/google_maps_flutter/google_maps_flutter_web/test/test_driver/google_maps_controller_integration_test.dart b/packages/google_maps_flutter/google_maps_flutter_web/test/test_driver/google_maps_controller_integration_test.dart new file mode 100644 index 000000000000..39444c0daa24 --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_web/test/test_driver/google_maps_controller_integration_test.dart @@ -0,0 +1,7 @@ +// Copyright 2017 The Chromium 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:integration_test/integration_test_driver.dart'; + +Future main() async => integrationDriver(); diff --git a/packages/google_maps_flutter/google_maps_flutter_web/test/test_driver/google_maps_plugin_integration.dart b/packages/google_maps_flutter/google_maps_flutter_web/test/test_driver/google_maps_plugin_integration.dart new file mode 100644 index 000000000000..59b5de42400f --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_web/test/test_driver/google_maps_plugin_integration.dart @@ -0,0 +1,392 @@ +// Copyright 2017 The Chromium 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:integration_test/integration_test.dart'; +import 'package:flutter/widgets.dart'; +import 'package:google_maps/google_maps.dart' as gmaps; +import 'package:google_maps_flutter_web/google_maps_flutter_web.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:mockito/mockito.dart'; + +import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart'; + +class _MockGoogleMapController extends Mock implements GoogleMapController {} + +/// Test GoogleMapsPlugin +void main() { + IntegrationTestWidgetsFlutterBinding.ensureInitialized(); + + group('GoogleMapsPlugin', () { + _MockGoogleMapController controller; + GoogleMapsPlugin plugin; + int reportedMapId; + + void onPlatformViewCreated(int id) { + reportedMapId = id; + } + + setUp(() { + controller = _MockGoogleMapController(); + plugin = GoogleMapsPlugin(); + reportedMapId = null; + }); + + group('init/dispose', () { + group('before buildWidget', () { + testWidgets('init throws assertion', (WidgetTester tester) async { + expect(() => plugin.init(0), throwsAssertionError); + }); + }); + + group('after buildWidget', () { + setUp(() { + plugin.debugSetMapById({0: controller}); + }); + + testWidgets('init initializes controller', (WidgetTester tester) async { + await plugin.init(0); + + verify(controller.init()); + }); + + testWidgets('cannot call methods after dispose', + (WidgetTester tester) async { + plugin.dispose(mapId: 0); + + verify(controller.dispose()); + expect( + () => plugin.init(0), + throwsAssertionError, + reason: 'Method calls should fail after dispose.', + ); + }); + }); + }); + + group('buildView', () { + final testMapId = 33930; + + testWidgets('throws without _webOnlyMapCreationId', + (WidgetTester tester) async { + expect( + () => plugin.buildView({}, null, onPlatformViewCreated), + throwsAssertionError, + reason: + '_webOnlyMapCreationId is mandatory to prevent unnecessary reloads in web.', + ); + }); + + testWidgets( + 'returns an HtmlElementView and caches the controller for later', + (WidgetTester tester) async { + final Map cache = {}; + plugin.debugSetMapById(cache); + + final HtmlElementView widget = plugin.buildView({ + '_webOnlyMapCreationId': testMapId, + }, null, onPlatformViewCreated); + + expect( + widget.viewType, + contains('$testMapId'), + reason: + 'view type should contain the mapId passed when creating the map.', + ); + expect( + reportedMapId, + testMapId, + reason: 'Should call onPlatformViewCreated with the mapId', + ); + expect(cache, contains(testMapId)); + expect( + cache[testMapId], + isNotNull, + reason: 'cached controller cannot be null.', + ); + }); + + testWidgets('returns cached instance if it already exists', + (WidgetTester tester) async { + final expected = HtmlElementView(viewType: 'only-for-testing'); + when(controller.widget).thenReturn(expected); + plugin.debugSetMapById({testMapId: controller}); + + final widget = plugin.buildView({ + '_webOnlyMapCreationId': testMapId, + }, null, onPlatformViewCreated); + + expect(widget, equals(expected)); + expect( + reportedMapId, + isNull, + reason: + 'onPlatformViewCreated should not be called when returning a cached controller', + ); + }); + }); + + group('setMapStyles', () { + String mapStyle = '''[{ + "featureType": "poi.park", + "elementType": "labels.text.fill", + "stylers": [{"color": "#6b9a76"}] + }]'''; + + testWidgets('translates styles for controller', + (WidgetTester tester) async { + plugin.debugSetMapById({0: controller}); + + await plugin.setMapStyle(mapStyle, mapId: 0); + + var captured = + verify(controller.updateRawOptions(captureThat(isMap))).captured[0]; + + expect(captured, contains('styles')); + var styles = captured['styles']; + expect(styles.length, 1); + // Let's peek inside the styles... + var style = styles[0] as gmaps.MapTypeStyle; + expect(style.featureType, gmaps.MapTypeStyleFeatureType.POI_PARK); + expect( + style.elementType, gmaps.MapTypeStyleElementType.LABELS_TEXT_FILL); + expect(style.stylers.length, 1); + expect(style.stylers[0].color, '#6b9a76'); + }); + }); + + // These methods only pass-through values from the plugin to the controller + // so we verify them all together here... + group('Pass-through methods:', () { + int mapId = 0; + setUp(() { + plugin.debugSetMapById({mapId: controller}); + }); + // Options + testWidgets('updateMapOptions', (WidgetTester tester) async { + final expectedMapOptions = {'someOption': 12345}; + + await plugin.updateMapOptions(expectedMapOptions, mapId: mapId); + + verify(controller.updateRawOptions(expectedMapOptions)); + }); + // Geometry + testWidgets('updateMarkers', (WidgetTester tester) async { + final expectedUpdates = MarkerUpdates.from(null, null); + + await plugin.updateMarkers(expectedUpdates, mapId: mapId); + + verify(controller.updateMarkers(expectedUpdates)); + }); + testWidgets('updatePolygons', (WidgetTester tester) async { + final expectedUpdates = PolygonUpdates.from(null, null); + + await plugin.updatePolygons(expectedUpdates, mapId: mapId); + + verify(controller.updatePolygons(expectedUpdates)); + }); + testWidgets('updatePolylines', (WidgetTester tester) async { + final expectedUpdates = PolylineUpdates.from(null, null); + + await plugin.updatePolylines(expectedUpdates, mapId: mapId); + + verify(controller.updatePolylines(expectedUpdates)); + }); + testWidgets('updateCircles', (WidgetTester tester) async { + final expectedUpdates = CircleUpdates.from(null, null); + + await plugin.updateCircles(expectedUpdates, mapId: mapId); + + verify(controller.updateCircles(expectedUpdates)); + }); + // Camera + testWidgets('animateCamera', (WidgetTester tester) async { + final expectedUpdates = + CameraUpdate.newLatLng(LatLng(43.3626, -5.8433)); + + await plugin.animateCamera(expectedUpdates, mapId: mapId); + + verify(controller.moveCamera(expectedUpdates)); + }); + testWidgets('moveCamera', (WidgetTester tester) async { + final expectedUpdates = + CameraUpdate.newLatLng(LatLng(43.3628, -5.8478)); + + await plugin.moveCamera(expectedUpdates, mapId: mapId); + + verify(controller.moveCamera(expectedUpdates)); + }); + // Viewport + testWidgets('getVisibleRegion', (WidgetTester tester) async { + await plugin.getVisibleRegion(mapId: mapId); + + verify(controller.getVisibleRegion()); + }); + testWidgets('getZoomLevel', (WidgetTester tester) async { + await plugin.getZoomLevel(mapId: mapId); + + verify(controller.getZoomLevel()); + }); + testWidgets('getScreenCoordinate', (WidgetTester tester) async { + final latLng = LatLng(43.3613, -5.8499); + + await plugin.getScreenCoordinate(latLng, mapId: mapId); + + verify(controller.getScreenCoordinate(latLng)); + }); + testWidgets('getLatLng', (WidgetTester tester) async { + final coordinates = ScreenCoordinate(x: 19, y: 26); + + await plugin.getLatLng(coordinates, mapId: mapId); + + verify(controller.getLatLng(coordinates)); + }); + // InfoWindows + testWidgets('showMarkerInfoWindow', (WidgetTester tester) async { + final markerId = MarkerId('testing-123'); + + await plugin.showMarkerInfoWindow(markerId, mapId: mapId); + + verify(controller.showInfoWindow(markerId)); + }); + testWidgets('hideMarkerInfoWindow', (WidgetTester tester) async { + final markerId = MarkerId('testing-123'); + + await plugin.hideMarkerInfoWindow(markerId, mapId: mapId); + + verify(controller.hideInfoWindow(markerId)); + }); + testWidgets('isMarkerInfoWindowShown', (WidgetTester tester) async { + final markerId = MarkerId('testing-123'); + + await plugin.isMarkerInfoWindowShown(markerId, mapId: mapId); + + verify(controller.isInfoWindowShown(markerId)); + }); + }); + + // Verify all event streams are filtered correctly from the main one... + group('Event Streams', () { + int mapId = 0; + StreamController streamController; + setUp(() { + streamController = StreamController.broadcast(); + when(controller.events) + .thenAnswer((realInvocation) => streamController.stream); + plugin.debugSetMapById({mapId: controller}); + }); + + // Dispatches a few events in the global streamController, and expects *only* the passed event to be there. + void _testStreamFiltering(Stream stream, MapEvent event) async { + Timer.run(() { + streamController.add(_OtherMapEvent(mapId)); + streamController.add(event); + streamController.add(_OtherMapEvent(mapId)); + streamController.close(); + }); + + final events = await stream.toList(); + + expect(events.length, 1); + expect(events[0], event); + } + + // Camera events + testWidgets('onCameraMoveStarted', (WidgetTester tester) async { + final event = CameraMoveStartedEvent(mapId); + + final stream = plugin.onCameraMoveStarted(mapId: mapId); + + await _testStreamFiltering(stream, event); + }); + testWidgets('onCameraMoveStarted', (WidgetTester tester) async { + final event = CameraMoveEvent( + mapId, + CameraPosition( + target: LatLng(43.3790, -5.8660), + ), + ); + + final stream = plugin.onCameraMove(mapId: mapId); + + await _testStreamFiltering(stream, event); + }); + testWidgets('onCameraIdle', (WidgetTester tester) async { + final event = CameraIdleEvent(mapId); + + final stream = plugin.onCameraIdle(mapId: mapId); + + await _testStreamFiltering(stream, event); + }); + // Marker events + testWidgets('onMarkerTap', (WidgetTester tester) async { + final event = MarkerTapEvent(mapId, MarkerId('test-123')); + + final stream = plugin.onMarkerTap(mapId: mapId); + + await _testStreamFiltering(stream, event); + }); + testWidgets('onInfoWindowTap', (WidgetTester tester) async { + final event = InfoWindowTapEvent(mapId, MarkerId('test-123')); + + final stream = plugin.onInfoWindowTap(mapId: mapId); + + await _testStreamFiltering(stream, event); + }); + testWidgets('onMarkerDragEnd', (WidgetTester tester) async { + final event = MarkerDragEndEvent( + mapId, + LatLng(43.3677, -5.8372), + MarkerId('test-123'), + ); + + final stream = plugin.onMarkerDragEnd(mapId: mapId); + + await _testStreamFiltering(stream, event); + }); + // Geometry + testWidgets('onPolygonTap', (WidgetTester tester) async { + final event = PolygonTapEvent(mapId, PolygonId('test-123')); + + final stream = plugin.onPolygonTap(mapId: mapId); + + await _testStreamFiltering(stream, event); + }); + testWidgets('onPolylineTap', (WidgetTester tester) async { + final event = PolylineTapEvent(mapId, PolylineId('test-123')); + + final stream = plugin.onPolylineTap(mapId: mapId); + + await _testStreamFiltering(stream, event); + }); + testWidgets('onCircleTap', (WidgetTester tester) async { + final event = CircleTapEvent(mapId, CircleId('test-123')); + + final stream = plugin.onCircleTap(mapId: mapId); + + await _testStreamFiltering(stream, event); + }); + // Map taps + testWidgets('onTap', (WidgetTester tester) async { + final event = MapTapEvent(mapId, LatLng(43.3597, -5.8458)); + + final stream = plugin.onTap(mapId: mapId); + + await _testStreamFiltering(stream, event); + }); + testWidgets('onLongPress', (WidgetTester tester) async { + final event = MapLongPressEvent(mapId, LatLng(43.3608, -5.8425)); + + final stream = plugin.onLongPress(mapId: mapId); + + await _testStreamFiltering(stream, event); + }); + }); + }); +} + +class _OtherMapEvent extends MapEvent { + _OtherMapEvent(int mapId) : super(mapId, null); +} diff --git a/packages/google_maps_flutter/google_maps_flutter_web/test/test_driver/google_maps_plugin_integration_test.dart b/packages/google_maps_flutter/google_maps_flutter_web/test/test_driver/google_maps_plugin_integration_test.dart new file mode 100644 index 000000000000..39444c0daa24 --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_web/test/test_driver/google_maps_plugin_integration_test.dart @@ -0,0 +1,7 @@ +// Copyright 2017 The Chromium 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:integration_test/integration_test_driver.dart'; + +Future main() async => integrationDriver(); diff --git a/packages/google_maps_flutter/google_maps_flutter_web/test/test_driver/marker_integration.dart b/packages/google_maps_flutter/google_maps_flutter_web/test/test_driver/marker_integration.dart new file mode 100644 index 000000000000..1cada32104af --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_web/test/test_driver/marker_integration.dart @@ -0,0 +1,99 @@ +// Copyright 2017 The Chromium 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:integration_test/integration_test.dart'; +import 'package:google_maps/google_maps.dart' as gmaps; +import 'package:google_maps_flutter_web/google_maps_flutter_web.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:mockito/mockito.dart'; + +class _MockMarker extends Mock implements gmaps.Marker { + final onClickController = StreamController(); + final onDragEndController = StreamController(); + + @override + Stream get onClick => onClickController.stream; + + @override + Stream get onDragend => onDragEndController.stream; +} + +class _MockMouseEvent extends Mock implements gmaps.MouseEvent {} + +class _MockInfoWindow extends Mock implements gmaps.InfoWindow {} + +/// Test Markers +void main() { + IntegrationTestWidgetsFlutterBinding.ensureInitialized(); + + bool called = false; + void onTap() { + called = true; + } + + void onDragEnd(gmaps.LatLng _) { + called = true; + } + + setUp(() { + called = false; + }); + + group('MarkerController', () { + _MockMarker marker; + + setUp(() { + marker = _MockMarker(); + }); + + testWidgets('onTap gets called', (WidgetTester tester) async { + MarkerController(marker: marker, onTap: onTap); + // Simulate a click + await marker.onClickController.add(null); + expect(called, isTrue); + }); + + testWidgets('onDragEnd gets called', (WidgetTester tester) async { + when(marker.draggable).thenReturn(true); + MarkerController(marker: marker, onDragEnd: onDragEnd); + // Simulate a drag end + await marker.onDragEndController.add(_MockMouseEvent()); + expect(called, isTrue); + }); + + testWidgets('update', (WidgetTester tester) async { + final controller = MarkerController(marker: marker); + final options = gmaps.MarkerOptions()..draggable = false; + controller.update(options); + verify(marker.options = options); + }); + + testWidgets('infoWindow null, showInfoWindow.', + (WidgetTester tester) async { + final controller = MarkerController(marker: marker); + controller.showInfoWindow(); + expect(controller.infoWindowShown, isFalse); + }); + + testWidgets('showInfoWindow', (WidgetTester tester) async { + final infoWindow = _MockInfoWindow(); + final controller = + MarkerController(marker: marker, infoWindow: infoWindow); + controller.showInfoWindow(); + verify(infoWindow.open(any, any)).called(1); + expect(controller.infoWindowShown, isTrue); + }); + + testWidgets('hideInfoWindow', (WidgetTester tester) async { + final infoWindow = _MockInfoWindow(); + final controller = + MarkerController(marker: marker, infoWindow: infoWindow); + controller.hideInfoWindow(); + verify(infoWindow.close()).called(1); + expect(controller.infoWindowShown, isFalse); + }); + }); +} diff --git a/packages/google_maps_flutter/google_maps_flutter_web/test/test_driver/marker_integration_test.dart b/packages/google_maps_flutter/google_maps_flutter_web/test/test_driver/marker_integration_test.dart new file mode 100644 index 000000000000..39444c0daa24 --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_web/test/test_driver/marker_integration_test.dart @@ -0,0 +1,7 @@ +// Copyright 2017 The Chromium 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:integration_test/integration_test_driver.dart'; + +Future main() async => integrationDriver(); diff --git a/packages/google_maps_flutter/google_maps_flutter_web/test/test_driver/markers_integration.dart b/packages/google_maps_flutter/google_maps_flutter_web/test/test_driver/markers_integration.dart new file mode 100644 index 000000000000..f447535668b9 --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_web/test/test_driver/markers_integration.dart @@ -0,0 +1,102 @@ +// Copyright 2017 The Chromium 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:integration_test/integration_test.dart'; +import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart'; +import 'package:google_maps_flutter_web/google_maps_flutter_web.dart'; +import 'package:flutter_test/flutter_test.dart'; + +void main() { + IntegrationTestWidgetsFlutterBinding.ensureInitialized(); + + group('MarkersController', () { + StreamController stream; + MarkersController controller; + + setUp(() { + stream = StreamController(); + controller = MarkersController(stream: stream); + }); + + testWidgets('addMarkers', (WidgetTester tester) async { + final markers = { + Marker(markerId: MarkerId('1')), + Marker(markerId: MarkerId('2')), + }; + + controller.addMarkers(markers); + + expect(controller.markers.length, 2); + expect(controller.markers, contains(MarkerId('1'))); + expect(controller.markers, contains(MarkerId('2'))); + expect(controller.markers, isNot(contains(MarkerId('66')))); + }); + + testWidgets('changeMarkers', (WidgetTester tester) async { + final markers = { + Marker(markerId: MarkerId('1')), + }; + controller.addMarkers(markers); + + expect(controller.markers[MarkerId('1')].marker.draggable, isFalse); + + // Update the marker with radius 10 + final updatedMarkers = { + Marker(markerId: MarkerId('1'), draggable: true), + }; + controller.changeMarkers(updatedMarkers); + + expect(controller.markers.length, 1); + expect(controller.markers[MarkerId('1')].marker.draggable, isTrue); + }); + + testWidgets('removeMarkers', (WidgetTester tester) async { + final markers = { + Marker(markerId: MarkerId('1')), + Marker(markerId: MarkerId('2')), + Marker(markerId: MarkerId('3')), + }; + + controller.addMarkers(markers); + + expect(controller.markers.length, 3); + + // Remove some markers... + final markerIdsToRemove = { + MarkerId('1'), + MarkerId('3'), + }; + + controller.removeMarkers(markerIdsToRemove); + + expect(controller.markers.length, 1); + expect(controller.markers, isNot(contains(MarkerId('1')))); + expect(controller.markers, contains(MarkerId('2'))); + expect(controller.markers, isNot(contains(MarkerId('3')))); + }); + + testWidgets('InfoWindow show/hide', (WidgetTester tester) async { + final markers = { + Marker( + markerId: MarkerId('1'), + infoWindow: InfoWindow(title: "Title", snippet: "Snippet"), + ), + }; + + controller.addMarkers(markers); + + expect(controller.markers[MarkerId('1')].infoWindowShown, isFalse); + + controller.showMarkerInfoWindow(MarkerId('1')); + + expect(controller.markers[MarkerId('1')].infoWindowShown, isTrue); + + controller.hideMarkerInfoWindow(MarkerId('1')); + + expect(controller.markers[MarkerId('1')].infoWindowShown, isFalse); + }); + }); +} diff --git a/packages/google_maps_flutter/google_maps_flutter_web/test/test_driver/markers_integration_test.dart b/packages/google_maps_flutter/google_maps_flutter_web/test/test_driver/markers_integration_test.dart new file mode 100644 index 000000000000..39444c0daa24 --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_web/test/test_driver/markers_integration_test.dart @@ -0,0 +1,7 @@ +// Copyright 2017 The Chromium 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:integration_test/integration_test_driver.dart'; + +Future main() async => integrationDriver(); diff --git a/packages/google_maps_flutter/google_maps_flutter_web/test/test_driver/shape_integration.dart b/packages/google_maps_flutter/google_maps_flutter_web/test/test_driver/shape_integration.dart new file mode 100644 index 000000000000..a05d704850e6 --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_web/test/test_driver/shape_integration.dart @@ -0,0 +1,113 @@ +// Copyright 2017 The Chromium 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:integration_test/integration_test.dart'; +import 'package:google_maps/google_maps.dart' as gmaps; +import 'package:google_maps_flutter_web/google_maps_flutter_web.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:mockito/mockito.dart'; + +class _MockCircle extends Mock implements gmaps.Circle { + final onClickController = StreamController(); + @override + Stream get onClick => onClickController.stream; +} + +class _MockPolygon extends Mock implements gmaps.Polygon { + final onClickController = StreamController(); + @override + Stream get onClick => onClickController.stream; +} + +class _MockPolyline extends Mock implements gmaps.Polyline { + final onClickController = StreamController(); + @override + Stream get onClick => onClickController.stream; +} + +/// Test Shapes (Circle, Polygon, Polyline) +void main() { + IntegrationTestWidgetsFlutterBinding.ensureInitialized(); + + bool called = false; + void onTap() { + called = true; + } + + setUp(() { + called = false; + }); + + group('CircleController', () { + _MockCircle circle; + + setUp(() { + circle = _MockCircle(); + }); + + testWidgets('onTap gets called', (WidgetTester tester) async { + CircleController(circle: circle, consumeTapEvents: true, onTap: onTap); + expect(circle.onClickController.hasListener, isTrue); + // Simulate a click + await circle.onClickController.add(null); + expect(called, isTrue); + }); + + testWidgets('update', (WidgetTester tester) async { + final controller = CircleController(circle: circle); + final options = gmaps.CircleOptions()..draggable = false; + controller.update(options); + verify(circle.options = options); + }); + }); + + group('PolygonController', () { + _MockPolygon polygon; + + setUp(() { + polygon = _MockPolygon(); + }); + + testWidgets('onTap gets called', (WidgetTester tester) async { + PolygonController(polygon: polygon, consumeTapEvents: true, onTap: onTap); + expect(polygon.onClickController.hasListener, isTrue); + // Simulate a click + await polygon.onClickController.add(null); + expect(called, isTrue); + }); + + testWidgets('update', (WidgetTester tester) async { + final controller = PolygonController(polygon: polygon); + final options = gmaps.PolygonOptions()..draggable = false; + controller.update(options); + verify(polygon.options = options); + }); + }); + + group('PolylineController', () { + _MockPolyline polyline; + + setUp(() { + polyline = _MockPolyline(); + }); + + testWidgets('onTap gets called', (WidgetTester tester) async { + PolylineController( + polyline: polyline, consumeTapEvents: true, onTap: onTap); + expect(polyline.onClickController.hasListener, isTrue); + // Simulate a click + await polyline.onClickController.add(null); + expect(called, isTrue); + }); + + testWidgets('update', (WidgetTester tester) async { + final controller = PolylineController(polyline: polyline); + final options = gmaps.PolylineOptions()..draggable = false; + controller.update(options); + verify(polyline.options = options); + }); + }); +} diff --git a/packages/google_maps_flutter/google_maps_flutter_web/test/test_driver/shape_integration_test.dart b/packages/google_maps_flutter/google_maps_flutter_web/test/test_driver/shape_integration_test.dart new file mode 100644 index 000000000000..39444c0daa24 --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_web/test/test_driver/shape_integration_test.dart @@ -0,0 +1,7 @@ +// Copyright 2017 The Chromium 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:integration_test/integration_test_driver.dart'; + +Future main() async => integrationDriver(); diff --git a/packages/google_maps_flutter/google_maps_flutter_web/test/test_driver/shapes_integration.dart b/packages/google_maps_flutter/google_maps_flutter_web/test/test_driver/shapes_integration.dart new file mode 100644 index 000000000000..b1bff7edd429 --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_web/test/test_driver/shapes_integration.dart @@ -0,0 +1,214 @@ +// Copyright 2017 The Chromium 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:integration_test/integration_test.dart'; +import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart'; +import 'package:google_maps_flutter_web/google_maps_flutter_web.dart'; +import 'package:flutter_test/flutter_test.dart'; + +/// Test Shapes (Circle, Polygon, Polyline) +void main() { + IntegrationTestWidgetsFlutterBinding.ensureInitialized(); + + group('CirclesController', () { + StreamController stream; + CirclesController controller; + + setUp(() { + stream = StreamController(); + controller = CirclesController(stream: stream); + }); + + testWidgets('addCircles', (WidgetTester tester) async { + final circles = { + Circle(circleId: CircleId('1')), + Circle(circleId: CircleId('2')), + }; + + controller.addCircles(circles); + + expect(controller.circles.length, 2); + expect(controller.circles, contains(CircleId('1'))); + expect(controller.circles, contains(CircleId('2'))); + expect(controller.circles, isNot(contains(CircleId('66')))); + }); + + testWidgets('changeCircles', (WidgetTester tester) async { + final circles = { + Circle(circleId: CircleId('1')), + }; + controller.addCircles(circles); + + expect(controller.circles[CircleId('1')].circle.visible, isTrue); + + final updatedCircles = { + Circle(circleId: CircleId('1'), visible: false), + }; + controller.changeCircles(updatedCircles); + + expect(controller.circles.length, 1); + expect(controller.circles[CircleId('1')].circle.visible, isFalse); + }); + + testWidgets('removeCircles', (WidgetTester tester) async { + final circles = { + Circle(circleId: CircleId('1')), + Circle(circleId: CircleId('2')), + Circle(circleId: CircleId('3')), + }; + + controller.addCircles(circles); + + expect(controller.circles.length, 3); + + // Remove some circles... + final circleIdsToRemove = { + CircleId('1'), + CircleId('3'), + }; + + controller.removeCircles(circleIdsToRemove); + + expect(controller.circles.length, 1); + expect(controller.circles, isNot(contains(CircleId('1')))); + expect(controller.circles, contains(CircleId('2'))); + expect(controller.circles, isNot(contains(CircleId('3')))); + }); + }); + + group('PolygonsController', () { + StreamController stream; + PolygonsController controller; + + setUp(() { + stream = StreamController(); + controller = PolygonsController(stream: stream); + }); + + testWidgets('addPolygons', (WidgetTester tester) async { + final polygons = { + Polygon(polygonId: PolygonId('1')), + Polygon(polygonId: PolygonId('2')), + }; + + controller.addPolygons(polygons); + + expect(controller.polygons.length, 2); + expect(controller.polygons, contains(PolygonId('1'))); + expect(controller.polygons, contains(PolygonId('2'))); + expect(controller.polygons, isNot(contains(PolygonId('66')))); + }); + + testWidgets('changePolygons', (WidgetTester tester) async { + final polygons = { + Polygon(polygonId: PolygonId('1')), + }; + controller.addPolygons(polygons); + + expect(controller.polygons[PolygonId('1')].polygon.visible, isTrue); + + // Update the polygon + final updatedPolygons = { + Polygon(polygonId: PolygonId('1'), visible: false), + }; + controller.changePolygons(updatedPolygons); + + expect(controller.polygons.length, 1); + expect(controller.polygons[PolygonId('1')].polygon.visible, isFalse); + }); + + testWidgets('removePolygons', (WidgetTester tester) async { + final polygons = { + Polygon(polygonId: PolygonId('1')), + Polygon(polygonId: PolygonId('2')), + Polygon(polygonId: PolygonId('3')), + }; + + controller.addPolygons(polygons); + + expect(controller.polygons.length, 3); + + // Remove some polygons... + final polygonIdsToRemove = { + PolygonId('1'), + PolygonId('3'), + }; + + controller.removePolygons(polygonIdsToRemove); + + expect(controller.polygons.length, 1); + expect(controller.polygons, isNot(contains(PolygonId('1')))); + expect(controller.polygons, contains(PolygonId('2'))); + expect(controller.polygons, isNot(contains(PolygonId('3')))); + }); + }); + + group('PolylinesController', () { + StreamController stream; + PolylinesController controller; + + setUp(() { + stream = StreamController(); + controller = PolylinesController(stream: stream); + }); + + testWidgets('addPolylines', (WidgetTester tester) async { + final polylines = { + Polyline(polylineId: PolylineId('1')), + Polyline(polylineId: PolylineId('2')), + }; + + controller.addPolylines(polylines); + + expect(controller.lines.length, 2); + expect(controller.lines, contains(PolylineId('1'))); + expect(controller.lines, contains(PolylineId('2'))); + expect(controller.lines, isNot(contains(PolylineId('66')))); + }); + + testWidgets('changePolylines', (WidgetTester tester) async { + final polylines = { + Polyline(polylineId: PolylineId('1')), + }; + controller.addPolylines(polylines); + + expect(controller.lines[PolylineId('1')].line.visible, isTrue); + + final updatedPolylines = { + Polyline(polylineId: PolylineId('1'), visible: false), + }; + controller.changePolylines(updatedPolylines); + + expect(controller.lines.length, 1); + expect(controller.lines[PolylineId('1')].line.visible, isFalse); + }); + + testWidgets('removePolylines', (WidgetTester tester) async { + final polylines = { + Polyline(polylineId: PolylineId('1')), + Polyline(polylineId: PolylineId('2')), + Polyline(polylineId: PolylineId('3')), + }; + + controller.addPolylines(polylines); + + expect(controller.lines.length, 3); + + // Remove some polylines... + final polylineIdsToRemove = { + PolylineId('1'), + PolylineId('3'), + }; + + controller.removePolylines(polylineIdsToRemove); + + expect(controller.lines.length, 1); + expect(controller.lines, isNot(contains(PolylineId('1')))); + expect(controller.lines, contains(PolylineId('2'))); + expect(controller.lines, isNot(contains(PolylineId('3')))); + }); + }); +} diff --git a/packages/google_maps_flutter/google_maps_flutter_web/test/test_driver/shapes_integration_test.dart b/packages/google_maps_flutter/google_maps_flutter_web/test/test_driver/shapes_integration_test.dart new file mode 100644 index 000000000000..39444c0daa24 --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_web/test/test_driver/shapes_integration_test.dart @@ -0,0 +1,7 @@ +// Copyright 2017 The Chromium 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:integration_test/integration_test_driver.dart'; + +Future main() async => integrationDriver(); diff --git a/packages/google_maps_flutter/google_maps_flutter_web/test/web/index.html b/packages/google_maps_flutter/google_maps_flutter_web/test/web/index.html new file mode 100644 index 000000000000..3b7e4edc3df1 --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_web/test/web/index.html @@ -0,0 +1,14 @@ + + + + + Browser Tests + + + + + + + diff --git a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/android/app/src/main/java/io/flutter/plugins/googlesigninexample/EmbeddingV1ActivityTest.java b/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/android/app/src/main/java/io/flutter/plugins/googlesigninexample/EmbeddingV1ActivityTest.java index 8bddbff7ce27..4d872e7eb5a1 100644 --- a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/android/app/src/main/java/io/flutter/plugins/googlesigninexample/EmbeddingV1ActivityTest.java +++ b/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/android/app/src/main/java/io/flutter/plugins/googlesigninexample/EmbeddingV1ActivityTest.java @@ -5,11 +5,11 @@ package io.flutter.plugins.googlesigninexample; import androidx.test.rule.ActivityTestRule; -import dev.flutter.plugins.e2e.FlutterRunner; +import dev.flutter.plugins.integration_test.FlutterTestRunner; import org.junit.Rule; import org.junit.runner.RunWith; -@RunWith(FlutterRunner.class) +@RunWith(FlutterTestRunner.class) public class EmbeddingV1ActivityTest { @Rule public ActivityTestRule rule = diff --git a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/android/app/src/main/java/io/flutter/plugins/googlesigninexample/FlutterActivityTest.java b/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/android/app/src/main/java/io/flutter/plugins/googlesigninexample/FlutterActivityTest.java index 77cdcee9bcdb..f9aa77b30e5d 100644 --- a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/android/app/src/main/java/io/flutter/plugins/googlesigninexample/FlutterActivityTest.java +++ b/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/android/app/src/main/java/io/flutter/plugins/googlesigninexample/FlutterActivityTest.java @@ -5,12 +5,12 @@ package io.flutter.plugins.googlesigninexample; import androidx.test.rule.ActivityTestRule; -import dev.flutter.plugins.e2e.FlutterRunner; +import dev.flutter.plugins.integration_test.FlutterTestRunner; import io.flutter.embedding.android.FlutterActivity; import org.junit.Rule; import org.junit.runner.RunWith; -@RunWith(FlutterRunner.class) +@RunWith(FlutterTestRunner.class) public class FlutterActivityTest { @Rule public ActivityTestRule rule = new ActivityTestRule<>(FlutterActivity.class); diff --git a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/pubspec.yaml b/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/pubspec.yaml index aee073971d2c..3e64fa2da3f2 100755 --- a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/pubspec.yaml +++ b/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/pubspec.yaml @@ -11,7 +11,8 @@ dependencies: dev_dependencies: pedantic: ^1.8.0 - e2e: ^0.2.1 + integration_test: + path: ../../../integration_test flutter_driver: sdk: flutter diff --git a/packages/google_sign_in/google_sign_in/CHANGELOG.md b/packages/google_sign_in/google_sign_in/CHANGELOG.md index 8fbba4944df7..e0212458a549 100644 --- a/packages/google_sign_in/google_sign_in/CHANGELOG.md +++ b/packages/google_sign_in/google_sign_in/CHANGELOG.md @@ -1,3 +1,12 @@ +## 4.5.3 + +* Update package:e2e -> package:integration_test + +## 4.5.2 + +* Update package:e2e reference to use the local version in the flutter/plugins + repository. + ## 4.5.1 * Add note on Apple sign in requirement in README. diff --git a/packages/google_sign_in/google_sign_in/example/android/app/src/main/java/io/flutter/plugins/googlesigninexample/EmbeddingV1ActivityTest.java b/packages/google_sign_in/google_sign_in/example/android/app/src/main/java/io/flutter/plugins/googlesigninexample/EmbeddingV1ActivityTest.java index 8bddbff7ce27..4d872e7eb5a1 100644 --- a/packages/google_sign_in/google_sign_in/example/android/app/src/main/java/io/flutter/plugins/googlesigninexample/EmbeddingV1ActivityTest.java +++ b/packages/google_sign_in/google_sign_in/example/android/app/src/main/java/io/flutter/plugins/googlesigninexample/EmbeddingV1ActivityTest.java @@ -5,11 +5,11 @@ package io.flutter.plugins.googlesigninexample; import androidx.test.rule.ActivityTestRule; -import dev.flutter.plugins.e2e.FlutterRunner; +import dev.flutter.plugins.integration_test.FlutterTestRunner; import org.junit.Rule; import org.junit.runner.RunWith; -@RunWith(FlutterRunner.class) +@RunWith(FlutterTestRunner.class) public class EmbeddingV1ActivityTest { @Rule public ActivityTestRule rule = diff --git a/packages/google_sign_in/google_sign_in/example/android/app/src/main/java/io/flutter/plugins/googlesigninexample/FlutterActivityTest.java b/packages/google_sign_in/google_sign_in/example/android/app/src/main/java/io/flutter/plugins/googlesigninexample/FlutterActivityTest.java index 77cdcee9bcdb..f9aa77b30e5d 100644 --- a/packages/google_sign_in/google_sign_in/example/android/app/src/main/java/io/flutter/plugins/googlesigninexample/FlutterActivityTest.java +++ b/packages/google_sign_in/google_sign_in/example/android/app/src/main/java/io/flutter/plugins/googlesigninexample/FlutterActivityTest.java @@ -5,12 +5,12 @@ package io.flutter.plugins.googlesigninexample; import androidx.test.rule.ActivityTestRule; -import dev.flutter.plugins.e2e.FlutterRunner; +import dev.flutter.plugins.integration_test.FlutterTestRunner; import io.flutter.embedding.android.FlutterActivity; import org.junit.Rule; import org.junit.runner.RunWith; -@RunWith(FlutterRunner.class) +@RunWith(FlutterTestRunner.class) public class FlutterActivityTest { @Rule public ActivityTestRule rule = new ActivityTestRule<>(FlutterActivity.class); diff --git a/packages/google_sign_in/google_sign_in/example/pubspec.yaml b/packages/google_sign_in/google_sign_in/example/pubspec.yaml index e3ab95e618f7..ebf8e82719f2 100755 --- a/packages/google_sign_in/google_sign_in/example/pubspec.yaml +++ b/packages/google_sign_in/google_sign_in/example/pubspec.yaml @@ -10,7 +10,8 @@ dependencies: dev_dependencies: pedantic: ^1.8.0 - e2e: ^0.2.1 + integration_test: + path: ../../../integration_test flutter_driver: sdk: flutter diff --git a/packages/google_sign_in/google_sign_in/pubspec.yaml b/packages/google_sign_in/google_sign_in/pubspec.yaml index 8e520334192c..c5bc15f037c5 100644 --- a/packages/google_sign_in/google_sign_in/pubspec.yaml +++ b/packages/google_sign_in/google_sign_in/pubspec.yaml @@ -2,7 +2,7 @@ name: google_sign_in description: Flutter plugin for Google Sign-In, a secure authentication system for signing in with a Google account on Android and iOS. homepage: https://github.com/flutter/plugins/tree/master/packages/google_sign_in/google_sign_in -version: 4.5.1 +version: 4.5.3 flutter: plugin: @@ -34,7 +34,8 @@ dev_dependencies: flutter_test: sdk: flutter pedantic: ^1.8.0 - e2e: ^0.2.1 + integration_test: + path: ../../integration_test environment: sdk: ">=2.1.0 <3.0.0" diff --git a/packages/google_sign_in/google_sign_in/test/google_sign_in_e2e.dart b/packages/google_sign_in/google_sign_in/test/google_sign_in_e2e.dart index 0c6431f37bf4..7b2b8d800778 100644 --- a/packages/google_sign_in/google_sign_in/test/google_sign_in_e2e.dart +++ b/packages/google_sign_in/google_sign_in/test/google_sign_in_e2e.dart @@ -1,9 +1,9 @@ -import 'package:e2e/e2e.dart'; +import 'package:integration_test/integration_test.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:google_sign_in/google_sign_in.dart'; void main() { - E2EWidgetsFlutterBinding.ensureInitialized(); + IntegrationTestWidgetsFlutterBinding.ensureInitialized(); testWidgets('Can initialize the plugin', (WidgetTester tester) async { GoogleSignIn signIn = GoogleSignIn(); diff --git a/packages/google_sign_in/google_sign_in/test_driver/google_sign_in_e2e_test.dart b/packages/google_sign_in/google_sign_in/test_driver/google_sign_in_e2e_test.dart index 9f1704fc4003..f07dba382187 100644 --- a/packages/google_sign_in/google_sign_in/test_driver/google_sign_in_e2e_test.dart +++ b/packages/google_sign_in/google_sign_in/test_driver/google_sign_in_e2e_test.dart @@ -3,13 +3,15 @@ // BSD-style license that can be found in the LICENSE file. import 'dart:async'; +import 'dart:convert'; import 'dart:io'; import 'package:flutter_driver/flutter_driver.dart'; Future main() async { final FlutterDriver driver = await FlutterDriver.connect(); - final String result = + final String data = await driver.requestData(null, timeout: const Duration(minutes: 1)); await driver.close(); - exit(result == 'pass' ? 0 : 1); + final Map result = jsonDecode(data); + exit(result['result'] == 'true' ? 0 : 1); } diff --git a/packages/google_sign_in/google_sign_in_web/CHANGELOG.md b/packages/google_sign_in/google_sign_in_web/CHANGELOG.md index af6b1a08b122..35a6934f9d4e 100644 --- a/packages/google_sign_in/google_sign_in_web/CHANGELOG.md +++ b/packages/google_sign_in/google_sign_in_web/CHANGELOG.md @@ -1,3 +1,8 @@ +## 0.9.1+2 + +* Update package:e2e reference to use the local version in the flutter/plugins + repository. + ## 0.9.1+1 * Remove Android folder from `google_sign_in_web`. diff --git a/packages/google_sign_in/google_sign_in_web/pubspec.yaml b/packages/google_sign_in/google_sign_in_web/pubspec.yaml index 76922d9eb8e6..8b48d36fde3c 100644 --- a/packages/google_sign_in/google_sign_in_web/pubspec.yaml +++ b/packages/google_sign_in/google_sign_in_web/pubspec.yaml @@ -2,7 +2,7 @@ name: google_sign_in_web description: Flutter plugin for Google Sign-In, a secure authentication system for signing in with a Google account on Android, iOS and Web. homepage: https://github.com/flutter/plugins/tree/master/packages/google_sign_in/google_sign_in_web -version: 0.9.1+1 +version: 0.9.1+2 flutter: plugin: diff --git a/packages/image_picker/image_picker/CHANGELOG.md b/packages/image_picker/image_picker/CHANGELOG.md index 0cec3a32b5f1..197314292f8f 100644 --- a/packages/image_picker/image_picker/CHANGELOG.md +++ b/packages/image_picker/image_picker/CHANGELOG.md @@ -1,3 +1,13 @@ +## 0.6.7+6 + +* Update package:e2e -> package:integration_test + +## 0.6.7+5 + +* Update package:e2e reference to use the local version in the flutter/plugins + repository. + + ## 0.6.7+4 * Support iOS simulator x86_64 architecture. diff --git a/packages/image_picker/image_picker/example/android/app/src/main/java/io/flutter/plugins/imagepickerexample/EmbeddingV1ActivityTest.java b/packages/image_picker/image_picker/example/android/app/src/main/java/io/flutter/plugins/imagepickerexample/EmbeddingV1ActivityTest.java index 924cf2fdb93c..0a8330d734bd 100644 --- a/packages/image_picker/image_picker/example/android/app/src/main/java/io/flutter/plugins/imagepickerexample/EmbeddingV1ActivityTest.java +++ b/packages/image_picker/image_picker/example/android/app/src/main/java/io/flutter/plugins/imagepickerexample/EmbeddingV1ActivityTest.java @@ -5,11 +5,11 @@ package io.flutter.plugins.imagepickerexample; import androidx.test.rule.ActivityTestRule; -import dev.flutter.plugins.e2e.FlutterRunner; +import dev.flutter.plugins.integration_test.FlutterTestRunner; import org.junit.Rule; import org.junit.runner.RunWith; -@RunWith(FlutterRunner.class) +@RunWith(FlutterTestRunner.class) public class EmbeddingV1ActivityTest { @Rule public ActivityTestRule rule = diff --git a/packages/image_picker/image_picker/example/android/app/src/main/java/io/flutter/plugins/imagepickerexample/FlutterActivityTest.java b/packages/image_picker/image_picker/example/android/app/src/main/java/io/flutter/plugins/imagepickerexample/FlutterActivityTest.java index df9794c8748f..58f8df35dc4f 100644 --- a/packages/image_picker/image_picker/example/android/app/src/main/java/io/flutter/plugins/imagepickerexample/FlutterActivityTest.java +++ b/packages/image_picker/image_picker/example/android/app/src/main/java/io/flutter/plugins/imagepickerexample/FlutterActivityTest.java @@ -1,12 +1,12 @@ package io.flutter.plugins.imagepickerexample; import androidx.test.rule.ActivityTestRule; -import dev.flutter.plugins.e2e.FlutterRunner; +import dev.flutter.plugins.integration_test.FlutterTestRunner; import io.flutter.embedding.android.FlutterActivity; import org.junit.Rule; import org.junit.runner.RunWith; -@RunWith(FlutterRunner.class) +@RunWith(FlutterTestRunner.class) public class FlutterActivityTest { @Rule public ActivityTestRule rule = new ActivityTestRule<>(FlutterActivity.class); diff --git a/packages/image_picker/image_picker/example/pubspec.yaml b/packages/image_picker/image_picker/example/pubspec.yaml index 93df8dfdc010..0ff2f280e2ab 100755 --- a/packages/image_picker/image_picker/example/pubspec.yaml +++ b/packages/image_picker/image_picker/example/pubspec.yaml @@ -14,7 +14,8 @@ dependencies: dev_dependencies: flutter_driver: sdk: flutter - e2e: ^0.2.1 + integration_test: + path: ../../../integration_test pedantic: ^1.8.0 flutter: diff --git a/packages/image_picker/image_picker/example/test_driver/test/image_picker_e2e_test.dart b/packages/image_picker/image_picker/example/test_driver/test/image_picker_e2e_test.dart index f3aa9e218d82..7a2c21338786 100644 --- a/packages/image_picker/image_picker/example/test_driver/test/image_picker_e2e_test.dart +++ b/packages/image_picker/image_picker/example/test_driver/test/image_picker_e2e_test.dart @@ -3,13 +3,15 @@ // BSD-style license that can be found in the LICENSE file. import 'dart:async'; +import 'dart:convert'; import 'dart:io'; import 'package:flutter_driver/flutter_driver.dart'; Future main() async { final FlutterDriver driver = await FlutterDriver.connect(); - final String result = + final String data = await driver.requestData(null, timeout: const Duration(minutes: 1)); await driver.close(); - exit(result == 'pass' ? 0 : 1); + final Map result = jsonDecode(data); + exit(result['result'] == 'true' ? 0 : 1); } diff --git a/packages/image_picker/image_picker/pubspec.yaml b/packages/image_picker/image_picker/pubspec.yaml index 06da5297d80c..118faf3712bc 100755 --- a/packages/image_picker/image_picker/pubspec.yaml +++ b/packages/image_picker/image_picker/pubspec.yaml @@ -2,7 +2,7 @@ name: image_picker description: Flutter plugin for selecting images from the Android and iOS image library, and taking new pictures with the camera. homepage: https://github.com/flutter/plugins/tree/master/packages/image_picker/image_picker -version: 0.6.7+4 +version: 0.6.7+6 flutter: plugin: @@ -23,7 +23,8 @@ dev_dependencies: video_player: ^0.10.3 flutter_test: sdk: flutter - e2e: ^0.2.1 + integration_test: + path: ../../integration_test pedantic: ^1.8.0 environment: diff --git a/packages/image_picker/image_picker/test/old_image_picker_e2e.dart b/packages/image_picker/image_picker/test/old_image_picker_e2e.dart index b19e37dd6541..d21a4e0cdfa3 100644 --- a/packages/image_picker/image_picker/test/old_image_picker_e2e.dart +++ b/packages/image_picker/image_picker/test/old_image_picker_e2e.dart @@ -1,5 +1,5 @@ -import 'package:e2e/e2e.dart'; +import 'package:integration_test/integration_test.dart'; void main() { - E2EWidgetsFlutterBinding.ensureInitialized(); + IntegrationTestWidgetsFlutterBinding.ensureInitialized(); } diff --git a/packages/in_app_purchase/CHANGELOG.md b/packages/in_app_purchase/CHANGELOG.md index c159b094fb47..ad53c7ccf1f5 100644 --- a/packages/in_app_purchase/CHANGELOG.md +++ b/packages/in_app_purchase/CHANGELOG.md @@ -1,3 +1,16 @@ +## 0.3.4+4 + +* Update package:e2e -> package:integration_test + +## 0.3.4+3 + +* Fixed typo 'manuelly' for 'manually'. + +## 0.3.4+2 + +* Update package:e2e reference to use the local version in the flutter/plugins + repository. + ## 0.3.4+1 * iOS: Fix the bug that `SKPaymentQueueWrapper.transactions` doesn't return all transactions. diff --git a/packages/in_app_purchase/example/android/app/src/main/java/io/flutter/plugins/inapppurchaseexample/EmbeddingV1Activity.java b/packages/in_app_purchase/example/android/app/src/main/java/io/flutter/plugins/inapppurchaseexample/EmbeddingV1Activity.java index 425c1661066b..e157950e5bec 100644 --- a/packages/in_app_purchase/example/android/app/src/main/java/io/flutter/plugins/inapppurchaseexample/EmbeddingV1Activity.java +++ b/packages/in_app_purchase/example/android/app/src/main/java/io/flutter/plugins/inapppurchaseexample/EmbeddingV1Activity.java @@ -5,7 +5,7 @@ package io.flutter.plugins.inapppurchaseexample; import android.os.Bundle; -import dev.flutter.plugins.e2e.E2EPlugin; +import dev.flutter.plugins.integration_test.IntegrationTestPlugin; import io.flutter.app.FlutterActivity; import io.flutter.plugins.inapppurchase.InAppPurchasePlugin; import io.flutter.plugins.sharedpreferences.SharedPreferencesPlugin; @@ -14,7 +14,8 @@ public class EmbeddingV1Activity extends FlutterActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - E2EPlugin.registerWith(registrarFor("dev.flutter.plugins.e2e.E2EPlugin")); + IntegrationTestPlugin.registerWith( + registrarFor("dev.flutter.plugins.integration_test.IntegrationTestPlugin")); SharedPreferencesPlugin.registerWith( registrarFor("io.flutter.plugins.sharedpreferences.SharedPreferencesPlugin")); InAppPurchasePlugin.registerWith( diff --git a/packages/in_app_purchase/example/android/app/src/main/java/io/flutter/plugins/inapppurchaseexample/EmbeddingV1ActivityTest.java b/packages/in_app_purchase/example/android/app/src/main/java/io/flutter/plugins/inapppurchaseexample/EmbeddingV1ActivityTest.java index 1cac72300228..b8ca3ae96e2c 100644 --- a/packages/in_app_purchase/example/android/app/src/main/java/io/flutter/plugins/inapppurchaseexample/EmbeddingV1ActivityTest.java +++ b/packages/in_app_purchase/example/android/app/src/main/java/io/flutter/plugins/inapppurchaseexample/EmbeddingV1ActivityTest.java @@ -5,11 +5,11 @@ package io.flutter.plugins.inapppurchaseexample; import androidx.test.rule.ActivityTestRule; -import dev.flutter.plugins.e2e.FlutterRunner; +import dev.flutter.plugins.integration_test.FlutterTestRunner; import org.junit.Rule; import org.junit.runner.RunWith; -@RunWith(FlutterRunner.class) +@RunWith(FlutterTestRunner.class) public class EmbeddingV1ActivityTest { @Rule public ActivityTestRule rule = diff --git a/packages/in_app_purchase/example/android/app/src/main/java/io/flutter/plugins/inapppurchaseexample/FlutterActivityTest.java b/packages/in_app_purchase/example/android/app/src/main/java/io/flutter/plugins/inapppurchaseexample/FlutterActivityTest.java index 1ebb9d212edb..15ec0da9958e 100644 --- a/packages/in_app_purchase/example/android/app/src/main/java/io/flutter/plugins/inapppurchaseexample/FlutterActivityTest.java +++ b/packages/in_app_purchase/example/android/app/src/main/java/io/flutter/plugins/inapppurchaseexample/FlutterActivityTest.java @@ -5,12 +5,12 @@ package io.flutter.plugins.inapppurchaseexample; import androidx.test.rule.ActivityTestRule; -import dev.flutter.plugins.e2e.FlutterRunner; +import dev.flutter.plugins.integration_test.FlutterTestRunner; import io.flutter.embedding.android.FlutterActivity; import org.junit.Rule; import org.junit.runner.RunWith; -@RunWith(FlutterRunner.class) +@RunWith(FlutterTestRunner.class) public class FlutterActivityTest { @Rule public ActivityTestRule rule = new ActivityTestRule<>(FlutterActivity.class); diff --git a/packages/in_app_purchase/example/pubspec.yaml b/packages/in_app_purchase/example/pubspec.yaml index 0d595bd41fd4..48359dbc6a06 100644 --- a/packages/in_app_purchase/example/pubspec.yaml +++ b/packages/in_app_purchase/example/pubspec.yaml @@ -14,7 +14,8 @@ dev_dependencies: sdk: flutter in_app_purchase: path: ../ - e2e: ^0.2.0 + integration_test: + path: ../../integration_test pedantic: ^1.8.0 flutter: diff --git a/packages/in_app_purchase/example/test_driver/test/in_app_purchase_e2e_test.dart b/packages/in_app_purchase/example/test_driver/test/in_app_purchase_e2e_test.dart index 449af666b605..7a2c21338786 100644 --- a/packages/in_app_purchase/example/test_driver/test/in_app_purchase_e2e_test.dart +++ b/packages/in_app_purchase/example/test_driver/test/in_app_purchase_e2e_test.dart @@ -2,14 +2,16 @@ // for details. 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:io'; import 'dart:async'; +import 'dart:convert'; +import 'dart:io'; import 'package:flutter_driver/flutter_driver.dart'; Future main() async { final FlutterDriver driver = await FlutterDriver.connect(); - final String result = + final String data = await driver.requestData(null, timeout: const Duration(minutes: 1)); await driver.close(); - exit(result == 'pass' ? 0 : 1); + final Map result = jsonDecode(data); + exit(result['result'] == 'true' ? 0 : 1); } diff --git a/packages/in_app_purchase/ios/Classes/InAppPurchasePlugin.m b/packages/in_app_purchase/ios/Classes/InAppPurchasePlugin.m index bfe29f981396..06fe74a613ae 100644 --- a/packages/in_app_purchase/ios/Classes/InAppPurchasePlugin.m +++ b/packages/in_app_purchase/ios/Classes/InAppPurchasePlugin.m @@ -187,7 +187,7 @@ - (void)addPayment:(FlutterMethodCall *)call result:(FlutterResult)result { result([FlutterError errorWithCode:@"storekit_duplicate_product_object" message:@"There is a pending transaction for the same product identifier. Please " - @"either wait for it to be finished or finish it manuelly using " + @"either wait for it to be finished or finish it manually using " @"`completePurchase` to avoid edge cases." details:call.arguments]); diff --git a/packages/in_app_purchase/ios/Tests/InAppPurchasePluginTest.m b/packages/in_app_purchase/ios/Tests/InAppPurchasePluginTest.m index 20543a203a97..f1290b074ad9 100644 --- a/packages/in_app_purchase/ios/Tests/InAppPurchasePluginTest.m +++ b/packages/in_app_purchase/ios/Tests/InAppPurchasePluginTest.m @@ -146,7 +146,7 @@ - (void)testAddPaymentWithSameProductIDWillFail { XCTAssertEqualObjects( error.message, @"There is a pending transaction for the same product identifier. Please " - @"either wait for it to be finished or finish it manuelly using " + @"either wait for it to be finished or finish it manually using " @"`completePurchase` to avoid edge cases."); [expectation fulfill]; }]; diff --git a/packages/in_app_purchase/pubspec.yaml b/packages/in_app_purchase/pubspec.yaml index 58f8e1174618..0633d154cb8b 100644 --- a/packages/in_app_purchase/pubspec.yaml +++ b/packages/in_app_purchase/pubspec.yaml @@ -1,7 +1,7 @@ name: in_app_purchase description: A Flutter plugin for in-app purchases. Exposes APIs for making in-app purchases through the App Store and Google Play. homepage: https://github.com/flutter/plugins/tree/master/packages/in_app_purchase -version: 0.3.4+1 +version: 0.3.4+4 dependencies: async: ^2.0.8 @@ -22,7 +22,8 @@ dev_dependencies: path: example/ test: ^1.5.2 shared_preferences: ^0.5.2 - e2e: ^0.2.0 + integration_test: + path: ../integration_test pedantic: ^1.8.0 flutter: diff --git a/packages/in_app_purchase/test/in_app_purchase_e2e.dart b/packages/in_app_purchase/test/in_app_purchase_e2e.dart index e167227b4c8f..a5bfdb0eb409 100644 --- a/packages/in_app_purchase/test/in_app_purchase_e2e.dart +++ b/packages/in_app_purchase/test/in_app_purchase_e2e.dart @@ -4,10 +4,10 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:in_app_purchase/in_app_purchase.dart'; -import 'package:e2e/e2e.dart'; +import 'package:integration_test/integration_test.dart'; void main() { - E2EWidgetsFlutterBinding.ensureInitialized(); + IntegrationTestWidgetsFlutterBinding.ensureInitialized(); testWidgets('Can create InAppPurchaseConnection instance', (WidgetTester tester) async { diff --git a/packages/e2e/.gitignore b/packages/integration_test/.gitignore similarity index 100% rename from packages/e2e/.gitignore rename to packages/integration_test/.gitignore diff --git a/packages/e2e/.metadata b/packages/integration_test/.metadata similarity index 100% rename from packages/e2e/.metadata rename to packages/integration_test/.metadata diff --git a/packages/e2e/CHANGELOG.md b/packages/integration_test/CHANGELOG.md similarity index 89% rename from packages/e2e/CHANGELOG.md rename to packages/integration_test/CHANGELOG.md index 255d7ce08c2d..cbd5282028f4 100644 --- a/packages/e2e/CHANGELOG.md +++ b/packages/integration_test/CHANGELOG.md @@ -1,3 +1,24 @@ +## 0.8.0 + +* Rename plugin to integration_test. + +## 0.7.0 + +* Move utilities for tracking frame performance in an e2e test to `flutter_test`. + +## 0.6.3 + +* Add customizable `flutter_driver` adaptor. +* Add utilities for tracking frame performance in an e2e test. + +## 0.6.2+1 + +* Fix incorrect test results when one test passes then another fails + +## 0.6.2 + +* Fix `setSurfaceSize` for e2e tests + ## 0.6.1 * Added `data` in the reported json. @@ -135,7 +156,7 @@ * Renamed package from instrumentation_adapter to e2e. * Refactored example app test. * **Breaking change**. Renamed `InstrumentationAdapterFlutterBinding` to - `E2EWidgetsFlutterBinding`. + `IntegrationTestWidgetsFlutterBinding`. * Updated README. ## 0.1.4 diff --git a/packages/e2e/LICENSE b/packages/integration_test/LICENSE similarity index 100% rename from packages/e2e/LICENSE rename to packages/integration_test/LICENSE diff --git a/packages/integration_test/README.md b/packages/integration_test/README.md new file mode 100644 index 000000000000..bb0bfa2eb1ae --- /dev/null +++ b/packages/integration_test/README.md @@ -0,0 +1,192 @@ +# integration_test + +This package enables self-driving testing of Flutter code on devices and emulators. +It adapts flutter_test results into a format that is compatible with `flutter drive` +and native Android instrumentation testing. + +## Usage + +Add a dependency on the `integration_test` package in the +`dev_dependencies` section of pubspec.yaml. For plugins, do this in the +pubspec.yaml of the example app. + +Invoke `IntegrationTestWidgetsFlutterBinding.ensureInitialized()` at the start +of a test file, e.g. + +```dart +import 'package:integration_test/integration_test.dart'; + +void main() { + IntegrationTestWidgetsFlutterBinding.ensureInitialized(); + testWidgets("failing test example", (WidgetTester tester) async { + expect(2 + 2, equals(5)); + }); +} +``` + +## Test locations + +It is recommended to put integration_test tests in the `test/` folder of the app +or package. For example apps, if the integration_test test references example +app code, it should go in `example/test/`. It is also acceptable to put +integration_test tests in `test_driver/` folder so that they're alongside the +runner app (see below). + +## Using Flutter driver to run tests + +`IntegrationTestWidgetsTestBinding` supports launching the on-device tests with +`flutter drive`. Note that the tests don't use the `FlutterDriver` API, they +use `testWidgets` instead. + +Put the a file named `_integration_test.dart` in the app' +`test_driver` directory: + +```dart +import 'dart:async'; + +import 'package:integration_test/integration_test_driver.dart'; + +Future main() async => integrationDriver(); + +``` + +To run a example app test with Flutter driver: + +``` +cd example +flutter drive test/_integration.dart +``` + +To test plugin APIs using Flutter driver: + +``` +cd example +flutter drive --driver=test_driver/_test.dart test/_e2e.dart +``` + +You can run tests on web in release or profile mode. + +First you need to make sure you have downloaded the driver for the browser. + +``` +cd example +flutter drive -v --target=test_driver/dart -d web-server --release --browser-name=chrome +``` + +## Android device testing + +Create an instrumentation test file in your application's +**android/app/src/androidTest/java/com/example/myapp/** directory (replacing +com, example, and myapp with values from your app's package name). You can name +this test file MainActivityTest.java or another name of your choice. + +```java +package com.example.myapp; + +import androidx.test.rule.ActivityTestRule; +import dev.flutter.plugins.e2e.FlutterTestRunner; +import org.junit.Rule; +import org.junit.runner.RunWith; + +@RunWith(FlutterTestRunner.class) +public class MainActivityTest { + @Rule + public ActivityTestRule rule = new ActivityTestRule<>(MainActivity.class, true, false); +} +``` + +Update your application's **myapp/android/app/build.gradle** to make sure it +uses androidx's version of AndroidJUnitRunner and has androidx libraries as a +dependency. + +``` +android { + ... + defaultConfig { + ... + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } +} + +dependencies { + testImplementation 'junit:junit:4.12' + + // https://developer.android.com/jetpack/androidx/releases/test/#1.2.0 + androidTestImplementation 'androidx.test:runner:1.2.0' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' +} +``` + +To e2e test on a local Android device (emulated or physical): + +``` +./gradlew app:connectedAndroidTest -Ptarget=`pwd`/../test_driver/_e2e.dart +``` + +## Firebase Test Lab + +If this is your first time testing with Firebase Test Lab, you'll need to follow +the guides in the [Firebase test lab +documentation](https://firebase.google.com/docs/test-lab/?gclid=EAIaIQobChMIs5qVwqW25QIV8iCtBh3DrwyUEAAYASAAEgLFU_D_BwE) +to set up a project. + +To run an e2e test on Android devices using Firebase Test Lab, use gradle commands to build an +instrumentation test for Android, after creating `androidTest` as suggested in the last section. + +```bash +pushd android +# flutter build generates files in android/ for building the app +flutter build apk +./gradlew app:assembleAndroidTest +./gradlew app:assembleDebug -Ptarget=.dart +popd +``` + +Upload the build apks Firebase Test Lab, making sure to replace , +, , and with your values. + +```bash +gcloud auth activate-service-account --key-file= +gcloud --quiet config set project +gcloud firebase test android run --type instrumentation \ + --app build/app/outputs/apk/debug/app-debug.apk \ + --test build/app/outputs/apk/androidTest/debug/app-debug-androidTest.apk\ + --timeout 2m \ + --results-bucket= \ + --results-dir= +``` + +You can pass additional parameters on the command line, such as the +devices you want to test on. See +[gcloud firebase test android run](https://cloud.google.com/sdk/gcloud/reference/firebase/test/android/run). + +## iOS device testing + +You need to change `iOS/Podfile` to avoid test target statically linking to the plugins. One way is to +link all of the plugins dynamically: + +``` +target 'Runner' do + use_frameworks! + ... +end +``` + +To e2e test on your iOS device (simulator or real), rebuild your iOS targets with Flutter tool. + +``` +flutter build ios -t test_driver/_e2e.dart (--simulator) +``` + +Open Xcode project (by default, it's `ios/Runner.xcodeproj`). Create a test target +(navigating `File > New > Target...` and set up the values) and a test file `RunnerTests.m` and +change the code. You can change `RunnerTests.m` to the name of your choice. + +```objective-c +#import +#import + +E2E_IOS_RUNNER(RunnerTests) +``` + +Now you can start RunnerTests to kick out e2e tests! diff --git a/packages/e2e/android/.gitignore b/packages/integration_test/android/.gitignore similarity index 100% rename from packages/e2e/android/.gitignore rename to packages/integration_test/android/.gitignore diff --git a/packages/e2e/android/build.gradle b/packages/integration_test/android/build.gradle similarity index 95% rename from packages/e2e/android/build.gradle rename to packages/integration_test/android/build.gradle index d0bb6c5a5967..9f5a3896be0d 100644 --- a/packages/e2e/android/build.gradle +++ b/packages/integration_test/android/build.gradle @@ -1,4 +1,4 @@ -group 'com.example.e2e' +group 'com.example.integration_test' version '1.0-SNAPSHOT' buildscript { diff --git a/packages/e2e/android/gradle.properties b/packages/integration_test/android/gradle.properties similarity index 100% rename from packages/e2e/android/gradle.properties rename to packages/integration_test/android/gradle.properties diff --git a/packages/integration_test/android/settings.gradle b/packages/integration_test/android/settings.gradle new file mode 100644 index 000000000000..1d010945f01e --- /dev/null +++ b/packages/integration_test/android/settings.gradle @@ -0,0 +1 @@ +rootProject.name = 'integrationTest' diff --git a/packages/e2e/android/src/main/AndroidManifest.xml b/packages/integration_test/android/src/main/AndroidManifest.xml similarity index 65% rename from packages/e2e/android/src/main/AndroidManifest.xml rename to packages/integration_test/android/src/main/AndroidManifest.xml index 33fdf86052ab..183e7fcd827c 100644 --- a/packages/e2e/android/src/main/AndroidManifest.xml +++ b/packages/integration_test/android/src/main/AndroidManifest.xml @@ -1,3 +1,3 @@ + package="dev.flutter.integration_test"> diff --git a/packages/e2e/android/src/main/java/dev/flutter/plugins/e2e/FlutterTestRunner.java b/packages/integration_test/android/src/main/java/dev/flutter/plugins/integration_test/FlutterTestRunner.java similarity index 96% rename from packages/e2e/android/src/main/java/dev/flutter/plugins/e2e/FlutterTestRunner.java rename to packages/integration_test/android/src/main/java/dev/flutter/plugins/integration_test/FlutterTestRunner.java index 78f0c3c5bac2..511fc141a917 100644 --- a/packages/e2e/android/src/main/java/dev/flutter/plugins/e2e/FlutterTestRunner.java +++ b/packages/integration_test/android/src/main/java/dev/flutter/plugins/integration_test/FlutterTestRunner.java @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -package dev.flutter.plugins.e2e; +package dev.flutter.plugins.integration_test; import android.util.Log; import androidx.test.rule.ActivityTestRule; @@ -68,7 +68,7 @@ public void run(RunNotifier notifier) { } Map results = null; try { - results = E2EPlugin.testResults.get(); + results = IntegrationTestPlugin.testResults.get(); } catch (ExecutionException | InterruptedException e) { throw new IllegalThreadStateException("Unable to get test results"); } diff --git a/packages/e2e/android/src/main/java/dev/flutter/plugins/e2e/E2EPlugin.java b/packages/integration_test/android/src/main/java/dev/flutter/plugins/integration_test/IntegrationTestPlugin.java similarity index 85% rename from packages/e2e/android/src/main/java/dev/flutter/plugins/e2e/E2EPlugin.java rename to packages/integration_test/android/src/main/java/dev/flutter/plugins/integration_test/IntegrationTestPlugin.java index 31100d442731..2245b33ba4c3 100644 --- a/packages/e2e/android/src/main/java/dev/flutter/plugins/e2e/E2EPlugin.java +++ b/packages/integration_test/android/src/main/java/dev/flutter/plugins/integration_test/IntegrationTestPlugin.java @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -package dev.flutter.plugins.e2e; +package dev.flutter.plugins.integration_test; import android.content.Context; import com.google.common.util.concurrent.SettableFuture; @@ -16,19 +16,19 @@ import java.util.Map; import java.util.concurrent.Future; -/** E2EPlugin */ -public class E2EPlugin implements MethodCallHandler, FlutterPlugin { +/** IntegrationTestPlugin */ +public class IntegrationTestPlugin implements MethodCallHandler, FlutterPlugin { private MethodChannel methodChannel; private static final SettableFuture> testResultsSettable = SettableFuture.create(); public static final Future> testResults = testResultsSettable; - private static final String CHANNEL = "plugins.flutter.io/e2e"; + private static final String CHANNEL = "plugins.flutter.io/integration_test"; /** Plugin registration. */ public static void registerWith(Registrar registrar) { - final E2EPlugin instance = new E2EPlugin(); + final IntegrationTestPlugin instance = new IntegrationTestPlugin(); instance.onAttachedToEngine(registrar.context(), registrar.messenger()); } @@ -38,7 +38,7 @@ public void onAttachedToEngine(FlutterPluginBinding binding) { } private void onAttachedToEngine(Context applicationContext, BinaryMessenger messenger) { - methodChannel = new MethodChannel(messenger, "plugins.flutter.io/e2e"); + methodChannel = new MethodChannel(messenger, "plugins.flutter.io/integration_test"); methodChannel.setMethodCallHandler(this); } diff --git a/packages/e2e/example/.gitignore b/packages/integration_test/example/.gitignore similarity index 100% rename from packages/e2e/example/.gitignore rename to packages/integration_test/example/.gitignore diff --git a/packages/e2e/example/.metadata b/packages/integration_test/example/.metadata similarity index 100% rename from packages/e2e/example/.metadata rename to packages/integration_test/example/.metadata diff --git a/packages/e2e/example/README.md b/packages/integration_test/example/README.md similarity index 100% rename from packages/e2e/example/README.md rename to packages/integration_test/example/README.md diff --git a/packages/e2e/example/android/app/build.gradle b/packages/integration_test/example/android/app/build.gradle similarity index 96% rename from packages/e2e/example/android/app/build.gradle rename to packages/integration_test/example/android/app/build.gradle index 527ed2dd38e0..73bd5f4bc41e 100644 --- a/packages/e2e/example/android/app/build.gradle +++ b/packages/integration_test/example/android/app/build.gradle @@ -33,7 +33,7 @@ android { defaultConfig { // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). - applicationId "com.example.e2e_example" + applicationId "com.example.integration_test_example" minSdkVersion 16 targetSdkVersion 28 versionCode flutterVersionCode.toInteger() diff --git a/packages/e2e/example/android/app/src/androidTest/java/com/example/e2e_example/EmbedderV1ActivityTest.java b/packages/integration_test/example/android/app/src/androidTest/java/com/example/e2e_example/EmbedderV1ActivityTest.java similarity index 73% rename from packages/e2e/example/android/app/src/androidTest/java/com/example/e2e_example/EmbedderV1ActivityTest.java rename to packages/integration_test/example/android/app/src/androidTest/java/com/example/e2e_example/EmbedderV1ActivityTest.java index eedde293eb6c..0ce7dc14d4a5 100644 --- a/packages/e2e/example/android/app/src/androidTest/java/com/example/e2e_example/EmbedderV1ActivityTest.java +++ b/packages/integration_test/example/android/app/src/androidTest/java/com/example/e2e_example/EmbedderV1ActivityTest.java @@ -1,7 +1,7 @@ -package com.example.e2e_example; +package com.example.integration_test_example; import androidx.test.rule.ActivityTestRule; -import dev.flutter.plugins.e2e.FlutterTestRunner; +import dev.flutter.plugins.integration_test.FlutterTestRunner; import org.junit.Rule; import org.junit.runner.RunWith; diff --git a/packages/e2e/example/android/app/src/androidTest/java/com/example/e2e_example/FlutterActivityTest.java b/packages/integration_test/example/android/app/src/androidTest/java/com/example/e2e_example/FlutterActivityTest.java similarity index 76% rename from packages/e2e/example/android/app/src/androidTest/java/com/example/e2e_example/FlutterActivityTest.java rename to packages/integration_test/example/android/app/src/androidTest/java/com/example/e2e_example/FlutterActivityTest.java index 86d552733332..36ae1ddfc7e8 100644 --- a/packages/e2e/example/android/app/src/androidTest/java/com/example/e2e_example/FlutterActivityTest.java +++ b/packages/integration_test/example/android/app/src/androidTest/java/com/example/e2e_example/FlutterActivityTest.java @@ -1,7 +1,7 @@ -package com.example.e2e_example; +package com.example.integration_test_example; import androidx.test.rule.ActivityTestRule; -import dev.flutter.plugins.e2e.FlutterTestRunner; +import dev.flutter.plugins.integration_test.FlutterTestRunner; import io.flutter.embedding.android.FlutterActivity; import org.junit.Rule; import org.junit.runner.RunWith; diff --git a/packages/e2e/example/android/app/src/androidTest/java/com/example/e2e_example/FlutterActivityWithPermissionTest.java b/packages/integration_test/example/android/app/src/androidTest/java/com/example/e2e_example/FlutterActivityWithPermissionTest.java similarity index 66% rename from packages/e2e/example/android/app/src/androidTest/java/com/example/e2e_example/FlutterActivityWithPermissionTest.java rename to packages/integration_test/example/android/app/src/androidTest/java/com/example/e2e_example/FlutterActivityWithPermissionTest.java index 73c3780f4e55..c01d23466fed 100644 --- a/packages/e2e/example/android/app/src/androidTest/java/com/example/e2e_example/FlutterActivityWithPermissionTest.java +++ b/packages/integration_test/example/android/app/src/androidTest/java/com/example/e2e_example/FlutterActivityWithPermissionTest.java @@ -1,16 +1,16 @@ -package com.example.e2e_example; +package com.example.integration_test_example; import android.Manifest.permission; import androidx.test.rule.ActivityTestRule; import androidx.test.rule.GrantPermissionRule; -import dev.flutter.plugins.e2e.FlutterTestRunner; +import dev.flutter.plugins.integration_test.FlutterTestRunner; import io.flutter.embedding.android.FlutterActivity; import org.junit.Rule; import org.junit.runner.RunWith; /** - * Demonstrates how a E2E test on Android can be run with permissions already granted. This is - * helpful if developers want to test native App behavior that depends on certain system service + * Demonstrates how an integration test on Android can be run with permissions already granted. This + * is helpful if developers want to test native App behavior that depends on certain system service * results which are guarded with permissions. */ @RunWith(FlutterTestRunner.class) diff --git a/packages/e2e/example/android/app/src/profile/AndroidManifest.xml b/packages/integration_test/example/android/app/src/debug/AndroidManifest.xml similarity index 84% rename from packages/e2e/example/android/app/src/profile/AndroidManifest.xml rename to packages/integration_test/example/android/app/src/debug/AndroidManifest.xml index 5d4aea26b1dd..04d0fdb2c153 100644 --- a/packages/e2e/example/android/app/src/profile/AndroidManifest.xml +++ b/packages/integration_test/example/android/app/src/debug/AndroidManifest.xml @@ -1,5 +1,5 @@ + package="com.example.integration_test_example"> diff --git a/packages/e2e/example/android/app/src/main/AndroidManifest.xml b/packages/integration_test/example/android/app/src/main/AndroidManifest.xml similarity index 94% rename from packages/e2e/example/android/app/src/main/AndroidManifest.xml rename to packages/integration_test/example/android/app/src/main/AndroidManifest.xml index 4710b796c0f5..d789e0e15faf 100644 --- a/packages/e2e/example/android/app/src/main/AndroidManifest.xml +++ b/packages/integration_test/example/android/app/src/main/AndroidManifest.xml @@ -1,5 +1,5 @@ + package="com.example.integration_test_example"> + package="com.example.integration_test_example"> diff --git a/packages/e2e/example/android/build.gradle b/packages/integration_test/example/android/build.gradle similarity index 100% rename from packages/e2e/example/android/build.gradle rename to packages/integration_test/example/android/build.gradle diff --git a/packages/e2e/example/android/gradle.properties b/packages/integration_test/example/android/gradle.properties similarity index 100% rename from packages/e2e/example/android/gradle.properties rename to packages/integration_test/example/android/gradle.properties diff --git a/packages/e2e/example/android/gradle/wrapper/gradle-wrapper.properties b/packages/integration_test/example/android/gradle/wrapper/gradle-wrapper.properties similarity index 100% rename from packages/e2e/example/android/gradle/wrapper/gradle-wrapper.properties rename to packages/integration_test/example/android/gradle/wrapper/gradle-wrapper.properties diff --git a/packages/e2e/example/android/settings.gradle b/packages/integration_test/example/android/settings.gradle similarity index 100% rename from packages/e2e/example/android/settings.gradle rename to packages/integration_test/example/android/settings.gradle diff --git a/packages/e2e/example/ios/Flutter/AppFrameworkInfo.plist b/packages/integration_test/example/ios/Flutter/AppFrameworkInfo.plist similarity index 100% rename from packages/e2e/example/ios/Flutter/AppFrameworkInfo.plist rename to packages/integration_test/example/ios/Flutter/AppFrameworkInfo.plist diff --git a/packages/e2e/example/ios/Flutter/Debug.xcconfig b/packages/integration_test/example/ios/Flutter/Debug.xcconfig similarity index 100% rename from packages/e2e/example/ios/Flutter/Debug.xcconfig rename to packages/integration_test/example/ios/Flutter/Debug.xcconfig diff --git a/packages/e2e/example/ios/Flutter/Release.xcconfig b/packages/integration_test/example/ios/Flutter/Release.xcconfig similarity index 100% rename from packages/e2e/example/ios/Flutter/Release.xcconfig rename to packages/integration_test/example/ios/Flutter/Release.xcconfig diff --git a/packages/e2e/example/ios/Runner.xcodeproj/project.pbxproj b/packages/integration_test/example/ios/Runner.xcodeproj/project.pbxproj similarity index 100% rename from packages/e2e/example/ios/Runner.xcodeproj/project.pbxproj rename to packages/integration_test/example/ios/Runner.xcodeproj/project.pbxproj diff --git a/packages/e2e/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/packages/integration_test/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme similarity index 100% rename from packages/e2e/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme rename to packages/integration_test/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme diff --git a/packages/e2e/example/ios/Runner/AppDelegate.h b/packages/integration_test/example/ios/Runner/AppDelegate.h similarity index 100% rename from packages/e2e/example/ios/Runner/AppDelegate.h rename to packages/integration_test/example/ios/Runner/AppDelegate.h diff --git a/packages/e2e/example/ios/Runner/AppDelegate.m b/packages/integration_test/example/ios/Runner/AppDelegate.m similarity index 100% rename from packages/e2e/example/ios/Runner/AppDelegate.m rename to packages/integration_test/example/ios/Runner/AppDelegate.m diff --git a/packages/e2e/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/packages/integration_test/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json similarity index 100% rename from packages/e2e/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json rename to packages/integration_test/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json diff --git a/packages/e2e/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/packages/integration_test/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png similarity index 100% rename from packages/e2e/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png rename to packages/integration_test/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png diff --git a/packages/e2e/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/packages/integration_test/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png similarity index 100% rename from packages/e2e/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png rename to packages/integration_test/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png diff --git a/packages/e2e/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/packages/integration_test/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png similarity index 100% rename from packages/e2e/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png rename to packages/integration_test/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png diff --git a/packages/e2e/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/packages/integration_test/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png similarity index 100% rename from packages/e2e/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png rename to packages/integration_test/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png diff --git a/packages/e2e/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/packages/integration_test/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png similarity index 100% rename from packages/e2e/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png rename to packages/integration_test/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png diff --git a/packages/e2e/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/packages/integration_test/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png similarity index 100% rename from packages/e2e/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png rename to packages/integration_test/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png diff --git a/packages/e2e/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/packages/integration_test/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png similarity index 100% rename from packages/e2e/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png rename to packages/integration_test/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png diff --git a/packages/e2e/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/packages/integration_test/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png similarity index 100% rename from packages/e2e/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png rename to packages/integration_test/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png diff --git a/packages/e2e/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/packages/integration_test/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png similarity index 100% rename from packages/e2e/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png rename to packages/integration_test/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png diff --git a/packages/e2e/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/packages/integration_test/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png similarity index 100% rename from packages/e2e/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png rename to packages/integration_test/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png diff --git a/packages/e2e/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/packages/integration_test/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png similarity index 100% rename from packages/e2e/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png rename to packages/integration_test/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png diff --git a/packages/e2e/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/packages/integration_test/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png similarity index 100% rename from packages/e2e/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png rename to packages/integration_test/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png diff --git a/packages/e2e/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/packages/integration_test/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png similarity index 100% rename from packages/e2e/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png rename to packages/integration_test/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png diff --git a/packages/e2e/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/packages/integration_test/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png similarity index 100% rename from packages/e2e/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png rename to packages/integration_test/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png diff --git a/packages/e2e/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/packages/integration_test/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png similarity index 100% rename from packages/e2e/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png rename to packages/integration_test/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png diff --git a/packages/e2e/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json b/packages/integration_test/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json similarity index 100% rename from packages/e2e/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json rename to packages/integration_test/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json diff --git a/packages/e2e/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png b/packages/integration_test/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png similarity index 100% rename from packages/e2e/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png rename to packages/integration_test/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png diff --git a/packages/e2e/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/packages/integration_test/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png similarity index 100% rename from packages/e2e/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png rename to packages/integration_test/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png diff --git a/packages/e2e/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/packages/integration_test/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png similarity index 100% rename from packages/e2e/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png rename to packages/integration_test/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png diff --git a/packages/e2e/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/packages/integration_test/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md similarity index 100% rename from packages/e2e/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md rename to packages/integration_test/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md diff --git a/packages/e2e/example/ios/Runner/Base.lproj/LaunchScreen.storyboard b/packages/integration_test/example/ios/Runner/Base.lproj/LaunchScreen.storyboard similarity index 100% rename from packages/e2e/example/ios/Runner/Base.lproj/LaunchScreen.storyboard rename to packages/integration_test/example/ios/Runner/Base.lproj/LaunchScreen.storyboard diff --git a/packages/e2e/example/ios/Runner/Base.lproj/Main.storyboard b/packages/integration_test/example/ios/Runner/Base.lproj/Main.storyboard similarity index 100% rename from packages/e2e/example/ios/Runner/Base.lproj/Main.storyboard rename to packages/integration_test/example/ios/Runner/Base.lproj/Main.storyboard diff --git a/packages/e2e/example/ios/Runner/Info.plist b/packages/integration_test/example/ios/Runner/Info.plist similarity index 97% rename from packages/e2e/example/ios/Runner/Info.plist rename to packages/integration_test/example/ios/Runner/Info.plist index 62f6fbb5c02c..d0e099be56e7 100644 --- a/packages/e2e/example/ios/Runner/Info.plist +++ b/packages/integration_test/example/ios/Runner/Info.plist @@ -11,7 +11,7 @@ CFBundleInfoDictionaryVersion 6.0 CFBundleName - e2e_example + integration_test_example CFBundlePackageType APPL CFBundleShortVersionString diff --git a/packages/e2e/example/ios/Runner/main.m b/packages/integration_test/example/ios/Runner/main.m similarity index 100% rename from packages/e2e/example/ios/Runner/main.m rename to packages/integration_test/example/ios/Runner/main.m diff --git a/packages/e2e/example/ios/RunnerTests/Info.plist b/packages/integration_test/example/ios/RunnerTests/Info.plist similarity index 100% rename from packages/e2e/example/ios/RunnerTests/Info.plist rename to packages/integration_test/example/ios/RunnerTests/Info.plist diff --git a/packages/integration_test/example/ios/RunnerTests/RunnerTests.m b/packages/integration_test/example/ios/RunnerTests/RunnerTests.m new file mode 100644 index 000000000000..ac89c60e5f06 --- /dev/null +++ b/packages/integration_test/example/ios/RunnerTests/RunnerTests.m @@ -0,0 +1,4 @@ +#import +#import + +INTEGRATION_TEST_IOS_RUNNER(RunnerTests) diff --git a/packages/e2e/example/lib/main.dart b/packages/integration_test/example/lib/main.dart similarity index 100% rename from packages/e2e/example/lib/main.dart rename to packages/integration_test/example/lib/main.dart diff --git a/packages/e2e/example/lib/my_app.dart b/packages/integration_test/example/lib/my_app.dart similarity index 100% rename from packages/e2e/example/lib/my_app.dart rename to packages/integration_test/example/lib/my_app.dart diff --git a/packages/e2e/example/lib/my_web_app.dart b/packages/integration_test/example/lib/my_web_app.dart similarity index 100% rename from packages/e2e/example/lib/my_web_app.dart rename to packages/integration_test/example/lib/my_web_app.dart diff --git a/packages/e2e/example/macos/Flutter/Flutter-Debug.xcconfig b/packages/integration_test/example/macos/Flutter/Flutter-Debug.xcconfig similarity index 100% rename from packages/e2e/example/macos/Flutter/Flutter-Debug.xcconfig rename to packages/integration_test/example/macos/Flutter/Flutter-Debug.xcconfig diff --git a/packages/e2e/example/macos/Flutter/Flutter-Release.xcconfig b/packages/integration_test/example/macos/Flutter/Flutter-Release.xcconfig similarity index 100% rename from packages/e2e/example/macos/Flutter/Flutter-Release.xcconfig rename to packages/integration_test/example/macos/Flutter/Flutter-Release.xcconfig diff --git a/packages/e2e/example/macos/Runner.xcodeproj/project.pbxproj b/packages/integration_test/example/macos/Runner.xcodeproj/project.pbxproj similarity index 98% rename from packages/e2e/example/macos/Runner.xcodeproj/project.pbxproj rename to packages/integration_test/example/macos/Runner.xcodeproj/project.pbxproj index 73b46daf7715..718462e3b4c5 100644 --- a/packages/e2e/example/macos/Runner.xcodeproj/project.pbxproj +++ b/packages/integration_test/example/macos/Runner.xcodeproj/project.pbxproj @@ -62,7 +62,7 @@ 2A162B3576CC7562C04C8319 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; 333000ED22D3DE5D00554162 /* Warnings.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Warnings.xcconfig; sourceTree = ""; }; 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GeneratedPluginRegistrant.swift; sourceTree = ""; }; - 33CC10ED2044A3C60003C045 /* e2e_example_example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = e2e_example_example.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 33CC10ED2044A3C60003C045 /* integration_test_example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = integration_test_example.app; sourceTree = BUILT_PRODUCTS_DIR; }; 33CC10F02044A3C60003C045 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 33CC10F22044A3C60003C045 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = Runner/Assets.xcassets; sourceTree = ""; }; 33CC10F52044A3C60003C045 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = ""; }; @@ -132,7 +132,7 @@ 33CC10EE2044A3C60003C045 /* Products */ = { isa = PBXGroup; children = ( - 33CC10ED2044A3C60003C045 /* e2e_example_example.app */, + 33CC10ED2044A3C60003C045 /* integration_test_example.app */, ); name = Products; sourceTree = ""; @@ -204,7 +204,7 @@ ); name = Runner; productName = Runner; - productReference = 33CC10ED2044A3C60003C045 /* e2e_example_example.app */; + productReference = 33CC10ED2044A3C60003C045 /* integration_test_example.app */; productType = "com.apple.product-type.application"; }; /* End PBXNativeTarget section */ diff --git a/packages/e2e/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/packages/integration_test/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme similarity index 93% rename from packages/e2e/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme rename to packages/integration_test/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index b0cc6c6e2166..464e05225e4c 100644 --- a/packages/e2e/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/packages/integration_test/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -15,7 +15,7 @@ @@ -43,7 +43,7 @@ @@ -66,7 +66,7 @@ @@ -85,7 +85,7 @@ diff --git a/packages/e2e/example/macos/Runner.xcworkspace/contents.xcworkspacedata b/packages/integration_test/example/macos/Runner.xcworkspace/contents.xcworkspacedata similarity index 100% rename from packages/e2e/example/macos/Runner.xcworkspace/contents.xcworkspacedata rename to packages/integration_test/example/macos/Runner.xcworkspace/contents.xcworkspacedata diff --git a/packages/e2e/example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/packages/integration_test/example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist similarity index 100% rename from packages/e2e/example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist rename to packages/integration_test/example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist diff --git a/packages/e2e/example/macos/Runner/AppDelegate.swift b/packages/integration_test/example/macos/Runner/AppDelegate.swift similarity index 100% rename from packages/e2e/example/macos/Runner/AppDelegate.swift rename to packages/integration_test/example/macos/Runner/AppDelegate.swift diff --git a/packages/e2e/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/packages/integration_test/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json similarity index 100% rename from packages/e2e/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json rename to packages/integration_test/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json diff --git a/packages/e2e/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png b/packages/integration_test/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png similarity index 100% rename from packages/e2e/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png rename to packages/integration_test/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png diff --git a/packages/e2e/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png b/packages/integration_test/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png similarity index 100% rename from packages/e2e/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png rename to packages/integration_test/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png diff --git a/packages/e2e/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png b/packages/integration_test/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png similarity index 100% rename from packages/e2e/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png rename to packages/integration_test/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png diff --git a/packages/e2e/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png b/packages/integration_test/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png similarity index 100% rename from packages/e2e/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png rename to packages/integration_test/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png diff --git a/packages/e2e/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png b/packages/integration_test/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png similarity index 100% rename from packages/e2e/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png rename to packages/integration_test/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png diff --git a/packages/e2e/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png b/packages/integration_test/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png similarity index 100% rename from packages/e2e/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png rename to packages/integration_test/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png diff --git a/packages/e2e/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png b/packages/integration_test/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png similarity index 100% rename from packages/e2e/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png rename to packages/integration_test/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png diff --git a/packages/e2e/example/macos/Runner/Base.lproj/MainMenu.xib b/packages/integration_test/example/macos/Runner/Base.lproj/MainMenu.xib similarity index 100% rename from packages/e2e/example/macos/Runner/Base.lproj/MainMenu.xib rename to packages/integration_test/example/macos/Runner/Base.lproj/MainMenu.xib diff --git a/packages/e2e/example/macos/Runner/Configs/AppInfo.xcconfig b/packages/integration_test/example/macos/Runner/Configs/AppInfo.xcconfig similarity index 83% rename from packages/e2e/example/macos/Runner/Configs/AppInfo.xcconfig rename to packages/integration_test/example/macos/Runner/Configs/AppInfo.xcconfig index 8a3359f80a49..1d9e2f0e043c 100644 --- a/packages/e2e/example/macos/Runner/Configs/AppInfo.xcconfig +++ b/packages/integration_test/example/macos/Runner/Configs/AppInfo.xcconfig @@ -5,10 +5,10 @@ // 'flutter create' template. // The application's name. By default this is also the title of the Flutter window. -PRODUCT_NAME = e2e_example_example +PRODUCT_NAME = integration_test_example // The application's bundle identifier -PRODUCT_BUNDLE_IDENTIFIER = com.example.e2eExample +PRODUCT_BUNDLE_IDENTIFIER = com.example.integrationTestExample // The copyright displayed in application information PRODUCT_COPYRIGHT = Copyright © 2019 com.example. All rights reserved. diff --git a/packages/e2e/example/macos/Runner/Configs/Debug.xcconfig b/packages/integration_test/example/macos/Runner/Configs/Debug.xcconfig similarity index 100% rename from packages/e2e/example/macos/Runner/Configs/Debug.xcconfig rename to packages/integration_test/example/macos/Runner/Configs/Debug.xcconfig diff --git a/packages/e2e/example/macos/Runner/Configs/Release.xcconfig b/packages/integration_test/example/macos/Runner/Configs/Release.xcconfig similarity index 100% rename from packages/e2e/example/macos/Runner/Configs/Release.xcconfig rename to packages/integration_test/example/macos/Runner/Configs/Release.xcconfig diff --git a/packages/e2e/example/macos/Runner/Configs/Warnings.xcconfig b/packages/integration_test/example/macos/Runner/Configs/Warnings.xcconfig similarity index 100% rename from packages/e2e/example/macos/Runner/Configs/Warnings.xcconfig rename to packages/integration_test/example/macos/Runner/Configs/Warnings.xcconfig diff --git a/packages/e2e/example/macos/Runner/DebugProfile.entitlements b/packages/integration_test/example/macos/Runner/DebugProfile.entitlements similarity index 100% rename from packages/e2e/example/macos/Runner/DebugProfile.entitlements rename to packages/integration_test/example/macos/Runner/DebugProfile.entitlements diff --git a/packages/e2e/example/macos/Runner/Info.plist b/packages/integration_test/example/macos/Runner/Info.plist similarity index 100% rename from packages/e2e/example/macos/Runner/Info.plist rename to packages/integration_test/example/macos/Runner/Info.plist diff --git a/packages/e2e/example/macos/Runner/MainFlutterWindow.swift b/packages/integration_test/example/macos/Runner/MainFlutterWindow.swift similarity index 100% rename from packages/e2e/example/macos/Runner/MainFlutterWindow.swift rename to packages/integration_test/example/macos/Runner/MainFlutterWindow.swift diff --git a/packages/e2e/example/macos/Runner/Release.entitlements b/packages/integration_test/example/macos/Runner/Release.entitlements similarity index 100% rename from packages/e2e/example/macos/Runner/Release.entitlements rename to packages/integration_test/example/macos/Runner/Release.entitlements diff --git a/packages/e2e/example/pubspec.yaml b/packages/integration_test/example/pubspec.yaml similarity index 71% rename from packages/e2e/example/pubspec.yaml rename to packages/integration_test/example/pubspec.yaml index 9ef6098477e3..9384e9763935 100644 --- a/packages/e2e/example/pubspec.yaml +++ b/packages/integration_test/example/pubspec.yaml @@ -1,5 +1,5 @@ -name: e2e_example -description: Demonstrates how to use the e2e plugin. +name: integration_test_example +description: Demonstrates how to use the integration_test plugin. publish_to: 'none' environment: @@ -17,10 +17,10 @@ dev_dependencies: sdk: flutter flutter_driver: sdk: flutter - e2e: + integration_test: path: ../ - e2e_macos: - path: ../e2e_macos + integration_test_macos: + path: ../integration_test_macos test: any pedantic: ^1.8.0 diff --git a/packages/e2e/example/test_driver/example_e2e.dart b/packages/integration_test/example/test_driver/example_integration.dart similarity index 63% rename from packages/e2e/example/test_driver/example_e2e.dart rename to packages/integration_test/example/test_driver/example_integration.dart index d97702d5d7cf..3ee993b911b9 100644 --- a/packages/e2e/example/test_driver/example_e2e.dart +++ b/packages/integration_test/example/test_driver/example_integration.dart @@ -5,12 +5,12 @@ // gestures. You can also use WidgetTester to find child widgets in the widget // tree, read text, and verify that the values of widget properties are correct. -import 'package:e2e/e2e.dart'; +import 'package:integration_test/integration_test.dart'; -import 'example_e2e_io.dart' if (dart.library.html) 'example_e2e_web.dart' - as tests; +import 'example_integration_io.dart' + if (dart.library.html) 'example_integration_web.dart' as tests; void main() { - E2EWidgetsFlutterBinding.ensureInitialized(); + IntegrationTestWidgetsFlutterBinding.ensureInitialized(); tests.main(); } diff --git a/packages/e2e/example/test_driver/example_e2e_io.dart b/packages/integration_test/example/test_driver/example_integration_io.dart similarity index 84% rename from packages/e2e/example/test_driver/example_e2e_io.dart rename to packages/integration_test/example/test_driver/example_integration_io.dart index 9766f568b654..35fc7271d841 100644 --- a/packages/e2e/example/test_driver/example_e2e_io.dart +++ b/packages/integration_test/example/test_driver/example_integration_io.dart @@ -8,12 +8,12 @@ import 'dart:io' show Platform; import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:e2e/e2e.dart'; +import 'package:integration_test/integration_test.dart'; -import 'package:e2e_example/main.dart' as app; +import 'package:integration_test_example/main.dart' as app; void main() { - E2EWidgetsFlutterBinding.ensureInitialized(); + IntegrationTestWidgetsFlutterBinding.ensureInitialized(); testWidgets('verify text', (WidgetTester tester) async { // Build our app and trigger a frame. app.main(); diff --git a/packages/integration_test/example/test_driver/example_integration_test.dart b/packages/integration_test/example/test_driver/example_integration_test.dart new file mode 100644 index 000000000000..10acaa69a42e --- /dev/null +++ b/packages/integration_test/example/test_driver/example_integration_test.dart @@ -0,0 +1,5 @@ +import 'dart:async'; + +import 'package:integration_test/integration_test_driver.dart'; + +Future main() async => integrationDriver(); diff --git a/packages/e2e/example/test_driver/example_e2e_web.dart b/packages/integration_test/example/test_driver/example_integration_web.dart similarity index 84% rename from packages/e2e/example/test_driver/example_e2e_web.dart rename to packages/integration_test/example/test_driver/example_integration_web.dart index 24c3f2cbb2a4..e1141cc010c8 100644 --- a/packages/e2e/example/test_driver/example_e2e_web.dart +++ b/packages/integration_test/example/test_driver/example_integration_web.dart @@ -8,12 +8,12 @@ import 'dart:html' as html; import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:e2e/e2e.dart'; +import 'package:integration_test/integration_test.dart'; -import 'package:e2e_example/main.dart' as app; +import 'package:integration_test_example/main.dart' as app; void main() { - E2EWidgetsFlutterBinding.ensureInitialized(); + IntegrationTestWidgetsFlutterBinding.ensureInitialized(); testWidgets('verify text', (WidgetTester tester) async { // Build our app and trigger a frame. app.main(); diff --git a/packages/e2e/example/test_driver/failure.dart b/packages/integration_test/example/test_driver/failure.dart similarity index 79% rename from packages/e2e/example/test_driver/failure.dart rename to packages/integration_test/example/test_driver/failure.dart index ddeeb800bb06..ffb569f75fbb 100644 --- a/packages/e2e/example/test_driver/failure.dart +++ b/packages/integration_test/example/test_driver/failure.dart @@ -4,16 +4,16 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:e2e/e2e.dart'; +import 'package:integration_test/integration_test.dart'; -import 'package:e2e_example/main.dart' as app; +import 'package:integration_test_example/main.dart' as app; -// Tests the failure behavior of the E2EWidgetsFlutterBinding +// Tests the failure behavior of the IntegrationTestWidgetsFlutterBinding // // This test fails intentionally! It should be run using a test runner that // expects failure. void main() { - E2EWidgetsFlutterBinding.ensureInitialized(); + IntegrationTestWidgetsFlutterBinding.ensureInitialized(); testWidgets('success', (WidgetTester tester) async { expect(1 + 1, 2); // This should pass diff --git a/packages/e2e/example/test_driver/failure_test.dart b/packages/integration_test/example/test_driver/failure_test.dart similarity index 89% rename from packages/e2e/example/test_driver/failure_test.dart rename to packages/integration_test/example/test_driver/failure_test.dart index a828df6242d7..bd9302f39409 100644 --- a/packages/e2e/example/test_driver/failure_test.dart +++ b/packages/integration_test/example/test_driver/failure_test.dart @@ -1,6 +1,6 @@ import 'dart:async'; -import 'package:e2e/common.dart' as common; +import 'package:integration_test/common.dart' as common; import 'package:flutter_driver/flutter_driver.dart'; import 'package:test/test.dart'; diff --git a/packages/e2e/example/web/favicon.png b/packages/integration_test/example/web/favicon.png similarity index 100% rename from packages/e2e/example/web/favicon.png rename to packages/integration_test/example/web/favicon.png diff --git a/packages/e2e/example/web/icons/Icon-192.png b/packages/integration_test/example/web/icons/Icon-192.png similarity index 100% rename from packages/e2e/example/web/icons/Icon-192.png rename to packages/integration_test/example/web/icons/Icon-192.png diff --git a/packages/e2e/example/web/icons/Icon-512.png b/packages/integration_test/example/web/icons/Icon-512.png similarity index 100% rename from packages/e2e/example/web/icons/Icon-512.png rename to packages/integration_test/example/web/icons/Icon-512.png diff --git a/packages/e2e/example/web/index.html b/packages/integration_test/example/web/index.html similarity index 100% rename from packages/e2e/example/web/index.html rename to packages/integration_test/example/web/index.html diff --git a/packages/e2e/example/web/manifest.json b/packages/integration_test/example/web/manifest.json similarity index 100% rename from packages/e2e/example/web/manifest.json rename to packages/integration_test/example/web/manifest.json diff --git a/packages/e2e/e2e_macos/CHANGELOG.md b/packages/integration_test/integration_test_macos/CHANGELOG.md similarity index 59% rename from packages/e2e/e2e_macos/CHANGELOG.md rename to packages/integration_test/integration_test_macos/CHANGELOG.md index a49173cad15e..ab4bac1a3f3f 100644 --- a/packages/e2e/e2e_macos/CHANGELOG.md +++ b/packages/integration_test/integration_test_macos/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.0.2 + +* Renames package to integration_test_macos. + ## 0.0.1+1 * Remove Android folder from `e2e_macos`. diff --git a/packages/e2e/e2e_macos/LICENSE b/packages/integration_test/integration_test_macos/LICENSE similarity index 100% rename from packages/e2e/e2e_macos/LICENSE rename to packages/integration_test/integration_test_macos/LICENSE diff --git a/packages/e2e/e2e_macos/ios/e2e_macos.podspec b/packages/integration_test/integration_test_macos/ios/integration_test_macos.podspec similarity index 68% rename from packages/e2e/e2e_macos/ios/e2e_macos.podspec rename to packages/integration_test/integration_test_macos/ios/integration_test_macos.podspec index 561933b15d08..7294590a6479 100644 --- a/packages/e2e/e2e_macos/ios/e2e_macos.podspec +++ b/packages/integration_test/integration_test_macos/ios/integration_test_macos.podspec @@ -2,14 +2,14 @@ # To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html # Pod::Spec.new do |s| - s.name = 'e2e_macos' + s.name = 'IntegrationTestMacOS' s.version = '0.0.1' - s.summary = 'No-op implementation of the e2e desktop plugin to avoid build issues on iOS' + s.summary = 'No-op implementation of the integration_test desktop plugin to avoid build issues on iOS' s.description = <<-DESC - No-op implementation of e2e to avoid build issues on iOS. + No-op implementation of integration to avoid build issues on iOS. See https://github.com/flutter/flutter/issues/39659 DESC - s.homepage = 'https://github.com/flutter/plugins/tree/master/packages/e2e/e2e_macos' + s.homepage = 'https://github.com/flutter/plugins/tree/master/packages/integration_test/integration_test_macos' s.license = { :file => '../LICENSE' } s.author = { 'Flutter Team' => 'flutter-dev@googlegroups.com' } s.source = { :path => '.' } diff --git a/packages/e2e/e2e_macos/macos/Assets/.gitkeep b/packages/integration_test/integration_test_macos/macos/Assets/.gitkeep similarity index 100% rename from packages/e2e/e2e_macos/macos/Assets/.gitkeep rename to packages/integration_test/integration_test_macos/macos/Assets/.gitkeep diff --git a/packages/e2e/e2e_macos/macos/Classes/E2EPlugin.swift b/packages/integration_test/integration_test_macos/macos/Classes/IntegrationTestPlugin.swift similarity index 75% rename from packages/e2e/e2e_macos/macos/Classes/E2EPlugin.swift rename to packages/integration_test/integration_test_macos/macos/Classes/IntegrationTestPlugin.swift index c3a80a9bcdbd..b4eb5fc410d5 100644 --- a/packages/e2e/e2e_macos/macos/Classes/E2EPlugin.swift +++ b/packages/integration_test/integration_test_macos/macos/Classes/IntegrationTestPlugin.swift @@ -1,13 +1,13 @@ import FlutterMacOS -public class E2EPlugin: NSObject, FlutterPlugin { +public class IntegrationTestPlugin: NSObject, FlutterPlugin { public static func register(with registrar: FlutterPluginRegistrar) { let channel = FlutterMethodChannel( - name: "plugins.flutter.io/e2e", + name: "plugins.flutter.io/integration_test", binaryMessenger: registrar.messenger) - let instance = E2EPlugin() + let instance = IntegrationTestPlugin() registrar.addMethodCallDelegate(instance, channel: channel) } diff --git a/packages/e2e/e2e_macos/macos/e2e_macos.podspec b/packages/integration_test/integration_test_macos/macos/integration_test_macos.podspec similarity index 77% rename from packages/e2e/e2e_macos/macos/e2e_macos.podspec rename to packages/integration_test/integration_test_macos/macos/integration_test_macos.podspec index c92addd8ba07..74bf66321319 100644 --- a/packages/e2e/e2e_macos/macos/e2e_macos.podspec +++ b/packages/integration_test/integration_test_macos/macos/integration_test_macos.podspec @@ -2,16 +2,16 @@ # To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html # Pod::Spec.new do |s| - s.name = 'e2e_macos' + s.name = 'IntegrationTestMacOS' s.version = '0.0.1' - s.summary = 'Adapter for e2e tests.' + s.summary = 'Adapter for integration tests.' s.description = <<-DESC Runs tests that use the flutter_test API as integration tests on macOS. DESC - s.homepage = 'https://github.com/flutter/plugins/tree/master/packages/e2e/e2e_macos' + s.homepage = 'https://github.com/flutter/plugins/tree/master/packages/integration_test/integration_test_macos' s.license = { :type => 'BSD', :file => '../LICENSE' } s.author = { 'Flutter Team' => 'flutter-dev@googlegroups.com' } - s.source = { :http => 'https://github.com/flutter/plugins/tree/master/packages/e2e' } + s.source = { :http => 'https://github.com/flutter/plugins/tree/master/packages/integration_test' } s.source_files = 'Classes/**/*' s.dependency 'FlutterMacOS' diff --git a/packages/e2e/e2e_macos/pubspec.yaml b/packages/integration_test/integration_test_macos/pubspec.yaml similarity index 62% rename from packages/e2e/e2e_macos/pubspec.yaml rename to packages/integration_test/integration_test_macos/pubspec.yaml index e026f32d3b0c..46510e32b94a 100644 --- a/packages/e2e/e2e_macos/pubspec.yaml +++ b/packages/integration_test/integration_test_macos/pubspec.yaml @@ -1,14 +1,14 @@ -name: e2e_macos -description: Desktop implementation of e2e plugin +name: integration_test_macos +description: Desktop implementation of integration_test plugin version: 0.0.1+1 author: Flutter Team -homepage: https://github.com/flutter/plugins/tree/master/packages/e2e/e2e_macos +homepage: https://github.com/flutter/plugins/tree/master/packages/integration_test/integration_test_macos flutter: plugin: platforms: macos: - pluginClass: E2EPlugin + pluginClass: IntegrationTestPlugin environment: sdk: ">=2.1.0 <3.0.0" diff --git a/packages/e2e/ios/.gitignore b/packages/integration_test/ios/.gitignore similarity index 100% rename from packages/e2e/ios/.gitignore rename to packages/integration_test/ios/.gitignore diff --git a/packages/e2e/ios/Assets/.gitkeep b/packages/integration_test/ios/Assets/.gitkeep similarity index 100% rename from packages/e2e/ios/Assets/.gitkeep rename to packages/integration_test/ios/Assets/.gitkeep diff --git a/packages/integration_test/ios/Classes/IntegrationTestIosTest.h b/packages/integration_test/ios/Classes/IntegrationTestIosTest.h new file mode 100644 index 000000000000..9c53edb160e9 --- /dev/null +++ b/packages/integration_test/ios/Classes/IntegrationTestIosTest.h @@ -0,0 +1,22 @@ +#import + +@interface IntegrationTestIosTest : NSObject + +- (BOOL)testIntegrationTest:(NSString **)testResult; + +@end + +#define INTEGRATION_TEST_IOS_RUNNER(__test_class) \ + @interface __test_class : XCTestCase \ + @end \ + \ + @implementation __test_class \ + \ + -(void)testIntegrationTest { \ + NSString *testResult; \ + IntegrationTestIosTest *integrationTestIosTest = [[IntegrationTestIosTest alloc] init]; \ + BOOL testPass = [integrationTestIosTest testIntegrationTest:&testResult]; \ + XCTAssertTrue(testPass, @"%@", testResult); \ + } \ + \ + @end diff --git a/packages/e2e/ios/Classes/E2EIosTest.m b/packages/integration_test/ios/Classes/IntegrationTestIosTest.m similarity index 69% rename from packages/e2e/ios/Classes/E2EIosTest.m rename to packages/integration_test/ios/Classes/IntegrationTestIosTest.m index b788780d87e7..4243cdd86bc0 100644 --- a/packages/e2e/ios/Classes/E2EIosTest.m +++ b/packages/integration_test/ios/Classes/IntegrationTestIosTest.m @@ -1,10 +1,10 @@ -#import "E2EIosTest.h" -#import "E2EPlugin.h" +#import "IntegrationTestIosTest.h" +#import "IntegrationTestPlugin.h" -@implementation E2EIosTest +@implementation IntegrationTestIosTest -- (BOOL)testE2E:(NSString **)testResult { - E2EPlugin *e2ePlugin = [E2EPlugin instance]; +- (BOOL)testIntegrationTest:(NSString **)testResult { + IntegrationTestPlugin *integrationTestPlugin = [IntegrationTestPlugin instance]; UIViewController *rootViewController = [[[[UIApplication sharedApplication] delegate] window] rootViewController]; if (![rootViewController isKindOfClass:[FlutterViewController class]]) { @@ -12,11 +12,11 @@ - (BOOL)testE2E:(NSString **)testResult { return NO; } FlutterViewController *flutterViewController = (FlutterViewController *)rootViewController; - [e2ePlugin setupChannels:flutterViewController.engine.binaryMessenger]; - while (!e2ePlugin.testResults) { + [integrationTestPlugin setupChannels:flutterViewController.engine.binaryMessenger]; + while (!integrationTestPlugin.testResults) { CFRunLoopRunInMode(kCFRunLoopDefaultMode, 1.f, NO); } - NSDictionary *testResults = e2ePlugin.testResults; + NSDictionary *testResults = integrationTestPlugin.testResults; NSMutableArray *passedTests = [NSMutableArray array]; NSMutableArray *failedTests = [NSMutableArray array]; NSLog(@"==================== Test Results ====================="); @@ -34,7 +34,7 @@ - (BOOL)testE2E:(NSString **)testResult { BOOL testPass = failedTests.count == 0; if (!testPass && testResult) { *testResult = - [NSString stringWithFormat:@"Detected failed E2E test(s) %@ among %@", + [NSString stringWithFormat:@"Detected failed integration test(s) %@ among %@", failedTests.description, testResults.allKeys.description]; } return testPass; diff --git a/packages/e2e/ios/Classes/E2EPlugin.h b/packages/integration_test/ios/Classes/IntegrationTestPlugin.h similarity index 63% rename from packages/e2e/ios/Classes/E2EPlugin.h rename to packages/integration_test/ios/Classes/IntegrationTestPlugin.h index e1a99f1b5a8e..8dd3109ffe09 100644 --- a/packages/e2e/ios/Classes/E2EPlugin.h +++ b/packages/integration_test/ios/Classes/IntegrationTestPlugin.h @@ -2,17 +2,19 @@ NS_ASSUME_NONNULL_BEGIN -/** A Flutter plugin that's responsible for communicating the test results back to iOS XCTest. */ -@interface E2EPlugin : NSObject +/** A Flutter plugin that's responsible for communicating the test results back + * to iOS XCTest. */ +@interface IntegrationTestPlugin : NSObject /** - * Test results that are sent from Dart when E2E test completes. Before the completion, it is + * Test results that are sent from Dart when integration test completes. Before the + * completion, it is * @c nil. */ @property(nonatomic, readonly, nullable) NSDictionary *testResults; /** Fetches the singleton instance of the plugin. */ -+ (E2EPlugin *)instance; ++ (IntegrationTestPlugin *)instance; - (void)setupChannels:(id)binaryMessenger; diff --git a/packages/e2e/ios/Classes/E2EPlugin.m b/packages/integration_test/ios/Classes/IntegrationTestPlugin.m similarity index 65% rename from packages/e2e/ios/Classes/E2EPlugin.m rename to packages/integration_test/ios/Classes/IntegrationTestPlugin.m index e025c2917201..99d0c7fdf888 100644 --- a/packages/e2e/ios/Classes/E2EPlugin.m +++ b/packages/integration_test/ios/Classes/IntegrationTestPlugin.m @@ -1,23 +1,23 @@ -#import "E2EPlugin.h" +#import "IntegrationTestPlugin.h" -static NSString *const kE2EPluginChannel = @"plugins.flutter.io/e2e"; +static NSString *const kIntegrationTestPluginChannel = @"plugins.flutter.io/integratoin_test"; static NSString *const kMethodTestFinished = @"allTestsFinished"; -@interface E2EPlugin () +@interface IntegrationTestPlugin () @property(nonatomic, readwrite) NSDictionary *testResults; @end -@implementation E2EPlugin { +@implementation IntegrationTestPlugin { NSDictionary *_testResults; } -+ (E2EPlugin *)instance { ++ (IntegrationTestPlugin *)instance { static dispatch_once_t onceToken; - static E2EPlugin *sInstance; + static IntegrationTestPlugin *sInstance; dispatch_once(&onceToken, ^{ - sInstance = [[E2EPlugin alloc] initForRegistration]; + sInstance = [[IntegrationTestPlugin alloc] initForRegistration]; }); return sInstance; } @@ -29,13 +29,14 @@ - (instancetype)initForRegistration { + (void)registerWithRegistrar:(NSObject *)registrar { // No initialization happens here because of the way XCTest loads the testing // bundles. Setup on static variables can be disregarded when a new static - // instance of E2EPlugin is allocated when the bundle is reloaded. + // instance of IntegrationTestPlugin is allocated when the bundle is reloaded. // See also: https://github.com/flutter/plugins/pull/2465 } - (void)setupChannels:(id)binaryMessenger { - FlutterMethodChannel *channel = [FlutterMethodChannel methodChannelWithName:kE2EPluginChannel - binaryMessenger:binaryMessenger]; + FlutterMethodChannel *channel = + [FlutterMethodChannel methodChannelWithName:kIntegrationTestPluginChannel + binaryMessenger:binaryMessenger]; [channel setMethodCallHandler:^(FlutterMethodCall *call, FlutterResult result) { [self handleMethodCall:call result:result]; }]; diff --git a/packages/e2e/ios/e2e.podspec b/packages/integration_test/ios/integration_test.podspec similarity index 81% rename from packages/e2e/ios/e2e.podspec rename to packages/integration_test/ios/integration_test.podspec index 0a6a6915607d..9fb0dfc9d790 100644 --- a/packages/e2e/ios/e2e.podspec +++ b/packages/integration_test/ios/integration_test.podspec @@ -2,16 +2,16 @@ # To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html # Pod::Spec.new do |s| - s.name = 'e2e' + s.name = 'integration_test' s.version = '0.0.1' - s.summary = 'Adapter for e2e tests.' + s.summary = 'Adapter for integration tests.' s.description = <<-DESC Runs tests that use the flutter_test API as integration tests. DESC - s.homepage = 'https://github.com/flutter/plugins/tree/master/packages/e2e' + s.homepage = 'https://github.com/flutter/plugins/tree/master/packages/integration_test' s.license = { :type => 'BSD', :file => '../LICENSE' } s.author = { 'Flutter Team' => 'flutter-dev@googlegroups.com' } - s.source = { :http => 'https://github.com/flutter/plugins/tree/master/packages/e2e' } + s.source = { :http => 'https://github.com/flutter/plugins/tree/master/packages/integration_test' } s.source_files = 'Classes/**/*' s.public_header_files = 'Classes/**/*.h' s.dependency 'Flutter' diff --git a/packages/e2e/lib/_extension_io.dart b/packages/integration_test/lib/_extension_io.dart similarity index 100% rename from packages/e2e/lib/_extension_io.dart rename to packages/integration_test/lib/_extension_io.dart diff --git a/packages/e2e/lib/_extension_web.dart b/packages/integration_test/lib/_extension_web.dart similarity index 100% rename from packages/e2e/lib/_extension_web.dart rename to packages/integration_test/lib/_extension_web.dart diff --git a/packages/e2e/lib/common.dart b/packages/integration_test/lib/common.dart similarity index 97% rename from packages/e2e/lib/common.dart rename to packages/integration_test/lib/common.dart index 4325b6555ba8..3363e3c91989 100644 --- a/packages/e2e/lib/common.dart +++ b/packages/integration_test/lib/common.dart @@ -4,7 +4,7 @@ import 'dart:convert'; -/// An object sent from e2e back to the Flutter Driver in response to +/// An object sent from integration_test back to the Flutter Driver in response to /// `request_data` command. class Response { final List _failureDetails; diff --git a/packages/e2e/lib/e2e.dart b/packages/integration_test/lib/integration_test.dart similarity index 71% rename from packages/e2e/lib/e2e.dart rename to packages/integration_test/lib/integration_test.dart index a9bf83041e40..6354ef768939 100644 --- a/packages/e2e/lib/e2e.dart +++ b/packages/integration_test/lib/integration_test.dart @@ -15,16 +15,18 @@ import '_extension_io.dart' if (dart.library.html) '_extension_web.dart'; /// A subclass of [LiveTestWidgetsFlutterBinding] that reports tests results /// on a channel to adapt them to native instrumentation test format. -class E2EWidgetsFlutterBinding extends LiveTestWidgetsFlutterBinding { +class IntegrationTestWidgetsFlutterBinding + extends LiveTestWidgetsFlutterBinding { /// Sets up a listener to report that the tests are finished when everything is /// torn down. - E2EWidgetsFlutterBinding() { + IntegrationTestWidgetsFlutterBinding() { // TODO(jackson): Report test results as they arrive tearDownAll(() async { + print('TESTING123: TEARING HER DOWN'); try { // For web integration tests we are not using the - // `plugins.flutter.io/e2e`. Mark the tests as complete before invoking - // the channel. + // `plugins.flutter.io/integration_test`. Mark the tests as complete + // before invoking the channel. if (kIsWeb) { if (!_allTestsPassed.isCompleted) { _allTestsPassed.complete(true); @@ -32,13 +34,26 @@ class E2EWidgetsFlutterBinding extends LiveTestWidgetsFlutterBinding { } await _channel.invokeMethod( 'allTestsFinished', - {'results': _results}, + {'results': results}, ); } on MissingPluginException { - print('Warning: E2E test plugin was not detected.'); + print('Warning: integration_test test plugin was not detected.'); } if (!_allTestsPassed.isCompleted) _allTestsPassed.complete(true); }); + + // TODO(jackson): Report the results individually instead of all at once + // See https://github.com/flutter/flutter/issues/38985 + final TestExceptionReporter oldTestExceptionReporter = reportTestException; + reportTestException = + (FlutterErrorDetails details, String testDescription) { + results[testDescription] = 'failed'; + _failureMethodsDetails.add(Failure(testDescription, details.toString())); + if (!_allTestsPassed.isCompleted) { + _allTestsPassed.complete(false); + } + oldTestExceptionReporter(details, testDescription); + }; } // TODO(dnfield): Remove the ignore once we bump the minimum Flutter version @@ -51,9 +66,33 @@ class E2EWidgetsFlutterBinding extends LiveTestWidgetsFlutterBinding { @override bool get registerTestTextInput => false; + Size _surfaceSize; + + /// Artificially changes the surface size to `size` on the Widget binding, + /// then flushes microtasks. + /// + /// Set to null to use the default surface size. + @override + Future setSurfaceSize(Size size) { + return TestAsyncUtils.guard(() async { + assert(inTest); + if (_surfaceSize == size) { + return; + } + _surfaceSize = size; + handleMetricsChanged(); + }); + } + @override - ViewConfiguration createViewConfiguration() => TestViewConfiguration( - size: window.physicalSize / window.devicePixelRatio); + ViewConfiguration createViewConfiguration() { + final double devicePixelRatio = window.devicePixelRatio; + final Size size = _surfaceSize ?? window.physicalSize / devicePixelRatio; + return TestViewConfiguration( + size: size, + window: window, + ); + } final Completer _allTestsPassed = Completer(); @@ -64,19 +103,26 @@ class E2EWidgetsFlutterBinding extends LiveTestWidgetsFlutterBinding { /// Similar to [WidgetsFlutterBinding.ensureInitialized]. /// - /// Returns an instance of the [E2EWidgetsFlutterBinding], creating and + /// Returns an instance of the [IntegrationTestWidgetsFlutterBinding], creating and /// initializing it if necessary. static WidgetsBinding ensureInitialized() { + print('TESTING123 ensuring init'); if (WidgetsBinding.instance == null) { - E2EWidgetsFlutterBinding(); + IntegrationTestWidgetsFlutterBinding(); } - assert(WidgetsBinding.instance is E2EWidgetsFlutterBinding); + assert(WidgetsBinding.instance is IntegrationTestWidgetsFlutterBinding); return WidgetsBinding.instance; } - static const MethodChannel _channel = MethodChannel('plugins.flutter.io/e2e'); + static const MethodChannel _channel = + MethodChannel('plugins.flutter.io/integration_test'); - static Map _results = {}; + /// Test results that will be populated after the tests have completed. + /// + /// Keys are the test descriptions, and values are either `success` or + /// `failed`. + @visibleForTesting + Map results = {}; /// The extra data for the reported result. /// @@ -134,24 +180,12 @@ class E2EWidgetsFlutterBinding extends LiveTestWidgetsFlutterBinding { String description = '', Duration timeout, }) async { - // TODO(jackson): Report the results individually instead of all at once - // See https://github.com/flutter/flutter/issues/38985 - final TestExceptionReporter oldTestExceptionReporter = reportTestException; - reportTestException = - (FlutterErrorDetails details, String testDescription) { - _results[description] = 'failed'; - _failureMethodsDetails.add(Failure(testDescription, details.toString())); - if (!_allTestsPassed.isCompleted) { - _allTestsPassed.complete(false); - } - oldTestExceptionReporter(details, testDescription); - }; await super.runTest( testBody, invariantTester, description: description, timeout: timeout, ); - _results[description] ??= 'success'; + results[description] ??= 'success'; } } diff --git a/packages/integration_test/lib/integration_test_driver.dart b/packages/integration_test/lib/integration_test_driver.dart new file mode 100644 index 000000000000..e5160b4e8d68 --- /dev/null +++ b/packages/integration_test/lib/integration_test_driver.dart @@ -0,0 +1,90 @@ +// 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:flutter_driver/flutter_driver.dart'; + +import 'package:integration_test/common.dart'; +import 'package:path/path.dart' as path; + +/// Flutter Driver test output directory. +/// +/// Tests should write any output files to this directory. Defaults to the path +/// set in the FLUTTER_TEST_OUTPUTS_DIR environment variable, or `build` if +/// unset. +String testOutputsDirectory = + Platform.environment['FLUTTER_TEST_OUTPUTS_DIR'] ?? 'build'; + +/// The callback type to handle [integration_test.Response.data] after the test succcess. +typedef ResponseDataCallback = FutureOr Function(Map); + +/// Writes a json-serializable json data to to +/// [testOutputsDirectory]/`testOutputFilename.json`. +/// +/// This is the default `responseDataCallback` in [integrationDriver]. +Future writeResponseData( + Map data, { + String testOutputFilename = 'integration_response_data', + String destinationDirectory, +}) async { + assert(testOutputFilename != null); + destinationDirectory ??= testOutputsDirectory; + await fs.directory(destinationDirectory).create(recursive: true); + final File file = fs.file(path.join( + destinationDirectory, + '$testOutputFilename.json', + )); + final String resultString = _encodeJson(data, true); + await file.writeAsString(resultString); +} + +/// Adaptor to run an integration test using `flutter drive`. +/// +/// `timeout` controls the longest time waited before the test ends. +/// It is not necessarily the execution time for the test app: the test may +/// finish sooner than the `timeout`. +/// +/// `responseDataCallback` is the handler for processing [integration_test.Response.data]. +/// The default value is `writeResponseData`. +/// +/// To an integration test `.dart` using `flutter drive`, put a file named +/// `_test.dart` in the app's `test_driver` directory: +/// +/// ```dart +/// import 'dart:async'; +/// +/// import 'package:integration_test/integration_test_driver.dart'; +/// +/// Future main() async => integrationDriver(); +/// +/// ``` +Future integrationDriver({ + Duration timeout = const Duration(minutes: 1), + ResponseDataCallback responseDataCallback = writeResponseData, +}) async { + final FlutterDriver driver = await FlutterDriver.connect(); + final String jsonResult = await driver.requestData(null, timeout: timeout); + final Response response = Response.fromJson(jsonResult); + await driver.close(); + + if (response.allTestsPassed) { + print('All tests passed.'); + if (responseDataCallback != null) { + await responseDataCallback(response.data); + } + exit(0); + } else { + print('Failure Details:\n${response.formattedFailureDetails}'); + exit(1); + } +} + +const JsonEncoder _prettyEncoder = JsonEncoder.withIndent(' '); + +String _encodeJson(Map jsonObject, bool pretty) { + return pretty ? _prettyEncoder.convert(jsonObject) : json.encode(jsonObject); +} diff --git a/packages/e2e/pubspec.yaml b/packages/integration_test/pubspec.yaml similarity index 66% rename from packages/e2e/pubspec.yaml rename to packages/integration_test/pubspec.yaml index 70e57d0cb4f7..b222531044e9 100644 --- a/packages/e2e/pubspec.yaml +++ b/packages/integration_test/pubspec.yaml @@ -1,7 +1,7 @@ -name: e2e +name: integration_test description: Runs tests that use the flutter_test API as integration tests. -version: 0.6.1 -homepage: https://github.com/flutter/plugins/tree/master/packages/e2e +version: 0.8.0 +homepage: https://github.com/flutter/plugins/tree/master/packages/integration_test environment: sdk: ">=2.2.2 <3.0.0" @@ -14,6 +14,7 @@ dependencies: sdk: flutter flutter_test: sdk: flutter + path: ^1.6.4 dev_dependencies: pedantic: ^1.8.0 @@ -22,7 +23,7 @@ flutter: plugin: platforms: android: - package: dev.flutter.plugins.e2e - pluginClass: E2EPlugin + package: dev.flutter.plugins.integration_test + pluginClass: IntegrationTestPlugin ios: - pluginClass: E2EPlugin + pluginClass: IntegrationTestPlugin diff --git a/packages/integration_test/test/binding_fail_test.dart b/packages/integration_test/test/binding_fail_test.dart new file mode 100644 index 000000000000..020fb9607608 --- /dev/null +++ b/packages/integration_test/test/binding_fail_test.dart @@ -0,0 +1,82 @@ +import 'dart:async'; +import 'dart:io'; +import 'dart:convert'; + +import 'package:flutter_test/flutter_test.dart'; + +// Assumes that the flutter command is in `$PATH`. +const String _flutterBin = 'flutter'; +const String _integrationResultsPrefix = + 'IntegrationTestWidgetsFlutterBinding test results:'; + +void main() async { + group('Integration binding result', () { + test('when multiple tests pass', () async { + final Map results = + await _runTest('test/data/pass_test_script.dart'); + + expect( + results, + equals({ + 'passing test 1': 'success', + 'passing test 2': 'success', + })); + }); + + test('when multiple tests fail', () async { + final Map results = + await _runTest('test/data/fail_test_script.dart'); + + expect( + results, + equals({ + 'failing test 1': 'failed', + 'failing test 2': 'failed', + })); + }); + + test('when one test passes, then another fails', () async { + final Map results = + await _runTest('test/data/pass_then_fail_test_script.dart'); + + expect( + results, + equals({ + 'passing test': 'success', + 'failing test': 'failed', + })); + }); + }); +} + +/// Runs a test script and returns the [IntegrationTestWidgetsFlutterBinding.result]. +/// +/// [scriptPath] is relative to the package root. +Future> _runTest(String scriptPath) async { + final Process process = + await Process.start(_flutterBin, ['test', '--machine', scriptPath]); + + /// In the test [tearDownAll] block, the test results are encoded into JSON and + /// are printed with the [_integrationResultsPrefix] prefix. + /// + /// See the following for the test event spec which we parse the printed lines + /// out of: https://github.com/dart-lang/test/blob/master/pkgs/test/doc/json_reporter.md + final String testResults = (await process.stdout + .transform(utf8.decoder) + .expand((String text) => text.split('\n')) + .map((String line) { + try { + return jsonDecode(line); + } on FormatException { + // Only interested in test events which are JSON. + } + }) + .where((dynamic testEvent) => + testEvent != null && testEvent['type'] == 'print') + .map((dynamic printEvent) => printEvent['message'] as String) + .firstWhere((String message) => + message.startsWith(_integrationResultsPrefix))) + .replaceAll(_integrationResultsPrefix, ''); + + return jsonDecode(testResults); +} diff --git a/packages/integration_test/test/binding_test.dart b/packages/integration_test/test/binding_test.dart new file mode 100644 index 000000000000..bad365ac59b6 --- /dev/null +++ b/packages/integration_test/test/binding_test.dart @@ -0,0 +1,68 @@ +import 'package:flutter/material.dart'; + +import 'package:integration_test/integration_test.dart'; +import 'package:integration_test/common.dart'; +import 'package:flutter_test/flutter_test.dart'; + +void main() async { + Future> request; + + group('Test Integration binding', () { + final WidgetsBinding binding = + IntegrationTestWidgetsFlutterBinding.ensureInitialized(); + assert(binding is IntegrationTestWidgetsFlutterBinding); + final IntegrationTestWidgetsFlutterBinding integrationBinding = + binding as IntegrationTestWidgetsFlutterBinding; + + setUp(() { + request = integrationBinding.callback({ + 'command': 'request_data', + }); + }); + + testWidgets('Run Integration app', (WidgetTester tester) async { + runApp(MaterialApp( + home: Text('Test'), + )); + expect(tester.binding, integrationBinding); + integrationBinding.reportData = {'answer': 42}; + }); + + testWidgets('setSurfaceSize works', (WidgetTester tester) async { + await tester.pumpWidget(MaterialApp(home: Center(child: Text('Test')))); + + final Size windowCenter = tester.binding.window.physicalSize / + tester.binding.window.devicePixelRatio / + 2; + final double windowCenterX = windowCenter.width; + final double windowCenterY = windowCenter.height; + + Offset widgetCenter = tester.getRect(find.byType(Text)).center; + expect(widgetCenter.dx, windowCenterX); + expect(widgetCenter.dy, windowCenterY); + + await tester.binding.setSurfaceSize(const Size(200, 300)); + await tester.pump(); + widgetCenter = tester.getRect(find.byType(Text)).center; + expect(widgetCenter.dx, 100); + expect(widgetCenter.dy, 150); + + await tester.binding.setSurfaceSize(null); + await tester.pump(); + widgetCenter = tester.getRect(find.byType(Text)).center; + expect(widgetCenter.dx, windowCenterX); + expect(widgetCenter.dy, windowCenterY); + }); + }); + + tearDownAll(() async { + // This part is outside the group so that `request` has been compeleted as + // part of the `tearDownAll` registerred in the group during + // `IntegrationTestWidgetsFlutterBinding` initialization. + final Map response = + (await request)['response'] as Map; + final String message = response['message'] as String; + Response result = Response.fromJson(message); + assert(result.data['answer'] == 42); + }); +} diff --git a/packages/integration_test/test/data/README.md b/packages/integration_test/test/data/README.md new file mode 100644 index 000000000000..e52aca112ce4 --- /dev/null +++ b/packages/integration_test/test/data/README.md @@ -0,0 +1,4 @@ +Files in this directory are not invoked directly by the test command. + +They are used as inputs for the other test files outside of this directory, so +that failures can be tested. \ No newline at end of file diff --git a/packages/integration_test/test/data/fail_test_script.dart b/packages/integration_test/test/data/fail_test_script.dart new file mode 100644 index 000000000000..05a75d7d031e --- /dev/null +++ b/packages/integration_test/test/data/fail_test_script.dart @@ -0,0 +1,22 @@ +import 'dart:convert'; + +import 'package:integration_test/integration_test.dart'; +import 'package:flutter_test/flutter_test.dart'; + +void main() async { + final IntegrationTestWidgetsFlutterBinding binding = + IntegrationTestWidgetsFlutterBinding.ensureInitialized(); + + testWidgets('failing test 1', (WidgetTester tester) async { + expect(true, false); + }); + + testWidgets('failing test 2', (WidgetTester tester) async { + expect(true, false); + }); + + tearDownAll(() { + print( + 'IntegrationTestWidgetsFlutterBinding test results: ${jsonEncode(binding.results)}'); + }); +} diff --git a/packages/integration_test/test/data/pass_test_script.dart b/packages/integration_test/test/data/pass_test_script.dart new file mode 100644 index 000000000000..7e222c8e8961 --- /dev/null +++ b/packages/integration_test/test/data/pass_test_script.dart @@ -0,0 +1,22 @@ +import 'dart:convert'; + +import 'package:integration_test/integration_test.dart'; +import 'package:flutter_test/flutter_test.dart'; + +void main() async { + final IntegrationTestWidgetsFlutterBinding binding = + IntegrationTestWidgetsFlutterBinding.ensureInitialized(); + + testWidgets('passing test 1', (WidgetTester tester) async { + expect(true, true); + }); + + testWidgets('passing test 2', (WidgetTester tester) async { + expect(true, true); + }); + + tearDownAll(() { + print( + 'IntegrationTestWidgetsFlutterBinding test results: ${jsonEncode(binding.results)}'); + }); +} diff --git a/packages/integration_test/test/data/pass_then_fail_test_script.dart b/packages/integration_test/test/data/pass_then_fail_test_script.dart new file mode 100644 index 000000000000..324c1c21cfa6 --- /dev/null +++ b/packages/integration_test/test/data/pass_then_fail_test_script.dart @@ -0,0 +1,22 @@ +import 'dart:convert'; + +import 'package:integration_test/integration_test.dart'; +import 'package:flutter_test/flutter_test.dart'; + +void main() async { + final IntegrationTestWidgetsFlutterBinding binding = + IntegrationTestWidgetsFlutterBinding.ensureInitialized(); + + testWidgets('passing test', (WidgetTester tester) async { + expect(true, true); + }); + + testWidgets('failing test', (WidgetTester tester) async { + expect(true, false); + }); + + tearDownAll(() { + print( + 'IntegrationTestWidgetsFlutterBinding test results: ${jsonEncode(binding.results)}'); + }); +} diff --git a/packages/e2e/test/response_serialization_test.dart b/packages/integration_test/test/response_serialization_test.dart similarity index 97% rename from packages/e2e/test/response_serialization_test.dart rename to packages/integration_test/test/response_serialization_test.dart index 4d823e2ebf10..8b969402035d 100644 --- a/packages/e2e/test/response_serialization_test.dart +++ b/packages/integration_test/test/response_serialization_test.dart @@ -1,6 +1,6 @@ import 'package:flutter_test/flutter_test.dart'; -import 'package:e2e/common.dart'; +import 'package:integration_test/common.dart'; void main() { test('Serialize and deserialize Failure', () { diff --git a/packages/local_auth/CHANGELOG.md b/packages/local_auth/CHANGELOG.md index 8fec727bd10e..222014af2153 100644 --- a/packages/local_auth/CHANGELOG.md +++ b/packages/local_auth/CHANGELOG.md @@ -1,3 +1,16 @@ +## 0.6.3+1 + +* Update package:e2e -> package:integration_test + +## 0.6.3 + +* Increase upper range of `package:platform` constraint to allow 3.X versions. + +## 0.6.2+4 + +* Update package:e2e reference to use the local version in the flutter/plugins + repository. + ## 0.6.2+3 * Post-v2 Android embedding cleanup. diff --git a/packages/local_auth/example/android/app/src/androidTest/java/io/flutter/plugins/localauth/EmbeddingV1ActivityTest.java b/packages/local_auth/example/android/app/src/androidTest/java/io/flutter/plugins/localauth/EmbeddingV1ActivityTest.java index b2cea8dc57a2..6b125e4cf8e2 100644 --- a/packages/local_auth/example/android/app/src/androidTest/java/io/flutter/plugins/localauth/EmbeddingV1ActivityTest.java +++ b/packages/local_auth/example/android/app/src/androidTest/java/io/flutter/plugins/localauth/EmbeddingV1ActivityTest.java @@ -1,12 +1,12 @@ package io.flutter.plugins.localauth; import androidx.test.rule.ActivityTestRule; -import dev.flutter.plugins.e2e.FlutterRunner; +import dev.flutter.plugins.integration_test.FlutterTestRunner; import io.flutter.plugins.localauthexample.EmbeddingV1Activity; import org.junit.Rule; import org.junit.runner.RunWith; -@RunWith(FlutterRunner.class) +@RunWith(FlutterTestRunner.class) public class EmbeddingV1ActivityTest { @Rule public ActivityTestRule rule = diff --git a/packages/local_auth/example/android/app/src/androidTest/java/io/flutter/plugins/localauth/MainActivityTest.java b/packages/local_auth/example/android/app/src/androidTest/java/io/flutter/plugins/localauth/MainActivityTest.java index f717ac97dd52..3d2d55bce0fa 100644 --- a/packages/local_auth/example/android/app/src/androidTest/java/io/flutter/plugins/localauth/MainActivityTest.java +++ b/packages/local_auth/example/android/app/src/androidTest/java/io/flutter/plugins/localauth/MainActivityTest.java @@ -1,12 +1,12 @@ package io.flutter.plugins.localauth; import androidx.test.rule.ActivityTestRule; -import dev.flutter.plugins.e2e.FlutterRunner; +import dev.flutter.plugins.integration_test.FlutterTestRunner; import io.flutter.embedding.android.FlutterFragmentActivity; import org.junit.Rule; import org.junit.runner.RunWith; -@RunWith(FlutterRunner.class) +@RunWith(FlutterTestRunner.class) public class FlutterFragmentActivityTest { @Rule public ActivityTestRule rule = diff --git a/packages/local_auth/example/android/app/src/main/java/io/flutter/plugins/localauthexample/EmbeddingV1Activity.java b/packages/local_auth/example/android/app/src/main/java/io/flutter/plugins/localauthexample/EmbeddingV1Activity.java index 166a043e9b66..456d5407c4be 100644 --- a/packages/local_auth/example/android/app/src/main/java/io/flutter/plugins/localauthexample/EmbeddingV1Activity.java +++ b/packages/local_auth/example/android/app/src/main/java/io/flutter/plugins/localauthexample/EmbeddingV1Activity.java @@ -1,7 +1,7 @@ package io.flutter.plugins.localauthexample; import android.os.Bundle; -import dev.flutter.plugins.e2e.E2EPlugin; +import dev.flutter.plugins.integration_test.IntegrationTestPlugin; import io.flutter.app.FlutterFragmentActivity; import io.flutter.plugins.flutter_plugin_android_lifecycle.FlutterAndroidLifecyclePlugin; import io.flutter.plugins.localauth.LocalAuthPlugin; @@ -10,7 +10,8 @@ public class EmbeddingV1Activity extends FlutterFragmentActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - E2EPlugin.registerWith(registrarFor("dev.flutter.plugins.e2e.E2EPlugin")); + IntegrationTestPlugin.registerWith( + registrarFor("dev.flutter.plugins.integration_test.IntegrationTestPlugin")); FlutterAndroidLifecyclePlugin.registerWith( registrarFor( "io.flutter.plugins.flutter_plugin_android_lifecycle.FlutterAndroidLifecyclePlugin")); diff --git a/packages/local_auth/example/pubspec.yaml b/packages/local_auth/example/pubspec.yaml index f6e7f669656f..8d17a43efb26 100644 --- a/packages/local_auth/example/pubspec.yaml +++ b/packages/local_auth/example/pubspec.yaml @@ -8,7 +8,8 @@ dependencies: path: ../ dev_dependencies: - e2e: ^0.2.1 + integration_test: + path: ../../integration_test flutter_driver: sdk: flutter pedantic: ^1.8.0 diff --git a/packages/local_auth/pubspec.yaml b/packages/local_auth/pubspec.yaml index d80ebeb304c3..57bf9fa37b6c 100644 --- a/packages/local_auth/pubspec.yaml +++ b/packages/local_auth/pubspec.yaml @@ -2,7 +2,7 @@ name: local_auth description: Flutter plugin for Android and iOS device authentication sensors such as Fingerprint Reader and Touch ID. homepage: https://github.com/flutter/plugins/tree/master/packages/local_auth -version: 0.6.2+3 +version: 0.6.3+1 flutter: plugin: @@ -18,11 +18,12 @@ dependencies: sdk: flutter meta: ^1.0.5 intl: ">=0.15.1 <0.17.0" - platform: ^2.0.0 + platform: ">=2.0.0 <4.0.0" flutter_plugin_android_lifecycle: ^1.0.2 dev_dependencies: - e2e: ^0.2.1 + integration_test: + path: ../integration_test flutter_driver: sdk: flutter flutter_test: diff --git a/packages/local_auth/test/local_auth_e2e.dart b/packages/local_auth/test/local_auth_e2e.dart index 5e9dc57b73f6..47e5dfa67912 100644 --- a/packages/local_auth/test/local_auth_e2e.dart +++ b/packages/local_auth/test/local_auth_e2e.dart @@ -1,10 +1,10 @@ import 'package:flutter_test/flutter_test.dart'; -import 'package:e2e/e2e.dart'; +import 'package:integration_test/integration_test.dart'; import 'package:local_auth/local_auth.dart'; void main() { - E2EWidgetsFlutterBinding.ensureInitialized(); + IntegrationTestWidgetsFlutterBinding.ensureInitialized(); testWidgets('canCheckBiometrics', (WidgetTester tester) async { expect(LocalAuthentication().getAvailableBiometrics(), completion(isList)); diff --git a/packages/package_info/CHANGELOG.md b/packages/package_info/CHANGELOG.md index 2344f37484bc..f88c270d92a3 100644 --- a/packages/package_info/CHANGELOG.md +++ b/packages/package_info/CHANGELOG.md @@ -1,3 +1,12 @@ +## 0.4.3 + +* Update package:e2e -> package:integration_test + +## 0.4.2 + +* Update package:e2e reference to use the local version in the flutter/plugins + repository. + ## 0.4.1 * Add support for macOS. diff --git a/packages/package_info/example/android/app/src/androidTest/java/io/flutter/plugins/packageinfoexample/EmbedderV1ActivityTest.java b/packages/package_info/example/android/app/src/androidTest/java/io/flutter/plugins/packageinfoexample/EmbedderV1ActivityTest.java index 47362ba64a9d..ab1d2d29635e 100644 --- a/packages/package_info/example/android/app/src/androidTest/java/io/flutter/plugins/packageinfoexample/EmbedderV1ActivityTest.java +++ b/packages/package_info/example/android/app/src/androidTest/java/io/flutter/plugins/packageinfoexample/EmbedderV1ActivityTest.java @@ -5,11 +5,11 @@ package io.flutter.plugins.packageinfoexample; import androidx.test.rule.ActivityTestRule; -import dev.flutter.plugins.e2e.FlutterRunner; +import dev.flutter.plugins.integration_test.FlutterTestRunner; import org.junit.Rule; import org.junit.runner.RunWith; -@RunWith(FlutterRunner.class) +@RunWith(FlutterTestRunner.class) public class EmbedderV1ActivityTest { @Rule public ActivityTestRule rule = diff --git a/packages/package_info/example/android/app/src/androidTest/java/io/flutter/plugins/packageinfoexample/MainActivityTest.java b/packages/package_info/example/android/app/src/androidTest/java/io/flutter/plugins/packageinfoexample/MainActivityTest.java index 7a1dfdb775f1..91aad52d4241 100644 --- a/packages/package_info/example/android/app/src/androidTest/java/io/flutter/plugins/packageinfoexample/MainActivityTest.java +++ b/packages/package_info/example/android/app/src/androidTest/java/io/flutter/plugins/packageinfoexample/MainActivityTest.java @@ -5,12 +5,12 @@ package io.flutter.plugins.packageinfoexample; import androidx.test.rule.ActivityTestRule; -import dev.flutter.plugins.e2e.FlutterRunner; +import dev.flutter.plugins.integration_test.FlutterTestRunner; import io.flutter.embedding.android.FlutterActivity; import org.junit.Rule; import org.junit.runner.RunWith; -@RunWith(FlutterRunner.class) +@RunWith(FlutterTestRunner.class) public class MainActivityTest { @Rule public ActivityTestRule rule = new ActivityTestRule<>(FlutterActivity.class); diff --git a/packages/package_info/example/pubspec.yaml b/packages/package_info/example/pubspec.yaml index f6ea2f40527e..a6dbbce44811 100644 --- a/packages/package_info/example/pubspec.yaml +++ b/packages/package_info/example/pubspec.yaml @@ -6,7 +6,8 @@ dependencies: sdk: flutter package_info: path: ../ - e2e: "^0.2.1" + integration_test: + path: ../../integration_test dev_dependencies: flutter_driver: diff --git a/packages/package_info/example/test_driver/package_info_e2e.dart b/packages/package_info/example/test_driver/package_info_e2e.dart index d701c8030bd9..5038509ec84f 100644 --- a/packages/package_info/example/test_driver/package_info_e2e.dart +++ b/packages/package_info/example/test_driver/package_info_e2e.dart @@ -4,12 +4,12 @@ import 'dart:io'; import 'package:flutter_test/flutter_test.dart'; -import 'package:e2e/e2e.dart'; +import 'package:integration_test/integration_test.dart'; import 'package:package_info/package_info.dart'; import 'package:package_info_example/main.dart'; void main() { - E2EWidgetsFlutterBinding.ensureInitialized(); + IntegrationTestWidgetsFlutterBinding.ensureInitialized(); testWidgets('fromPlatform', (WidgetTester tester) async { final PackageInfo info = await PackageInfo.fromPlatform(); diff --git a/packages/package_info/example/test_driver/package_info_e2e_test.dart b/packages/package_info/example/test_driver/package_info_e2e_test.dart index 1bcd0d37f450..f532c389a02b 100644 --- a/packages/package_info/example/test_driver/package_info_e2e_test.dart +++ b/packages/package_info/example/test_driver/package_info_e2e_test.dart @@ -2,14 +2,18 @@ // for details. 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:convert'; import 'dart:io'; import 'package:flutter_driver/flutter_driver.dart'; Future main() async { final FlutterDriver driver = await FlutterDriver.connect(); - final String result = - await driver.requestData(null, timeout: const Duration(minutes: 1)); + final String data = await driver.requestData( + null, + timeout: const Duration(minutes: 1), + ); await driver.close(); - exit(result == 'pass' ? 0 : 1); + final Map result = jsonDecode(data); + exit(result['result'] == 'true' ? 0 : 1); } diff --git a/packages/package_info/pubspec.yaml b/packages/package_info/pubspec.yaml index bb18407fd862..0705dd11d139 100644 --- a/packages/package_info/pubspec.yaml +++ b/packages/package_info/pubspec.yaml @@ -5,7 +5,7 @@ homepage: https://github.com/flutter/plugins/tree/master/packages/package_info # 0.4.y+z is compatible with 1.0.0, if you land a breaking change bump # the version to 2.0.0. # See more details: https://github.com/flutter/flutter/wiki/Package-migration-to-1.0.0 -version: 0.4.1 +version: 0.4.3 flutter: plugin: @@ -28,7 +28,8 @@ dev_dependencies: flutter_driver: sdk: flutter test: any - e2e: "^0.2.1" + integration_test: + path: ../integration_test pedantic: ^1.8.0 environment: diff --git a/packages/path_provider/path_provider/CHANGELOG.md b/packages/path_provider/path_provider/CHANGELOG.md index 226d9ae01d0c..07778d5ccef3 100644 --- a/packages/path_provider/path_provider/CHANGELOG.md +++ b/packages/path_provider/path_provider/CHANGELOG.md @@ -1,7 +1,22 @@ +## 1.6.14 + +* Update package:e2e -> package:integration_test + +## 1.6.13 + +* Update package:e2e reference to use the local version in the flutter/plugins + repository. + +## 1.6.12 + +* Fixed a Java lint in a test. + ## 1.6.11 + * Updated documentation to reflect the need for changes in testing for federated plugins ## 1.6.10 + * Linux implementation endorsement ## 1.6.9 diff --git a/packages/path_provider/path_provider/example/android/app/src/androidTest/java/EmbeddingV1ActivityTest.java b/packages/path_provider/path_provider/example/android/app/src/androidTest/java/EmbeddingV1ActivityTest.java index cce04b79f516..50cb342715cb 100644 --- a/packages/path_provider/path_provider/example/android/app/src/androidTest/java/EmbeddingV1ActivityTest.java +++ b/packages/path_provider/path_provider/example/android/app/src/androidTest/java/EmbeddingV1ActivityTest.java @@ -2,12 +2,12 @@ package io.flutter.plugins.pathprovider; import androidx.test.rule.ActivityTestRule; -import dev.flutter.plugins.e2e.FlutterRunner; +import dev.flutter.plugins.integration_test.FlutterTestRunner; import io.flutter.plugins.pathproviderexample.EmbeddingV1Activity; import org.junit.Rule; import org.junit.runner.RunWith; -@RunWith(FlutterRunner.class) +@RunWith(FlutterTestRunner.class) public class EmbeddingV1ActivityTest { @Rule public ActivityTestRule rule = diff --git a/packages/path_provider/path_provider/example/android/app/src/androidTest/java/MainActivityTest.java b/packages/path_provider/path_provider/example/android/app/src/androidTest/java/MainActivityTest.java index 25ee8d8fcdc0..a99767c4ccf9 100644 --- a/packages/path_provider/path_provider/example/android/app/src/androidTest/java/MainActivityTest.java +++ b/packages/path_provider/path_provider/example/android/app/src/androidTest/java/MainActivityTest.java @@ -2,13 +2,13 @@ package io.flutter.plugins.pathprovider; import androidx.test.rule.ActivityTestRule; -import dev.flutter.plugins.e2e.FlutterRunner; +import dev.flutter.plugins.integration_test.FlutterTestRunner; import io.flutter.embedding.android.FlutterActivity; import org.junit.Rule; import org.junit.runner.RunWith; -@RunWith(FlutterRunner.class) -public class FlutterActivityTest { +@RunWith(FlutterTestRunner.class) +public class MainActivityTest { @Rule public ActivityTestRule rule = new ActivityTestRule<>(FlutterActivity.class); } diff --git a/packages/path_provider/path_provider/example/android/app/src/main/java/io/flutter/plugins/pathproviderexample/EmbeddingV1Activity.java b/packages/path_provider/path_provider/example/android/app/src/main/java/io/flutter/plugins/pathproviderexample/EmbeddingV1Activity.java index 2a59361e7f67..6c4a6185359c 100644 --- a/packages/path_provider/path_provider/example/android/app/src/main/java/io/flutter/plugins/pathproviderexample/EmbeddingV1Activity.java +++ b/packages/path_provider/path_provider/example/android/app/src/main/java/io/flutter/plugins/pathproviderexample/EmbeddingV1Activity.java @@ -2,7 +2,7 @@ package io.flutter.plugins.pathproviderexample; import android.os.Bundle; -import dev.flutter.plugins.e2e.E2EPlugin; +import dev.flutter.plugins.integration_test.IntegrationTestPlugin; import io.flutter.app.FlutterActivity; import io.flutter.plugins.pathprovider.PathProviderPlugin; @@ -10,7 +10,8 @@ public class EmbeddingV1Activity extends FlutterActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - E2EPlugin.registerWith(registrarFor("dev.flutter.plugins.e2e.E2EPlugin")); + IntegrationTestPlugin.registerWith( + registrarFor("dev.flutter.plugins.integration_test.IntegrationTestPlugin")); PathProviderPlugin.registerWith( registrarFor("io.flutter.plugins.pathprovider.PathProviderPlugin")); } diff --git a/packages/path_provider/path_provider/example/pubspec.yaml b/packages/path_provider/path_provider/example/pubspec.yaml index 1d6a50c2ca0f..983b3b82eb53 100644 --- a/packages/path_provider/path_provider/example/pubspec.yaml +++ b/packages/path_provider/path_provider/example/pubspec.yaml @@ -8,7 +8,8 @@ dependencies: path: ../ dev_dependencies: - e2e: ^0.2.1 + integration_test: + path: ../../../integration_test flutter_driver: sdk: flutter test: any diff --git a/packages/path_provider/path_provider/example/test_driver/path_provider_e2e.dart b/packages/path_provider/path_provider/example/test_driver/path_provider_e2e.dart index d3a1019a7c23..8eb8520b5b4b 100644 --- a/packages/path_provider/path_provider/example/test_driver/path_provider_e2e.dart +++ b/packages/path_provider/path_provider/example/test_driver/path_provider_e2e.dart @@ -7,10 +7,10 @@ import 'dart:async'; import 'dart:io'; import 'package:flutter_test/flutter_test.dart'; import 'package:path_provider/path_provider.dart'; -import 'package:e2e/e2e.dart'; +import 'package:integration_test/integration_test.dart'; void main() { - E2EWidgetsFlutterBinding.ensureInitialized(); + IntegrationTestWidgetsFlutterBinding.ensureInitialized(); testWidgets('getTemporaryDirectory', (WidgetTester tester) async { final Directory result = await getTemporaryDirectory(); diff --git a/packages/path_provider/path_provider/example/test_driver/path_provider_e2e_test.dart b/packages/path_provider/path_provider/example/test_driver/path_provider_e2e_test.dart index f3aa9e218d82..7a2c21338786 100644 --- a/packages/path_provider/path_provider/example/test_driver/path_provider_e2e_test.dart +++ b/packages/path_provider/path_provider/example/test_driver/path_provider_e2e_test.dart @@ -3,13 +3,15 @@ // BSD-style license that can be found in the LICENSE file. import 'dart:async'; +import 'dart:convert'; import 'dart:io'; import 'package:flutter_driver/flutter_driver.dart'; Future main() async { final FlutterDriver driver = await FlutterDriver.connect(); - final String result = + final String data = await driver.requestData(null, timeout: const Duration(minutes: 1)); await driver.close(); - exit(result == 'pass' ? 0 : 1); + final Map result = jsonDecode(data); + exit(result['result'] == 'true' ? 0 : 1); } diff --git a/packages/path_provider/path_provider/pubspec.yaml b/packages/path_provider/path_provider/pubspec.yaml index d83911ddc2a8..7781c76331d4 100644 --- a/packages/path_provider/path_provider/pubspec.yaml +++ b/packages/path_provider/path_provider/pubspec.yaml @@ -2,7 +2,7 @@ name: path_provider description: Flutter plugin for getting commonly used locations on the Android & iOS file systems, such as the temp and app data directories. homepage: https://github.com/flutter/plugins/tree/master/packages/path_provider/path_provider -version: 1.6.11 +version: 1.6.14 flutter: plugin: @@ -25,7 +25,8 @@ dependencies: path_provider_linux: ^0.0.1 dev_dependencies: - e2e: ^0.2.1 + integration_test: + path: ../../integration_test flutter_test: sdk: flutter flutter_driver: diff --git a/packages/path_provider/path_provider/test/path_provider_e2e.dart b/packages/path_provider/path_provider/test/path_provider_e2e.dart index 545671e32b01..18570aeca57e 100644 --- a/packages/path_provider/path_provider/test/path_provider_e2e.dart +++ b/packages/path_provider/path_provider/test/path_provider_e2e.dart @@ -1,9 +1,9 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:path_provider/path_provider.dart'; -import 'package:e2e/e2e.dart'; +import 'package:integration_test/integration_test.dart'; void main() { - E2EWidgetsFlutterBinding.ensureInitialized(); + IntegrationTestWidgetsFlutterBinding.ensureInitialized(); testWidgets('Can get temporary directory', (WidgetTester tester) async { final String tempPath = (await getTemporaryDirectory()).path; diff --git a/packages/path_provider/path_provider_linux/CHANGELOG.md b/packages/path_provider/path_provider_linux/CHANGELOG.md index 2b95b38b9c59..baec603b426f 100644 --- a/packages/path_provider/path_provider_linux/CHANGELOG.md +++ b/packages/path_provider/path_provider_linux/CHANGELOG.md @@ -1,4 +1,8 @@ -## 0.1.0 +## 0.1.1 - NOT PUBLISHED +* Reverts changes on 0.1.0, which broke the tree. + + +## 0.1.0 - NOT PUBLISHED * This release updates getApplicationSupportPath to use the application ID instead of the executable name. * No migration is provided, so any older apps that were using this path will now have a different directory. @@ -11,4 +15,4 @@ ## 0.0.1 * The initial implementation of path_provider for Linux * Implements getApplicationSupportPath, getApplicationDocumentsPath, getDownloadsPath, and getTemporaryPath - + diff --git a/packages/path_provider/path_provider_linux/example/pubspec.yaml b/packages/path_provider/path_provider_linux/example/pubspec.yaml index 4d758b78733a..85dbb24bbb29 100644 --- a/packages/path_provider/path_provider_linux/example/pubspec.yaml +++ b/packages/path_provider/path_provider_linux/example/pubspec.yaml @@ -24,7 +24,8 @@ dev_dependencies: sdk: flutter flutter_driver: sdk: flutter - e2e: ^0.2.1 + integration_test: + path: ../../../integration_test # For information on the generic Dart part of this file, see the # following page: https://dart.dev/tools/pub/pubspec diff --git a/packages/path_provider/path_provider_linux/example/test_driver/path_provider_e2e.dart b/packages/path_provider/path_provider_linux/example/test_driver/path_provider_e2e.dart index c90c4d96dde5..18ac49debbd4 100644 --- a/packages/path_provider/path_provider_linux/example/test_driver/path_provider_e2e.dart +++ b/packages/path_provider/path_provider_linux/example/test_driver/path_provider_e2e.dart @@ -5,10 +5,10 @@ import 'dart:io'; import 'package:flutter_test/flutter_test.dart'; import 'package:path_provider/path_provider.dart'; -import 'package:e2e/e2e.dart'; +import 'package:integration_test/integration_test.dart'; void main() { - E2EWidgetsFlutterBinding.ensureInitialized(); + IntegrationTestWidgetsFlutterBinding.ensureInitialized(); testWidgets('getTemporaryDirectory', (WidgetTester tester) async { final Directory result = await getTemporaryDirectory(); diff --git a/packages/path_provider/path_provider_linux/example/test_driver/path_provider_e2e_test.dart b/packages/path_provider/path_provider_linux/example/test_driver/path_provider_e2e_test.dart index f3aa9e218d82..7a2c21338786 100644 --- a/packages/path_provider/path_provider_linux/example/test_driver/path_provider_e2e_test.dart +++ b/packages/path_provider/path_provider_linux/example/test_driver/path_provider_e2e_test.dart @@ -3,13 +3,15 @@ // BSD-style license that can be found in the LICENSE file. import 'dart:async'; +import 'dart:convert'; import 'dart:io'; import 'package:flutter_driver/flutter_driver.dart'; Future main() async { final FlutterDriver driver = await FlutterDriver.connect(); - final String result = + final String data = await driver.requestData(null, timeout: const Duration(minutes: 1)); await driver.close(); - exit(result == 'pass' ? 0 : 1); + final Map result = jsonDecode(data); + exit(result['result'] == 'true' ? 0 : 1); } diff --git a/packages/path_provider/path_provider_linux/lib/path_provider_linux.dart b/packages/path_provider/path_provider_linux/lib/path_provider_linux.dart index 9441f6ea5f5d..09d2447c0a6c 100644 --- a/packages/path_provider/path_provider_linux/lib/path_provider_linux.dart +++ b/packages/path_provider/path_provider_linux/lib/path_provider_linux.dart @@ -3,21 +3,11 @@ // found in the LICENSE file. import 'dart:io'; import 'dart:async'; -import 'dart:ffi'; -import 'package:ffi/ffi.dart'; import 'package:xdg_directories/xdg_directories.dart' as xdg; import 'package:path/path.dart' as path; import 'package:path_provider_platform_interface/path_provider_platform_interface.dart'; -// GApplication* g_application_get_default(); -typedef g_application_get_default_c = IntPtr Function(); -typedef g_application_get_default_dart = int Function(); - -// const gchar* g_application_get_application_id(GApplication* application); -typedef g_application_get_application_id_c = Pointer Function(IntPtr); -typedef g_application_get_application_id_dart = Pointer Function(int); - /// The linux implementation of [PathProviderPlatform] /// /// This class implements the `package:path_provider` functionality for linux @@ -32,43 +22,11 @@ class PathProviderLinux extends PathProviderPlatform { return Future.value("/tmp"); } - // Gets the application ID set in GApplication. - String _getApplicationId() { - DynamicLibrary gio; - try { - gio = DynamicLibrary.open('libgio-2.0.so'); - } on ArgumentError { - return null; - } - var g_application_get_default = gio.lookupFunction< - g_application_get_default_c, - g_application_get_default_dart>('g_application_get_default'); - var app = g_application_get_default(); - if (app == 0) return null; - - var g_application_get_application_id = gio.lookupFunction< - g_application_get_application_id_c, - g_application_get_application_id_dart>( - 'g_application_get_application_id'); - var app_id = g_application_get_application_id(app); - if (app_id == null) return null; - - return Utf8.fromUtf8(app_id); - } - - // Gets the unique ID for this application. - Future _getId() async { - var appId = _getApplicationId(); - if (appId != null) return appId; - - // Fall back to using the executable name. - return path.basenameWithoutExtension( - await File('/proc/self/exe').resolveSymbolicLinks()); - } - @override Future getApplicationSupportPath() async { - final directory = Directory(path.join(xdg.dataHome.path, await _getId())); + final processName = path.basenameWithoutExtension( + await File('/proc/self/exe').resolveSymbolicLinks()); + final directory = Directory(path.join(xdg.dataHome.path, processName)); // Creating the directory if it doesn't exist, because mobile implementations assume the directory exists if (!await directory.exists()) { await directory.create(recursive: true); diff --git a/packages/path_provider/path_provider_linux/pubspec.yaml b/packages/path_provider/path_provider_linux/pubspec.yaml index a6d48bfa59aa..b0188fd2a4c7 100644 --- a/packages/path_provider/path_provider_linux/pubspec.yaml +++ b/packages/path_provider/path_provider_linux/pubspec.yaml @@ -1,6 +1,6 @@ name: path_provider_linux description: linux implementation of the path_provider plugin -version: 0.1.0 +version: 0.1.1 homepage: https://github.com/flutter/plugins/tree/master/packages/path_provider/path_provider_linux flutter: @@ -15,7 +15,6 @@ environment: flutter: ">=1.10.0 <2.0.0" dependencies: - ffi: ^0.1.3 path: ^1.6.4 xdg_directories: ^0.1.0 path_provider_platform_interface: ^1.0.1 diff --git a/packages/path_provider/path_provider_macos/example/android/app/src/androidTest/java/EmbeddingV1ActivityTest.java b/packages/path_provider/path_provider_macos/example/android/app/src/androidTest/java/EmbeddingV1ActivityTest.java index cce04b79f516..50cb342715cb 100644 --- a/packages/path_provider/path_provider_macos/example/android/app/src/androidTest/java/EmbeddingV1ActivityTest.java +++ b/packages/path_provider/path_provider_macos/example/android/app/src/androidTest/java/EmbeddingV1ActivityTest.java @@ -2,12 +2,12 @@ package io.flutter.plugins.pathprovider; import androidx.test.rule.ActivityTestRule; -import dev.flutter.plugins.e2e.FlutterRunner; +import dev.flutter.plugins.integration_test.FlutterTestRunner; import io.flutter.plugins.pathproviderexample.EmbeddingV1Activity; import org.junit.Rule; import org.junit.runner.RunWith; -@RunWith(FlutterRunner.class) +@RunWith(FlutterTestRunner.class) public class EmbeddingV1ActivityTest { @Rule public ActivityTestRule rule = diff --git a/packages/path_provider/path_provider_macos/example/android/app/src/androidTest/java/MainActivityTest.java b/packages/path_provider/path_provider_macos/example/android/app/src/androidTest/java/MainActivityTest.java index 7bdd449981f5..09e000524a69 100644 --- a/packages/path_provider/path_provider_macos/example/android/app/src/androidTest/java/MainActivityTest.java +++ b/packages/path_provider/path_provider_macos/example/android/app/src/androidTest/java/MainActivityTest.java @@ -2,12 +2,12 @@ package io.flutter.plugins.pathprovider; import androidx.test.rule.ActivityTestRule; -import dev.flutter.plugins.e2e.FlutterRunner; +import dev.flutter.plugins.integration_test.FlutterTestRunner; import io.flutter.plugins.pathproviderexample.MainActivity; import org.junit.Rule; import org.junit.runner.RunWith; -@RunWith(FlutterRunner.class) +@RunWith(FlutterTestRunner.class) public class MainActivityTest { @Rule public ActivityTestRule rule = new ActivityTestRule<>(MainActivity.class); } diff --git a/packages/path_provider/path_provider_macos/example/android/app/src/main/java/io/flutter/plugins/pathproviderexample/MainActivity.java b/packages/path_provider/path_provider_macos/example/android/app/src/main/java/io/flutter/plugins/pathproviderexample/MainActivity.java index 36372960fe9c..bdecc162446a 100644 --- a/packages/path_provider/path_provider_macos/example/android/app/src/main/java/io/flutter/plugins/pathproviderexample/MainActivity.java +++ b/packages/path_provider/path_provider_macos/example/android/app/src/main/java/io/flutter/plugins/pathproviderexample/MainActivity.java @@ -4,7 +4,7 @@ package io.flutter.plugins.pathproviderexample; -import dev.flutter.plugins.e2e.E2EPlugin; +import dev.flutter.plugins.integration_test.IntegrationTestPlugin; import io.flutter.embedding.android.FlutterActivity; import io.flutter.embedding.engine.FlutterEngine; import io.flutter.plugins.pathprovider.PathProviderPlugin; @@ -14,6 +14,6 @@ public class MainActivity extends FlutterActivity { @Override public void configureFlutterEngine(FlutterEngine flutterEngine) { flutterEngine.getPlugins().add(new PathProviderPlugin()); - flutterEngine.getPlugins().add(new E2EPlugin()); + flutterEngine.getPlugins().add(new IntegrationTestPlugin()); } } diff --git a/packages/path_provider/path_provider_macos/example/pubspec.yaml b/packages/path_provider/path_provider_macos/example/pubspec.yaml index e3242b83ad99..1ba991dc8160 100644 --- a/packages/path_provider/path_provider_macos/example/pubspec.yaml +++ b/packages/path_provider/path_provider_macos/example/pubspec.yaml @@ -9,7 +9,8 @@ dependencies: path: ../ dev_dependencies: - e2e: ^0.2.1 + integration_test: + path: ../../../integration_test flutter_driver: sdk: flutter test: any diff --git a/packages/path_provider/path_provider_macos/example/test_driver/path_provider_e2e.dart b/packages/path_provider/path_provider_macos/example/test_driver/path_provider_e2e.dart index 6cb8362b76d5..58a4d1805cb0 100644 --- a/packages/path_provider/path_provider_macos/example/test_driver/path_provider_e2e.dart +++ b/packages/path_provider/path_provider_macos/example/test_driver/path_provider_e2e.dart @@ -5,10 +5,10 @@ import 'dart:io'; import 'package:flutter_test/flutter_test.dart'; import 'package:path_provider/path_provider.dart'; -import 'package:e2e/e2e.dart'; +import 'package:integration_test/integration_test.dart'; void main() { - E2EWidgetsFlutterBinding.ensureInitialized(); + IntegrationTestWidgetsFlutterBinding.ensureInitialized(); testWidgets('getTemporaryDirectory', (WidgetTester tester) async { final Directory result = await getTemporaryDirectory(); diff --git a/packages/path_provider/path_provider_macos/example/test_driver/path_provider_e2e_test.dart b/packages/path_provider/path_provider_macos/example/test_driver/path_provider_e2e_test.dart index f3aa9e218d82..7a2c21338786 100644 --- a/packages/path_provider/path_provider_macos/example/test_driver/path_provider_e2e_test.dart +++ b/packages/path_provider/path_provider_macos/example/test_driver/path_provider_e2e_test.dart @@ -3,13 +3,15 @@ // BSD-style license that can be found in the LICENSE file. import 'dart:async'; +import 'dart:convert'; import 'dart:io'; import 'package:flutter_driver/flutter_driver.dart'; Future main() async { final FlutterDriver driver = await FlutterDriver.connect(); - final String result = + final String data = await driver.requestData(null, timeout: const Duration(minutes: 1)); await driver.close(); - exit(result == 'pass' ? 0 : 1); + final Map result = jsonDecode(data); + exit(result['result'] == 'true' ? 0 : 1); } diff --git a/packages/path_provider/path_provider_platform_interface/CHANGELOG.md b/packages/path_provider/path_provider_platform_interface/CHANGELOG.md index 605ab6560ac5..23f71c99a678 100644 --- a/packages/path_provider/path_provider_platform_interface/CHANGELOG.md +++ b/packages/path_provider/path_provider_platform_interface/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.0.3 + +* Increase upper range of `package:platform` constraint to allow 3.X versions. + ## 1.0.2 * Update lower bound of dart dependency to 2.1.0. diff --git a/packages/path_provider/path_provider_platform_interface/pubspec.yaml b/packages/path_provider/path_provider_platform_interface/pubspec.yaml index d87224717221..9f1293883826 100644 --- a/packages/path_provider/path_provider_platform_interface/pubspec.yaml +++ b/packages/path_provider/path_provider_platform_interface/pubspec.yaml @@ -3,13 +3,13 @@ description: A common platform interface for the path_provider plugin. homepage: https://github.com/flutter/plugins/tree/master/packages/path_provider/path_provider_platform_interface # NOTE: We strongly prefer non-breaking changes, even at the expense of a # less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes -version: 1.0.2 +version: 1.0.3 dependencies: flutter: sdk: flutter meta: ^1.0.5 - platform: ^2.0.0 + platform: ">=2.0.0 <4.0.0" plugin_platform_interface: ^1.0.1 dev_dependencies: diff --git a/packages/plugin_platform_interface/CHANGELOG.md b/packages/plugin_platform_interface/CHANGELOG.md index 1c240eaa901d..5fb208e3dbd8 100644 --- a/packages/plugin_platform_interface/CHANGELOG.md +++ b/packages/plugin_platform_interface/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.0.3 + +* Fix (url) typos in documentation. + ## 1.0.2 * Make the pedantic dev_dependency explicit. diff --git a/packages/plugin_platform_interface/README.md b/packages/plugin_platform_interface/README.md index 9fdbd8a75fe2..2fe44328c7dc 100644 --- a/packages/plugin_platform_interface/README.md +++ b/packages/plugin_platform_interface/README.md @@ -1,6 +1,6 @@ # plugin_platform_interface -This package provides a base class for platform interfaces of [federated flutter plugins](https://fluter.dev/go/federated-plugins). +This package provides a base class for platform interfaces of [federated flutter plugins](https://flutter.dev/go/federated-plugins). Platform implementations should extend their platform interface classes rather than implement it as newly added methods to platform interfaces are not considered as breaking changes. Extending a platform diff --git a/packages/plugin_platform_interface/pubspec.yaml b/packages/plugin_platform_interface/pubspec.yaml index b5f263ca4e69..37ea8052b6df 100644 --- a/packages/plugin_platform_interface/pubspec.yaml +++ b/packages/plugin_platform_interface/pubspec.yaml @@ -12,9 +12,9 @@ description: Reusable base class for Flutter plugin platform interfaces. # be done when absolutely necessary and after the ecosystem has already migrated to 1.X.Y version # that is forward compatible with 2.0.0 (ideally the ecosystem have migrated to depend on: # `plugin_platform_interface: >=1.X.Y <3.0.0`). -version: 1.0.2 +version: 1.0.3 -homepage: https://github.com/flutter/plugins/plugin_platform_interface +homepage: https://github.com/flutter/plugins/tree/master/packages/plugin_platform_interface environment: sdk: ">=2.1.0 <3.0.0" diff --git a/packages/quick_actions/CHANGELOG.md b/packages/quick_actions/CHANGELOG.md index 1afc92af7c06..b850014e2bf0 100644 --- a/packages/quick_actions/CHANGELOG.md +++ b/packages/quick_actions/CHANGELOG.md @@ -1,3 +1,12 @@ +## 0.4.0+8 + +* Update package:e2e -> package:integration_test + +## 0.4.0+7 + +* Update package:e2e reference to use the local version in the flutter/plugins + repository. + ## 0.4.0+6 * Post-v2 Android embedding cleanup. diff --git a/packages/quick_actions/example/android/app/src/main/java/io/flutter/plugins/quickactionsexample/EmbeddingV1ActivityTest.java b/packages/quick_actions/example/android/app/src/main/java/io/flutter/plugins/quickactionsexample/EmbeddingV1ActivityTest.java index b3e2a08c44b4..6fc6778159e5 100644 --- a/packages/quick_actions/example/android/app/src/main/java/io/flutter/plugins/quickactionsexample/EmbeddingV1ActivityTest.java +++ b/packages/quick_actions/example/android/app/src/main/java/io/flutter/plugins/quickactionsexample/EmbeddingV1ActivityTest.java @@ -5,11 +5,11 @@ package io.flutter.plugins.quickactionsexample; import androidx.test.rule.ActivityTestRule; -import dev.flutter.plugins.e2e.FlutterRunner; +import dev.flutter.plugins.integration_test.FlutterTestRunner; import org.junit.Rule; import org.junit.runner.RunWith; -@RunWith(FlutterRunner.class) +@RunWith(FlutterTestRunner.class) public class EmbeddingV1ActivityTest { @Rule public ActivityTestRule rule = diff --git a/packages/quick_actions/example/android/app/src/main/java/io/flutter/plugins/quickactionsexample/FlutterActivityTest.java b/packages/quick_actions/example/android/app/src/main/java/io/flutter/plugins/quickactionsexample/FlutterActivityTest.java index d80914056b35..9ce1e8dfe4ea 100644 --- a/packages/quick_actions/example/android/app/src/main/java/io/flutter/plugins/quickactionsexample/FlutterActivityTest.java +++ b/packages/quick_actions/example/android/app/src/main/java/io/flutter/plugins/quickactionsexample/FlutterActivityTest.java @@ -5,12 +5,12 @@ package io.flutter.plugins.quickactionsexample; import androidx.test.rule.ActivityTestRule; -import dev.flutter.plugins.e2e.FlutterRunner; +import dev.flutter.plugins.integration_test.FlutterTestRunner; import io.flutter.embedding.android.FlutterActivity; import org.junit.Rule; import org.junit.runner.RunWith; -@RunWith(FlutterRunner.class) +@RunWith(FlutterTestRunner.class) public class FlutterActivityTest { @Rule public ActivityTestRule rule = new ActivityTestRule<>(FlutterActivity.class); diff --git a/packages/quick_actions/example/pubspec.yaml b/packages/quick_actions/example/pubspec.yaml index 058d208a7690..6f9c0efd01af 100644 --- a/packages/quick_actions/example/pubspec.yaml +++ b/packages/quick_actions/example/pubspec.yaml @@ -10,7 +10,8 @@ dependencies: dev_dependencies: flutter_driver: sdk: flutter - e2e: ^0.2.0 + integration_test: + path: ../../integration_test pedantic: ^1.8.0 flutter: diff --git a/packages/quick_actions/example/test_driver/quick_actions_e2e.dart b/packages/quick_actions/example/test_driver/quick_actions_e2e.dart index 41d35b874640..03ecfe491d93 100644 --- a/packages/quick_actions/example/test_driver/quick_actions_e2e.dart +++ b/packages/quick_actions/example/test_driver/quick_actions_e2e.dart @@ -3,11 +3,11 @@ // BSD-style license that can be found in the LICENSE file. import 'package:flutter_test/flutter_test.dart'; -import 'package:e2e/e2e.dart'; +import 'package:integration_test/integration_test.dart'; import 'package:quick_actions/quick_actions.dart'; void main() { - E2EWidgetsFlutterBinding.ensureInitialized(); + IntegrationTestWidgetsFlutterBinding.ensureInitialized(); testWidgets('Can set shortcuts', (WidgetTester tester) async { final QuickActions quickActions = QuickActions(); diff --git a/packages/quick_actions/example/test_driver/quick_actions_e2e_test.dart b/packages/quick_actions/example/test_driver/quick_actions_e2e_test.dart index f3aa9e218d82..7a2c21338786 100644 --- a/packages/quick_actions/example/test_driver/quick_actions_e2e_test.dart +++ b/packages/quick_actions/example/test_driver/quick_actions_e2e_test.dart @@ -3,13 +3,15 @@ // BSD-style license that can be found in the LICENSE file. import 'dart:async'; +import 'dart:convert'; import 'dart:io'; import 'package:flutter_driver/flutter_driver.dart'; Future main() async { final FlutterDriver driver = await FlutterDriver.connect(); - final String result = + final String data = await driver.requestData(null, timeout: const Duration(minutes: 1)); await driver.close(); - exit(result == 'pass' ? 0 : 1); + final Map result = jsonDecode(data); + exit(result['result'] == 'true' ? 0 : 1); } diff --git a/packages/quick_actions/pubspec.yaml b/packages/quick_actions/pubspec.yaml index 570c864ffe38..0468bbfd2e00 100644 --- a/packages/quick_actions/pubspec.yaml +++ b/packages/quick_actions/pubspec.yaml @@ -2,7 +2,7 @@ name: quick_actions description: Flutter plugin for creating shortcuts on home screen, also known as Quick Actions on iOS and App Shortcuts on Android. homepage: https://github.com/flutter/plugins/tree/master/packages/quick_actions -version: 0.4.0+6 +version: 0.4.0+8 flutter: plugin: @@ -23,7 +23,8 @@ dev_dependencies: mockito: ^3.0.0 flutter_test: sdk: flutter - e2e: ^0.2.0 + integration_test: + path: ../integration_test pedantic: ^1.8.0 environment: diff --git a/packages/sensors/CHANGELOG.md b/packages/sensors/CHANGELOG.md index 55501436c45e..cd70351e1c2b 100644 --- a/packages/sensors/CHANGELOG.md +++ b/packages/sensors/CHANGELOG.md @@ -1,3 +1,12 @@ +## 0.4.2+4 + +* Update package:e2e -> package:integration_test + +## 0.4.2+3 + +* Update package:e2e reference to use the local version in the flutter/plugins + repository. + ## 0.4.2+2 * Post-v2 Android embedding cleanup. diff --git a/packages/sensors/example/android/app/src/main/java/io/flutter/plugins/sensorsexample/EmbeddingV1Activity.java b/packages/sensors/example/android/app/src/main/java/io/flutter/plugins/sensorsexample/EmbeddingV1Activity.java index 80f6c8223377..390819ba0e49 100644 --- a/packages/sensors/example/android/app/src/main/java/io/flutter/plugins/sensorsexample/EmbeddingV1Activity.java +++ b/packages/sensors/example/android/app/src/main/java/io/flutter/plugins/sensorsexample/EmbeddingV1Activity.java @@ -5,7 +5,7 @@ package io.flutter.plugins.sensorsexample; import android.os.Bundle; -import dev.flutter.plugins.e2e.E2EPlugin; +import dev.flutter.plugins.integration_test.IntegrationTestPlugin; import io.flutter.app.FlutterActivity; import io.flutter.plugins.sensors.SensorsPlugin; @@ -13,7 +13,8 @@ public class EmbeddingV1Activity extends FlutterActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - E2EPlugin.registerWith(registrarFor("dev.flutter.plugins.e2e.E2EPlugin")); + IntegrationTestPlugin.registerWith( + registrarFor("dev.flutter.plugins.integration_test.IntegrationTestPlugin")); SensorsPlugin.registerWith(registrarFor("io.flutter.plugins.sensors.SensorsPlugin")); } } diff --git a/packages/sensors/example/android/app/src/main/java/io/flutter/plugins/sensorsexample/EmbeddingV1ActivityTest.java b/packages/sensors/example/android/app/src/main/java/io/flutter/plugins/sensorsexample/EmbeddingV1ActivityTest.java index 6d0274f50e2c..ace170bb78ac 100644 --- a/packages/sensors/example/android/app/src/main/java/io/flutter/plugins/sensorsexample/EmbeddingV1ActivityTest.java +++ b/packages/sensors/example/android/app/src/main/java/io/flutter/plugins/sensorsexample/EmbeddingV1ActivityTest.java @@ -1,11 +1,11 @@ package io.flutter.plugins.sensorsexample; import androidx.test.rule.ActivityTestRule; -import dev.flutter.plugins.e2e.FlutterRunner; +import dev.flutter.plugins.integration_test.FlutterTestRunner; import org.junit.Rule; import org.junit.runner.RunWith; -@RunWith(FlutterRunner.class) +@RunWith(FlutterTestRunner.class) public class EmbeddingV1ActivityTest { @Rule public ActivityTestRule rule = diff --git a/packages/sensors/example/android/app/src/main/java/io/flutter/plugins/sensorsexample/FlutterActivityTest.java b/packages/sensors/example/android/app/src/main/java/io/flutter/plugins/sensorsexample/FlutterActivityTest.java index a0fff8201676..0835b0f5945a 100644 --- a/packages/sensors/example/android/app/src/main/java/io/flutter/plugins/sensorsexample/FlutterActivityTest.java +++ b/packages/sensors/example/android/app/src/main/java/io/flutter/plugins/sensorsexample/FlutterActivityTest.java @@ -5,12 +5,12 @@ package io.flutter.plugins.sensorsexample; import androidx.test.rule.ActivityTestRule; -import dev.flutter.plugins.e2e.FlutterRunner; +import dev.flutter.plugins.integration_test.FlutterTestRunner; import io.flutter.embedding.android.FlutterActivity; import org.junit.Rule; import org.junit.runner.RunWith; -@RunWith(FlutterRunner.class) +@RunWith(FlutterTestRunner.class) public class FlutterActivityTest { @Rule public ActivityTestRule rule = new ActivityTestRule<>(FlutterActivity.class); diff --git a/packages/sensors/example/pubspec.yaml b/packages/sensors/example/pubspec.yaml index 69aa54ca94e4..eb46c611a43a 100644 --- a/packages/sensors/example/pubspec.yaml +++ b/packages/sensors/example/pubspec.yaml @@ -10,7 +10,8 @@ dependencies: dev_dependencies: flutter_driver: sdk: flutter - e2e: ^0.2.0 + integration_test: + path: ../../integration_test pedantic: ^1.8.0 flutter: diff --git a/packages/sensors/example/test_driver/test/sensors_e2e_test.dart b/packages/sensors/example/test_driver/test/sensors_e2e_test.dart index f3aa9e218d82..7a2c21338786 100644 --- a/packages/sensors/example/test_driver/test/sensors_e2e_test.dart +++ b/packages/sensors/example/test_driver/test/sensors_e2e_test.dart @@ -3,13 +3,15 @@ // BSD-style license that can be found in the LICENSE file. import 'dart:async'; +import 'dart:convert'; import 'dart:io'; import 'package:flutter_driver/flutter_driver.dart'; Future main() async { final FlutterDriver driver = await FlutterDriver.connect(); - final String result = + final String data = await driver.requestData(null, timeout: const Duration(minutes: 1)); await driver.close(); - exit(result == 'pass' ? 0 : 1); + final Map result = jsonDecode(data); + exit(result['result'] == 'true' ? 0 : 1); } diff --git a/packages/sensors/pubspec.yaml b/packages/sensors/pubspec.yaml index 3e3aed165a8e..0daaf08521bc 100644 --- a/packages/sensors/pubspec.yaml +++ b/packages/sensors/pubspec.yaml @@ -5,7 +5,7 @@ homepage: https://github.com/flutter/plugins/tree/master/packages/sensors # 0.4.y+z is compatible with 1.0.0, if you land a breaking change bump # the version to 2.0.0. # See more details: https://github.com/flutter/flutter/wiki/Package-migration-to-1.0.0 -version: 0.4.2+2 +version: 0.4.2+4 flutter: plugin: @@ -24,7 +24,8 @@ dev_dependencies: test: ^1.3.0 flutter_test: sdk: flutter - e2e: ^0.2.0 + integration_test: + path: ../integration_test mockito: ^4.1.1 pedantic: ^1.8.0 diff --git a/packages/sensors/test/sensors_e2e.dart b/packages/sensors/test/sensors_e2e.dart index acc356dfc235..ea1db0375f38 100644 --- a/packages/sensors/test/sensors_e2e.dart +++ b/packages/sensors/test/sensors_e2e.dart @@ -5,10 +5,10 @@ import 'dart:async'; import 'package:flutter_test/flutter_test.dart'; import 'package:sensors/sensors.dart'; -import 'package:e2e/e2e.dart'; +import 'package:integration_test/integration_test.dart'; void main() { - E2EWidgetsFlutterBinding.ensureInitialized(); + IntegrationTestWidgetsFlutterBinding.ensureInitialized(); testWidgets('Can subscript to accelerometerEvents and get non-null events', (WidgetTester tester) async { diff --git a/packages/share/CHANGELOG.md b/packages/share/CHANGELOG.md index b06f8de45f4a..8c3814d2f559 100644 --- a/packages/share/CHANGELOG.md +++ b/packages/share/CHANGELOG.md @@ -1,3 +1,12 @@ +## 0.6.4+5 + +* Update package:e2e -> package:integration_test + +## 0.6.4+4 + +* Update package:e2e reference to use the local version in the flutter/plugins + repository. + ## 0.6.4+3 * Post-v2 Android embedding cleanup. diff --git a/packages/share/example/android/app/src/main/java/io/flutter/plugins/shareexample/EmbeddingV1Activity.java b/packages/share/example/android/app/src/main/java/io/flutter/plugins/shareexample/EmbeddingV1Activity.java index e12d223b0f7b..70b1a8d8f09e 100644 --- a/packages/share/example/android/app/src/main/java/io/flutter/plugins/shareexample/EmbeddingV1Activity.java +++ b/packages/share/example/android/app/src/main/java/io/flutter/plugins/shareexample/EmbeddingV1Activity.java @@ -5,7 +5,7 @@ package io.flutter.plugins.shareexample; import android.os.Bundle; -import dev.flutter.plugins.e2e.E2EPlugin; +import dev.flutter.plugins.integration_test.IntegrationTestPlugin; import io.flutter.app.FlutterActivity; import io.flutter.plugins.share.SharePlugin; @@ -14,7 +14,8 @@ public class EmbeddingV1Activity extends FlutterActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - E2EPlugin.registerWith(registrarFor("dev.flutter.plugins.e2e.E2EPlugin")); + IntegrationTestPlugin.registerWith( + registrarFor("dev.flutter.plugins.integration_test.IntegrationTestPlugin")); SharePlugin.registerWith(registrarFor("io.flutter.plugins.share.SharePlugin")); } } diff --git a/packages/share/example/android/app/src/main/java/io/flutter/plugins/shareexample/EmbeddingV1ActivityTest.java b/packages/share/example/android/app/src/main/java/io/flutter/plugins/shareexample/EmbeddingV1ActivityTest.java index 958541165806..b5ae4ef061b6 100644 --- a/packages/share/example/android/app/src/main/java/io/flutter/plugins/shareexample/EmbeddingV1ActivityTest.java +++ b/packages/share/example/android/app/src/main/java/io/flutter/plugins/shareexample/EmbeddingV1ActivityTest.java @@ -1,11 +1,11 @@ package io.flutter.plugins.shareexample; import androidx.test.rule.ActivityTestRule; -import dev.flutter.plugins.e2e.FlutterRunner; +import dev.flutter.plugins.integration_test.FlutterTestRunner; import org.junit.Rule; import org.junit.runner.RunWith; -@RunWith(FlutterRunner.class) +@RunWith(FlutterTestRunner.class) public class EmbeddingV1ActivityTest { @Rule public ActivityTestRule rule = diff --git a/packages/share/example/android/app/src/main/java/io/flutter/plugins/shareexample/FlutterActivityTest.java b/packages/share/example/android/app/src/main/java/io/flutter/plugins/shareexample/FlutterActivityTest.java index 58c9edf6762a..3b73737f15b2 100644 --- a/packages/share/example/android/app/src/main/java/io/flutter/plugins/shareexample/FlutterActivityTest.java +++ b/packages/share/example/android/app/src/main/java/io/flutter/plugins/shareexample/FlutterActivityTest.java @@ -5,12 +5,12 @@ package io.flutter.plugins.shareexample; import androidx.test.rule.ActivityTestRule; -import dev.flutter.plugins.e2e.FlutterRunner; +import dev.flutter.plugins.integration_test.FlutterTestRunner; import io.flutter.embedding.android.FlutterActivity; import org.junit.Rule; import org.junit.runner.RunWith; -@RunWith(FlutterRunner.class) +@RunWith(FlutterTestRunner.class) public class FlutterActivityTest { @Rule public ActivityTestRule rule = new ActivityTestRule<>(FlutterActivity.class); diff --git a/packages/share/example/pubspec.yaml b/packages/share/example/pubspec.yaml index f69de96283b3..4830b7186019 100644 --- a/packages/share/example/pubspec.yaml +++ b/packages/share/example/pubspec.yaml @@ -10,7 +10,8 @@ dependencies: dev_dependencies: flutter_driver: sdk: flutter - e2e: ^0.2.0 + integration_test: + path: ../../integration_test pedantic: ^1.8.0 flutter: @@ -19,4 +20,4 @@ flutter: environment: sdk: ">=2.0.0-dev.28.0 <3.0.0" flutter: ">=1.9.1+hotfix.2 <2.0.0" - + diff --git a/packages/share/example/test_driver/test/share_e2e_test.dart b/packages/share/example/test_driver/test/share_e2e_test.dart index f3aa9e218d82..7a2c21338786 100644 --- a/packages/share/example/test_driver/test/share_e2e_test.dart +++ b/packages/share/example/test_driver/test/share_e2e_test.dart @@ -3,13 +3,15 @@ // BSD-style license that can be found in the LICENSE file. import 'dart:async'; +import 'dart:convert'; import 'dart:io'; import 'package:flutter_driver/flutter_driver.dart'; Future main() async { final FlutterDriver driver = await FlutterDriver.connect(); - final String result = + final String data = await driver.requestData(null, timeout: const Duration(minutes: 1)); await driver.close(); - exit(result == 'pass' ? 0 : 1); + final Map result = jsonDecode(data); + exit(result['result'] == 'true' ? 0 : 1); } diff --git a/packages/share/pubspec.yaml b/packages/share/pubspec.yaml index f695dbd936c8..f5e545ca112e 100644 --- a/packages/share/pubspec.yaml +++ b/packages/share/pubspec.yaml @@ -5,7 +5,7 @@ homepage: https://github.com/flutter/plugins/tree/master/packages/share # 0.6.y+z is compatible with 1.0.0, if you land a breaking change bump # the version to 2.0.0. # See more details: https://github.com/flutter/flutter/wiki/Package-migration-to-1.0.0 -version: 0.6.4+3 +version: 0.6.4+5 flutter: plugin: @@ -26,7 +26,8 @@ dev_dependencies: mockito: ^3.0.0 flutter_test: sdk: flutter - e2e: ^0.2.0 + integration_test: + path: ../integration_test pedantic: ^1.8.0 environment: diff --git a/packages/share/test/share_e2e.dart b/packages/share/test/share_e2e.dart index eb990222b009..08a19ce2c27b 100644 --- a/packages/share/test/share_e2e.dart +++ b/packages/share/test/share_e2e.dart @@ -4,10 +4,10 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:share/share.dart'; -import 'package:e2e/e2e.dart'; +import 'package:integration_test/integration_test.dart'; void main() { - E2EWidgetsFlutterBinding.ensureInitialized(); + IntegrationTestWidgetsFlutterBinding.ensureInitialized(); testWidgets('Can launch share', (WidgetTester tester) async { expect(Share.share('message', subject: 'title'), completes); diff --git a/packages/shared_preferences/shared_preferences/CHANGELOG.md b/packages/shared_preferences/shared_preferences/CHANGELOG.md index d17bbb96289b..3f4edca10dc2 100644 --- a/packages/shared_preferences/shared_preferences/CHANGELOG.md +++ b/packages/shared_preferences/shared_preferences/CHANGELOG.md @@ -1,3 +1,12 @@ +## 0.5.10 + +* Update package:e2e -> package:integration_test + +## 0.5.9 + +* Update package:e2e reference to use the local version in the flutter/plugins + repository. + ## 0.5.8 * Support Linux by default. diff --git a/packages/shared_preferences/shared_preferences/example/android/app/src/main/java/io/flutter/plugins/sharedpreferencesexample/EmbeddingV1Activity.java b/packages/shared_preferences/shared_preferences/example/android/app/src/main/java/io/flutter/plugins/sharedpreferencesexample/EmbeddingV1Activity.java index 33f294231602..7a748792f566 100644 --- a/packages/shared_preferences/shared_preferences/example/android/app/src/main/java/io/flutter/plugins/sharedpreferencesexample/EmbeddingV1Activity.java +++ b/packages/shared_preferences/shared_preferences/example/android/app/src/main/java/io/flutter/plugins/sharedpreferencesexample/EmbeddingV1Activity.java @@ -5,7 +5,7 @@ package io.flutter.plugins.sharedpreferencesexample; import android.os.Bundle; -import dev.flutter.plugins.e2e.E2EPlugin; +import dev.flutter.plugins.integration_test.IntegrationTestPlugin; import io.flutter.app.FlutterActivity; import io.flutter.plugins.sharedpreferences.SharedPreferencesPlugin; @@ -14,7 +14,8 @@ public class EmbeddingV1Activity extends FlutterActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - E2EPlugin.registerWith(registrarFor("dev.flutter.plugins.e2e.E2EPlugin")); + IntegrationTestPlugin.registerWith( + registrarFor("dev.flutter.plugins.integration_test.IntegrationTestPlugin")); SharedPreferencesPlugin.registerWith( registrarFor("io.flutter.plugins.sharedpreferences.SharedPreferencesPlugin")); } diff --git a/packages/shared_preferences/shared_preferences/example/android/app/src/main/java/io/flutter/plugins/sharedpreferencesexample/EmbeddingV1ActivityTest.java b/packages/shared_preferences/shared_preferences/example/android/app/src/main/java/io/flutter/plugins/sharedpreferencesexample/EmbeddingV1ActivityTest.java index 3eb677b21163..d37f5549e3ec 100644 --- a/packages/shared_preferences/shared_preferences/example/android/app/src/main/java/io/flutter/plugins/sharedpreferencesexample/EmbeddingV1ActivityTest.java +++ b/packages/shared_preferences/shared_preferences/example/android/app/src/main/java/io/flutter/plugins/sharedpreferencesexample/EmbeddingV1ActivityTest.java @@ -2,11 +2,11 @@ package io.flutter.plugins.sharedpreferencesexample; import androidx.test.rule.ActivityTestRule; -import dev.flutter.plugins.e2e.FlutterRunner; +import dev.flutter.plugins.integration_test.FlutterTestRunner; import org.junit.Rule; import org.junit.runner.RunWith; -@RunWith(FlutterRunner.class) +@RunWith(FlutterTestRunner.class) public class EmbeddingV1ActivityTest { @Rule public ActivityTestRule rule = diff --git a/packages/shared_preferences/shared_preferences/example/android/app/src/main/java/io/flutter/plugins/sharedpreferencesexample/FlutterActivityTest.java b/packages/shared_preferences/shared_preferences/example/android/app/src/main/java/io/flutter/plugins/sharedpreferencesexample/FlutterActivityTest.java index e1ec837fa99a..7a63d6d90c91 100644 --- a/packages/shared_preferences/shared_preferences/example/android/app/src/main/java/io/flutter/plugins/sharedpreferencesexample/FlutterActivityTest.java +++ b/packages/shared_preferences/shared_preferences/example/android/app/src/main/java/io/flutter/plugins/sharedpreferencesexample/FlutterActivityTest.java @@ -5,12 +5,12 @@ package io.flutter.plugins.sharedpreferencesexample; import androidx.test.rule.ActivityTestRule; -import dev.flutter.plugins.e2e.FlutterRunner; +import dev.flutter.plugins.integration_test.FlutterTestRunner; import io.flutter.embedding.android.FlutterActivity; import org.junit.Rule; import org.junit.runner.RunWith; -@RunWith(FlutterRunner.class) +@RunWith(FlutterTestRunner.class) public class FlutterActivityTest { @Rule public ActivityTestRule rule = new ActivityTestRule<>(FlutterActivity.class); diff --git a/packages/shared_preferences/shared_preferences/example/pubspec.yaml b/packages/shared_preferences/shared_preferences/example/pubspec.yaml index 1e6df16e581b..2b970949bee6 100644 --- a/packages/shared_preferences/shared_preferences/example/pubspec.yaml +++ b/packages/shared_preferences/shared_preferences/example/pubspec.yaml @@ -11,7 +11,8 @@ dev_dependencies: flutter_driver: sdk: flutter test: any - e2e: ^0.2.0 + integration_test: + path: ../../../integration_test pedantic: ^1.8.0 flutter: diff --git a/packages/shared_preferences/shared_preferences/example/test_driver/shared_preferences_e2e.dart b/packages/shared_preferences/shared_preferences/example/test_driver/shared_preferences_e2e.dart index b693df2131ed..0d49ed95dd2d 100644 --- a/packages/shared_preferences/shared_preferences/example/test_driver/shared_preferences_e2e.dart +++ b/packages/shared_preferences/shared_preferences/example/test_driver/shared_preferences_e2e.dart @@ -1,10 +1,10 @@ import 'dart:async'; import 'package:flutter_test/flutter_test.dart'; import 'package:shared_preferences/shared_preferences.dart'; -import 'package:e2e/e2e.dart'; +import 'package:integration_test/integration_test.dart'; void main() { - E2EWidgetsFlutterBinding.ensureInitialized(); + IntegrationTestWidgetsFlutterBinding.ensureInitialized(); group('$SharedPreferences', () { const Map kTestValues = { diff --git a/packages/shared_preferences/shared_preferences/example/test_driver/shared_preferences_e2e_test.dart b/packages/shared_preferences/shared_preferences/example/test_driver/shared_preferences_e2e_test.dart index f3aa9e218d82..7a2c21338786 100644 --- a/packages/shared_preferences/shared_preferences/example/test_driver/shared_preferences_e2e_test.dart +++ b/packages/shared_preferences/shared_preferences/example/test_driver/shared_preferences_e2e_test.dart @@ -3,13 +3,15 @@ // BSD-style license that can be found in the LICENSE file. import 'dart:async'; +import 'dart:convert'; import 'dart:io'; import 'package:flutter_driver/flutter_driver.dart'; Future main() async { final FlutterDriver driver = await FlutterDriver.connect(); - final String result = + final String data = await driver.requestData(null, timeout: const Duration(minutes: 1)); await driver.close(); - exit(result == 'pass' ? 0 : 1); + final Map result = jsonDecode(data); + exit(result['result'] == 'true' ? 0 : 1); } diff --git a/packages/shared_preferences/shared_preferences/pubspec.yaml b/packages/shared_preferences/shared_preferences/pubspec.yaml index ca8c443cd753..04b7813a2a99 100644 --- a/packages/shared_preferences/shared_preferences/pubspec.yaml +++ b/packages/shared_preferences/shared_preferences/pubspec.yaml @@ -5,7 +5,7 @@ homepage: https://github.com/flutter/plugins/tree/master/packages/shared_prefere # 0.5.y+z is compatible with 1.0.0, if you land a breaking change bump # the version to 2.0.0. # See more details: https://github.com/flutter/flutter/wiki/Package-migration-to-1.0.0 -version: 0.5.8 +version: 0.5.10 flutter: plugin: @@ -42,7 +42,8 @@ dev_dependencies: flutter_driver: sdk: flutter test: any - e2e: ^0.2.0 + integration_test: + path: ../../integration_test pedantic: ^1.8.0 environment: diff --git a/packages/shared_preferences/shared_preferences_linux/example/pubspec.yaml b/packages/shared_preferences/shared_preferences_linux/example/pubspec.yaml index 8e726d642274..5936e3ace02f 100644 --- a/packages/shared_preferences/shared_preferences_linux/example/pubspec.yaml +++ b/packages/shared_preferences/shared_preferences_linux/example/pubspec.yaml @@ -18,7 +18,8 @@ dev_dependencies: flutter_driver: sdk: flutter test: any - e2e: ^0.2.0 + integration_test: + path: ../../../integration_test pedantic: ^1.8.0 flutter: diff --git a/packages/shared_preferences/shared_preferences_linux/example/test_driver/shared_preferences_e2e.dart b/packages/shared_preferences/shared_preferences_linux/example/test_driver/shared_preferences_e2e.dart index b693df2131ed..0d49ed95dd2d 100644 --- a/packages/shared_preferences/shared_preferences_linux/example/test_driver/shared_preferences_e2e.dart +++ b/packages/shared_preferences/shared_preferences_linux/example/test_driver/shared_preferences_e2e.dart @@ -1,10 +1,10 @@ import 'dart:async'; import 'package:flutter_test/flutter_test.dart'; import 'package:shared_preferences/shared_preferences.dart'; -import 'package:e2e/e2e.dart'; +import 'package:integration_test/integration_test.dart'; void main() { - E2EWidgetsFlutterBinding.ensureInitialized(); + IntegrationTestWidgetsFlutterBinding.ensureInitialized(); group('$SharedPreferences', () { const Map kTestValues = { diff --git a/packages/shared_preferences/shared_preferences_linux/example/test_driver/shared_preferences_e2e_test.dart b/packages/shared_preferences/shared_preferences_linux/example/test_driver/shared_preferences_e2e_test.dart index f3aa9e218d82..7a2c21338786 100644 --- a/packages/shared_preferences/shared_preferences_linux/example/test_driver/shared_preferences_e2e_test.dart +++ b/packages/shared_preferences/shared_preferences_linux/example/test_driver/shared_preferences_e2e_test.dart @@ -3,13 +3,15 @@ // BSD-style license that can be found in the LICENSE file. import 'dart:async'; +import 'dart:convert'; import 'dart:io'; import 'package:flutter_driver/flutter_driver.dart'; Future main() async { final FlutterDriver driver = await FlutterDriver.connect(); - final String result = + final String data = await driver.requestData(null, timeout: const Duration(minutes: 1)); await driver.close(); - exit(result == 'pass' ? 0 : 1); + final Map result = jsonDecode(data); + exit(result['result'] == 'true' ? 0 : 1); } diff --git a/packages/shared_preferences/shared_preferences_macos/example/pubspec.yaml b/packages/shared_preferences/shared_preferences_macos/example/pubspec.yaml index c31a0637253c..de4b6ed9d379 100644 --- a/packages/shared_preferences/shared_preferences_macos/example/pubspec.yaml +++ b/packages/shared_preferences/shared_preferences_macos/example/pubspec.yaml @@ -12,7 +12,8 @@ dev_dependencies: flutter_driver: sdk: flutter test: any - e2e: ^0.2.0 + integration_test: + path: ../../../integration_test pedantic: ^1.8.0 flutter: diff --git a/packages/shared_preferences/shared_preferences_macos/example/test_driver/shared_preferences_e2e.dart b/packages/shared_preferences/shared_preferences_macos/example/test_driver/shared_preferences_e2e.dart index b693df2131ed..0d49ed95dd2d 100644 --- a/packages/shared_preferences/shared_preferences_macos/example/test_driver/shared_preferences_e2e.dart +++ b/packages/shared_preferences/shared_preferences_macos/example/test_driver/shared_preferences_e2e.dart @@ -1,10 +1,10 @@ import 'dart:async'; import 'package:flutter_test/flutter_test.dart'; import 'package:shared_preferences/shared_preferences.dart'; -import 'package:e2e/e2e.dart'; +import 'package:integration_test/integration_test.dart'; void main() { - E2EWidgetsFlutterBinding.ensureInitialized(); + IntegrationTestWidgetsFlutterBinding.ensureInitialized(); group('$SharedPreferences', () { const Map kTestValues = { diff --git a/packages/shared_preferences/shared_preferences_macos/example/test_driver/shared_preferences_e2e_test.dart b/packages/shared_preferences/shared_preferences_macos/example/test_driver/shared_preferences_e2e_test.dart index f3aa9e218d82..7a2c21338786 100644 --- a/packages/shared_preferences/shared_preferences_macos/example/test_driver/shared_preferences_e2e_test.dart +++ b/packages/shared_preferences/shared_preferences_macos/example/test_driver/shared_preferences_e2e_test.dart @@ -3,13 +3,15 @@ // BSD-style license that can be found in the LICENSE file. import 'dart:async'; +import 'dart:convert'; import 'dart:io'; import 'package:flutter_driver/flutter_driver.dart'; Future main() async { final FlutterDriver driver = await FlutterDriver.connect(); - final String result = + final String data = await driver.requestData(null, timeout: const Duration(minutes: 1)); await driver.close(); - exit(result == 'pass' ? 0 : 1); + final Map result = jsonDecode(data); + exit(result['result'] == 'true' ? 0 : 1); } diff --git a/packages/url_launcher/url_launcher/example/android/app/src/androidTestDebug/java/io/flutter/plugins/urllauncherexample/EmbeddingV1ActivityTest.java b/packages/url_launcher/url_launcher/example/android/app/src/androidTestDebug/java/io/flutter/plugins/urllauncherexample/EmbeddingV1ActivityTest.java index bae2957ab81e..fb66478feed8 100644 --- a/packages/url_launcher/url_launcher/example/android/app/src/androidTestDebug/java/io/flutter/plugins/urllauncherexample/EmbeddingV1ActivityTest.java +++ b/packages/url_launcher/url_launcher/example/android/app/src/androidTestDebug/java/io/flutter/plugins/urllauncherexample/EmbeddingV1ActivityTest.java @@ -1,11 +1,11 @@ package io.flutter.plugins.urllauncherexample; import androidx.test.rule.ActivityTestRule; -import dev.flutter.plugins.e2e.FlutterRunner; +import dev.flutter.plugins.integration_test.FlutterTestRunner; import org.junit.Rule; import org.junit.runner.RunWith; -@RunWith(FlutterRunner.class) +@RunWith(FlutterTestRunner.class) public class EmbeddingV1ActivityTest { @Rule public ActivityTestRule rule = diff --git a/packages/url_launcher/url_launcher/example/android/app/src/androidTestDebug/java/io/flutter/plugins/urllauncherexample/MainActivityTest.java b/packages/url_launcher/url_launcher/example/android/app/src/androidTestDebug/java/io/flutter/plugins/urllauncherexample/MainActivityTest.java index a9000fb29228..5b50523f7f40 100644 --- a/packages/url_launcher/url_launcher/example/android/app/src/androidTestDebug/java/io/flutter/plugins/urllauncherexample/MainActivityTest.java +++ b/packages/url_launcher/url_launcher/example/android/app/src/androidTestDebug/java/io/flutter/plugins/urllauncherexample/MainActivityTest.java @@ -1,12 +1,12 @@ package io.flutter.plugins.urllauncherexample; import androidx.test.rule.ActivityTestRule; -import dev.flutter.plugins.e2e.FlutterRunner; +import dev.flutter.plugins.integration_test.FlutterTestRunner; import io.flutter.embedding.android.FlutterActivity; import org.junit.Rule; import org.junit.runner.RunWith; -@RunWith(FlutterRunner.class) +@RunWith(FlutterTestRunner.class) public class FlutterActivityTest { @Rule public ActivityTestRule rule = new ActivityTestRule<>(FlutterActivity.class); diff --git a/packages/url_launcher/url_launcher/example/android/app/src/main/java/io/flutter/plugins/urllauncherexample/EmbeddingV1Activity.java b/packages/url_launcher/url_launcher/example/android/app/src/main/java/io/flutter/plugins/urllauncherexample/EmbeddingV1Activity.java index fc6aa5622573..39afc642ddb9 100644 --- a/packages/url_launcher/url_launcher/example/android/app/src/main/java/io/flutter/plugins/urllauncherexample/EmbeddingV1Activity.java +++ b/packages/url_launcher/url_launcher/example/android/app/src/main/java/io/flutter/plugins/urllauncherexample/EmbeddingV1Activity.java @@ -5,7 +5,7 @@ package io.flutter.plugins.urllauncherexample; import android.os.Bundle; -import dev.flutter.plugins.e2e.E2EPlugin; +import dev.flutter.plugins.integration_test.IntegrationTestPlugin; import io.flutter.app.FlutterActivity; import io.flutter.plugins.urllauncher.UrlLauncherPlugin; @@ -14,7 +14,8 @@ public class EmbeddingV1Activity extends FlutterActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - E2EPlugin.registerWith(registrarFor("dev.flutter.plugins.e2e.E2EPlugin")); + IntegrationTestPlugin.registerWith( + registrarFor("dev.flutter.plugins.integration_test.IntegrationTestPlugin")); UrlLauncherPlugin.registerWith( registrarFor("io.flutter.plugins.urllauncher.UrlLauncherPlugin")); } diff --git a/packages/url_launcher/url_launcher/example/pubspec.yaml b/packages/url_launcher/url_launcher/example/pubspec.yaml index 1eb3e603696f..b48445c3a7e9 100644 --- a/packages/url_launcher/url_launcher/example/pubspec.yaml +++ b/packages/url_launcher/url_launcher/example/pubspec.yaml @@ -8,7 +8,8 @@ dependencies: path: ../ dev_dependencies: - e2e: "^0.2.0" + integration_test: + path: ../../../integration_test flutter_driver: sdk: flutter pedantic: ^1.8.0 diff --git a/packages/url_launcher/url_launcher/example/test_driver/url_launcher_e2e.dart b/packages/url_launcher/url_launcher/example/test_driver/url_launcher_e2e.dart index 6cf1168c81bd..fe51d94aa3a9 100644 --- a/packages/url_launcher/url_launcher/example/test_driver/url_launcher_e2e.dart +++ b/packages/url_launcher/url_launcher/example/test_driver/url_launcher_e2e.dart @@ -6,11 +6,11 @@ import 'dart:io' show Platform; import 'package:flutter/foundation.dart' show kIsWeb; import 'package:flutter_test/flutter_test.dart'; -import 'package:e2e/e2e.dart'; +import 'package:integration_test/integration_test.dart'; import 'package:url_launcher/url_launcher.dart'; void main() { - E2EWidgetsFlutterBinding.ensureInitialized(); + IntegrationTestWidgetsFlutterBinding.ensureInitialized(); test('canLaunch', () async { expect(await canLaunch('randomstring'), false); diff --git a/packages/url_launcher/url_launcher/example/test_driver/url_launcher_e2e_test.dart b/packages/url_launcher/url_launcher/example/test_driver/url_launcher_e2e_test.dart index 1bcd0d37f450..7a2c21338786 100644 --- a/packages/url_launcher/url_launcher/example/test_driver/url_launcher_e2e_test.dart +++ b/packages/url_launcher/url_launcher/example/test_driver/url_launcher_e2e_test.dart @@ -2,14 +2,16 @@ // for details. 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:flutter_driver/flutter_driver.dart'; Future main() async { final FlutterDriver driver = await FlutterDriver.connect(); - final String result = + final String data = await driver.requestData(null, timeout: const Duration(minutes: 1)); await driver.close(); - exit(result == 'pass' ? 0 : 1); + final Map result = jsonDecode(data); + exit(result['result'] == 'true' ? 0 : 1); } diff --git a/packages/url_launcher/url_launcher_linux/example/pubspec.yaml b/packages/url_launcher/url_launcher_linux/example/pubspec.yaml index a4d08f30d6b4..c9d0c32f5cb6 100644 --- a/packages/url_launcher/url_launcher_linux/example/pubspec.yaml +++ b/packages/url_launcher/url_launcher_linux/example/pubspec.yaml @@ -9,7 +9,8 @@ dependencies: path: ../ dev_dependencies: - e2e: "^0.2.0" + integration_test: + path: ../../../integration_test flutter_driver: sdk: flutter pedantic: ^1.8.0 diff --git a/packages/url_launcher/url_launcher_linux/example/test_driver/url_launcher_e2e.dart b/packages/url_launcher/url_launcher_linux/example/test_driver/url_launcher_e2e.dart index 516835cec33b..0b25516c2a29 100644 --- a/packages/url_launcher/url_launcher_linux/example/test_driver/url_launcher_e2e.dart +++ b/packages/url_launcher/url_launcher_linux/example/test_driver/url_launcher_e2e.dart @@ -3,11 +3,11 @@ // BSD-style license that can be found in the LICENSE file. import 'package:flutter_test/flutter_test.dart'; -import 'package:e2e/e2e.dart'; +import 'package:integration_test/integration_test.dart'; import 'package:url_launcher/url_launcher.dart'; void main() { - E2EWidgetsFlutterBinding.ensureInitialized(); + IntegrationTestWidgetsFlutterBinding.ensureInitialized(); test('canLaunch', () async { expect(await canLaunch('randomstring'), false); diff --git a/packages/url_launcher/url_launcher_linux/example/test_driver/url_launcher_e2e_test.dart b/packages/url_launcher/url_launcher_linux/example/test_driver/url_launcher_e2e_test.dart index 1bcd0d37f450..7a2c21338786 100644 --- a/packages/url_launcher/url_launcher_linux/example/test_driver/url_launcher_e2e_test.dart +++ b/packages/url_launcher/url_launcher_linux/example/test_driver/url_launcher_e2e_test.dart @@ -2,14 +2,16 @@ // for details. 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:flutter_driver/flutter_driver.dart'; Future main() async { final FlutterDriver driver = await FlutterDriver.connect(); - final String result = + final String data = await driver.requestData(null, timeout: const Duration(minutes: 1)); await driver.close(); - exit(result == 'pass' ? 0 : 1); + final Map result = jsonDecode(data); + exit(result['result'] == 'true' ? 0 : 1); } diff --git a/packages/url_launcher/url_launcher_macos/example/android/app/src/androidTestDebug/java/io/flutter/plugins/urllauncherexample/EmbeddingV1ActivityTest.java b/packages/url_launcher/url_launcher_macos/example/android/app/src/androidTestDebug/java/io/flutter/plugins/urllauncherexample/EmbeddingV1ActivityTest.java index bae2957ab81e..fb66478feed8 100644 --- a/packages/url_launcher/url_launcher_macos/example/android/app/src/androidTestDebug/java/io/flutter/plugins/urllauncherexample/EmbeddingV1ActivityTest.java +++ b/packages/url_launcher/url_launcher_macos/example/android/app/src/androidTestDebug/java/io/flutter/plugins/urllauncherexample/EmbeddingV1ActivityTest.java @@ -1,11 +1,11 @@ package io.flutter.plugins.urllauncherexample; import androidx.test.rule.ActivityTestRule; -import dev.flutter.plugins.e2e.FlutterRunner; +import dev.flutter.plugins.integration_test.FlutterTestRunner; import org.junit.Rule; import org.junit.runner.RunWith; -@RunWith(FlutterRunner.class) +@RunWith(FlutterTestRunner.class) public class EmbeddingV1ActivityTest { @Rule public ActivityTestRule rule = diff --git a/packages/url_launcher/url_launcher_macos/example/android/app/src/androidTestDebug/java/io/flutter/plugins/urllauncherexample/FlutterActivityTest.java b/packages/url_launcher/url_launcher_macos/example/android/app/src/androidTestDebug/java/io/flutter/plugins/urllauncherexample/FlutterActivityTest.java index a9000fb29228..5b50523f7f40 100644 --- a/packages/url_launcher/url_launcher_macos/example/android/app/src/androidTestDebug/java/io/flutter/plugins/urllauncherexample/FlutterActivityTest.java +++ b/packages/url_launcher/url_launcher_macos/example/android/app/src/androidTestDebug/java/io/flutter/plugins/urllauncherexample/FlutterActivityTest.java @@ -1,12 +1,12 @@ package io.flutter.plugins.urllauncherexample; import androidx.test.rule.ActivityTestRule; -import dev.flutter.plugins.e2e.FlutterRunner; +import dev.flutter.plugins.integration_test.FlutterTestRunner; import io.flutter.embedding.android.FlutterActivity; import org.junit.Rule; import org.junit.runner.RunWith; -@RunWith(FlutterRunner.class) +@RunWith(FlutterTestRunner.class) public class FlutterActivityTest { @Rule public ActivityTestRule rule = new ActivityTestRule<>(FlutterActivity.class); diff --git a/packages/url_launcher/url_launcher_macos/example/android/app/src/main/java/io/flutter/plugins/urllauncherexample/EmbeddingV1Activity.java b/packages/url_launcher/url_launcher_macos/example/android/app/src/main/java/io/flutter/plugins/urllauncherexample/EmbeddingV1Activity.java index fc6aa5622573..39afc642ddb9 100644 --- a/packages/url_launcher/url_launcher_macos/example/android/app/src/main/java/io/flutter/plugins/urllauncherexample/EmbeddingV1Activity.java +++ b/packages/url_launcher/url_launcher_macos/example/android/app/src/main/java/io/flutter/plugins/urllauncherexample/EmbeddingV1Activity.java @@ -5,7 +5,7 @@ package io.flutter.plugins.urllauncherexample; import android.os.Bundle; -import dev.flutter.plugins.e2e.E2EPlugin; +import dev.flutter.plugins.integration_test.IntegrationTestPlugin; import io.flutter.app.FlutterActivity; import io.flutter.plugins.urllauncher.UrlLauncherPlugin; @@ -14,7 +14,8 @@ public class EmbeddingV1Activity extends FlutterActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - E2EPlugin.registerWith(registrarFor("dev.flutter.plugins.e2e.E2EPlugin")); + IntegrationTestPlugin.registerWith( + registrarFor("dev.flutter.plugins.integration_test.IntegrationTestPlugin")); UrlLauncherPlugin.registerWith( registrarFor("io.flutter.plugins.urllauncher.UrlLauncherPlugin")); } diff --git a/packages/url_launcher/url_launcher_macos/example/pubspec.yaml b/packages/url_launcher/url_launcher_macos/example/pubspec.yaml index 1125b6da73e9..0fab67e8af1b 100644 --- a/packages/url_launcher/url_launcher_macos/example/pubspec.yaml +++ b/packages/url_launcher/url_launcher_macos/example/pubspec.yaml @@ -9,7 +9,8 @@ dependencies: path: ../ dev_dependencies: - e2e: "^0.2.0" + integration_test: + path: ../../../integration_test flutter_driver: sdk: flutter pedantic: ^1.8.0 diff --git a/packages/url_launcher/url_launcher_macos/example/test_driver/url_launcher_e2e.dart b/packages/url_launcher/url_launcher_macos/example/test_driver/url_launcher_e2e.dart index e1d75f93b326..676b78c3bbfb 100644 --- a/packages/url_launcher/url_launcher_macos/example/test_driver/url_launcher_e2e.dart +++ b/packages/url_launcher/url_launcher_macos/example/test_driver/url_launcher_e2e.dart @@ -3,11 +3,11 @@ // BSD-style license that can be found in the LICENSE file. import 'package:flutter_test/flutter_test.dart'; -import 'package:e2e/e2e.dart'; +import 'package:integration_test/integration_test.dart'; import 'package:url_launcher/url_launcher.dart'; void main() { - E2EWidgetsFlutterBinding.ensureInitialized(); + IntegrationTestWidgetsFlutterBinding.ensureInitialized(); test('canLaunch', () async { expect(await canLaunch('randomstring'), false); diff --git a/packages/url_launcher/url_launcher_macos/example/test_driver/url_launcher_e2e_test.dart b/packages/url_launcher/url_launcher_macos/example/test_driver/url_launcher_e2e_test.dart index 1bcd0d37f450..7a2c21338786 100644 --- a/packages/url_launcher/url_launcher_macos/example/test_driver/url_launcher_e2e_test.dart +++ b/packages/url_launcher/url_launcher_macos/example/test_driver/url_launcher_e2e_test.dart @@ -2,14 +2,16 @@ // for details. 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:flutter_driver/flutter_driver.dart'; Future main() async { final FlutterDriver driver = await FlutterDriver.connect(); - final String result = + final String data = await driver.requestData(null, timeout: const Duration(minutes: 1)); await driver.close(); - exit(result == 'pass' ? 0 : 1); + final Map result = jsonDecode(data); + exit(result['result'] == 'true' ? 0 : 1); } diff --git a/packages/url_launcher/url_launcher_web/CHANGELOG.md b/packages/url_launcher/url_launcher_web/CHANGELOG.md index e9f7bde63fda..ed8014297776 100644 --- a/packages/url_launcher/url_launcher_web/CHANGELOG.md +++ b/packages/url_launcher/url_launcher_web/CHANGELOG.md @@ -1,3 +1,7 @@ +# 0.1.2+1 + +- Update docs + # 0.1.2 - Adds "tel" and "sms" support diff --git a/packages/url_launcher/url_launcher_web/README.md b/packages/url_launcher/url_launcher_web/README.md index 374301032778..21ab2fc52927 100644 --- a/packages/url_launcher/url_launcher_web/README.md +++ b/packages/url_launcher/url_launcher_web/README.md @@ -34,4 +34,4 @@ dependencies: Once you have the `url_launcher_web` dependency in your pubspec, you should be able to use `package:url_launcher` as normal. -[1]: ../url_launcher/url_launcher +[1]: ../url_launcher diff --git a/packages/url_launcher/url_launcher_web/pubspec.yaml b/packages/url_launcher/url_launcher_web/pubspec.yaml index 9a5beac00b94..727b396ba2e6 100644 --- a/packages/url_launcher/url_launcher_web/pubspec.yaml +++ b/packages/url_launcher/url_launcher_web/pubspec.yaml @@ -4,7 +4,7 @@ homepage: https://github.com/flutter/plugins/tree/master/packages/url_launcher/u # 0.1.y+z is compatible with 1.0.0, if you land a breaking change bump # the version to 2.0.0. # See more details: https://github.com/flutter/flutter/wiki/Package-migration-to-1.0.0 -version: 0.1.2 +version: 0.1.2+1 flutter: plugin: diff --git a/packages/video_player/video_player/CHANGELOG.md b/packages/video_player/video_player/CHANGELOG.md index e3f49e736411..1fdfad6256f4 100644 --- a/packages/video_player/video_player/CHANGELOG.md +++ b/packages/video_player/video_player/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.10.12 + +* Introduce VideoPlayerOptions to set the audio mix mode. + ## 0.10.11+2 * Fix aspectRatio calculation when size.width or size.height are zero. diff --git a/packages/video_player/video_player/android/src/main/java/io/flutter/plugins/videoplayer/Messages.java b/packages/video_player/video_player/android/src/main/java/io/flutter/plugins/videoplayer/Messages.java index 7bba51b21f98..003ca18f23cb 100644 --- a/packages/video_player/video_player/android/src/main/java/io/flutter/plugins/videoplayer/Messages.java +++ b/packages/video_player/video_player/android/src/main/java/io/flutter/plugins/videoplayer/Messages.java @@ -223,6 +223,31 @@ static PositionMessage fromMap(HashMap map) { } } + /** Generated class from Pigeon that represents data sent in messages. */ + public static class MixWithOthersMessage { + private Boolean mixWithOthers; + + public Boolean getMixWithOthers() { + return mixWithOthers; + } + + public void setMixWithOthers(Boolean setterArg) { + this.mixWithOthers = setterArg; + } + + HashMap toMap() { + HashMap toMapResult = new HashMap(); + toMapResult.put("mixWithOthers", mixWithOthers); + return toMapResult; + } + + static MixWithOthersMessage fromMap(HashMap map) { + MixWithOthersMessage fromMapResult = new MixWithOthersMessage(); + fromMapResult.mixWithOthers = (Boolean) map.get("mixWithOthers"); + return fromMapResult; + } + } + /** Generated interface from Pigeon that represents a handler of messages from Flutter. */ public interface VideoPlayerApi { void initialize(); @@ -243,6 +268,8 @@ public interface VideoPlayerApi { void pause(TextureMessage arg); + void setMixWithOthers(MixWithOthersMessage arg); + /** Sets up an instance of `VideoPlayerApi` to handle messages through the `binaryMessenger` */ public static void setup(BinaryMessenger binaryMessenger, VideoPlayerApi api) { { @@ -469,6 +496,31 @@ public void onMessage(Object message, BasicMessageChannel.Reply reply) { channel.setMessageHandler(null); } } + { + BasicMessageChannel channel = + new BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.VideoPlayerApi.setMixWithOthers", + new StandardMessageCodec()); + if (api != null) { + channel.setMessageHandler( + new BasicMessageChannel.MessageHandler() { + public void onMessage(Object message, BasicMessageChannel.Reply reply) { + MixWithOthersMessage input = MixWithOthersMessage.fromMap((HashMap) message); + HashMap wrapped = new HashMap(); + try { + api.setMixWithOthers(input); + wrapped.put("result", null); + } catch (Exception exception) { + wrapped.put("error", wrapError(exception)); + } + reply.reply(wrapped); + } + }); + } else { + channel.setMessageHandler(null); + } + } } } diff --git a/packages/video_player/video_player/android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayer.java b/packages/video_player/video_player/android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayer.java index 9db281d38b86..801c2ca3bff2 100644 --- a/packages/video_player/video_player/android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayer.java +++ b/packages/video_player/video_player/android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayer.java @@ -56,14 +56,18 @@ final class VideoPlayer { private boolean isInitialized = false; + private final VideoPlayerOptions options; + VideoPlayer( Context context, EventChannel eventChannel, TextureRegistry.SurfaceTextureEntry textureEntry, String dataSource, - String formatHint) { + String formatHint, + VideoPlayerOptions options) { this.eventChannel = eventChannel; this.textureEntry = textureEntry; + this.options = options; TrackSelector trackSelector = new DefaultTrackSelector(); exoPlayer = ExoPlayerFactory.newSimpleInstance(context, trackSelector); @@ -163,7 +167,7 @@ public void onCancel(Object o) { surface = new Surface(textureEntry.surfaceTexture()); exoPlayer.setVideoSurface(surface); - setAudioAttributes(exoPlayer); + setAudioAttributes(exoPlayer, options.mixWithOthers); exoPlayer.addListener( new EventListener() { @@ -203,10 +207,10 @@ void sendBufferingUpdate() { } @SuppressWarnings("deprecation") - private static void setAudioAttributes(SimpleExoPlayer exoPlayer) { + private static void setAudioAttributes(SimpleExoPlayer exoPlayer, boolean isMixMode) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { exoPlayer.setAudioAttributes( - new AudioAttributes.Builder().setContentType(C.CONTENT_TYPE_MOVIE).build()); + new AudioAttributes.Builder().setContentType(C.CONTENT_TYPE_MOVIE).build(), !isMixMode); } else { exoPlayer.setAudioStreamType(C.STREAM_TYPE_MUSIC); } diff --git a/packages/video_player/video_player/android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayerOptions.java b/packages/video_player/video_player/android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayerOptions.java new file mode 100644 index 000000000000..7381f4a941a5 --- /dev/null +++ b/packages/video_player/video_player/android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayerOptions.java @@ -0,0 +1,5 @@ +package io.flutter.plugins.videoplayer; + +class VideoPlayerOptions { + public boolean mixWithOthers; +} diff --git a/packages/video_player/video_player/android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayerPlugin.java b/packages/video_player/video_player/android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayerPlugin.java index 3ec40e5fa2c4..a22a4f2d7ae4 100644 --- a/packages/video_player/video_player/android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayerPlugin.java +++ b/packages/video_player/video_player/android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayerPlugin.java @@ -13,6 +13,7 @@ import io.flutter.plugin.common.PluginRegistry.Registrar; import io.flutter.plugins.videoplayer.Messages.CreateMessage; import io.flutter.plugins.videoplayer.Messages.LoopingMessage; +import io.flutter.plugins.videoplayer.Messages.MixWithOthersMessage; import io.flutter.plugins.videoplayer.Messages.PositionMessage; import io.flutter.plugins.videoplayer.Messages.TextureMessage; import io.flutter.plugins.videoplayer.Messages.VideoPlayerApi; @@ -25,6 +26,7 @@ public class VideoPlayerPlugin implements FlutterPlugin, VideoPlayerApi { private static final String TAG = "VideoPlayerPlugin"; private final LongSparseArray videoPlayers = new LongSparseArray<>(); private FlutterState flutterState; + private VideoPlayerOptions options = new VideoPlayerOptions(); /** Register this with the v2 embedding for the plugin to respond to lifecycle callbacks. */ public VideoPlayerPlugin() {} @@ -113,7 +115,8 @@ public TextureMessage create(CreateMessage arg) { eventChannel, handle, "asset:///" + assetLookupKey, - null); + null, + options); videoPlayers.put(handle.id(), player); } else { player = @@ -122,7 +125,8 @@ public TextureMessage create(CreateMessage arg) { eventChannel, handle, arg.getUri(), - arg.getFormatHint()); + arg.getFormatHint(), + options); videoPlayers.put(handle.id(), player); } @@ -170,6 +174,11 @@ public void pause(TextureMessage arg) { player.pause(); } + @Override + public void setMixWithOthers(MixWithOthersMessage arg) { + options.mixWithOthers = arg.getMixWithOthers(); + } + private interface KeyForAssetFn { String get(String asset); } diff --git a/packages/video_player/video_player/example/android/app/src/main/java/io/flutter/plugins/videoplayerexample/EmbeddingV1Activity.java b/packages/video_player/video_player/example/android/app/src/main/java/io/flutter/plugins/videoplayerexample/EmbeddingV1Activity.java index de29b463fca9..b21435f82fde 100644 --- a/packages/video_player/video_player/example/android/app/src/main/java/io/flutter/plugins/videoplayerexample/EmbeddingV1Activity.java +++ b/packages/video_player/video_player/example/android/app/src/main/java/io/flutter/plugins/videoplayerexample/EmbeddingV1Activity.java @@ -5,7 +5,7 @@ package io.flutter.plugins.videoplayerexample; import android.os.Bundle; -import dev.flutter.plugins.e2e.E2EPlugin; +import dev.flutter.plugins.integration_test.IntegrationTestPlugin; import io.flutter.app.FlutterActivity; import io.flutter.plugins.videoplayer.VideoPlayerPlugin; @@ -13,7 +13,8 @@ public class EmbeddingV1Activity extends FlutterActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - E2EPlugin.registerWith(registrarFor("dev.flutter.plugins.e2e.E2EPlugin")); + IntegrationTestPlugin.registerWith( + registrarFor("dev.flutter.plugins.integration_test.IntegrationTestPlugin")); VideoPlayerPlugin.registerWith( registrarFor("io.flutter.plugins.videoplayer.VideoPlayerPlugin")); } diff --git a/packages/video_player/video_player/example/lib/main.dart b/packages/video_player/video_player/example/lib/main.dart index bfe81b9056fb..ee2fcbdc9632 100644 --- a/packages/video_player/video_player/example/lib/main.dart +++ b/packages/video_player/video_player/example/lib/main.dart @@ -220,6 +220,7 @@ class _BumbleBeeRemoteVideoState extends State<_BumbleBeeRemoteVideo> { _controller = VideoPlayerController.network( 'https://flutter.github.io/assets-for-api-docs/assets/videos/bee.mp4', closedCaptionFile: _loadCaptions(), + videoPlayerOptions: VideoPlayerOptions(mixWithOthers: true), ); _controller.addListener(() { diff --git a/packages/video_player/video_player/example/pubspec.yaml b/packages/video_player/video_player/example/pubspec.yaml index 29f1c91e4af3..e0afa4193dc2 100644 --- a/packages/video_player/video_player/example/pubspec.yaml +++ b/packages/video_player/video_player/example/pubspec.yaml @@ -12,7 +12,8 @@ dev_dependencies: sdk: flutter flutter_driver: sdk: flutter - e2e: "^0.2.0" + integration_test: + path: ../../../integration_test test: any pedantic: ^1.8.0 diff --git a/packages/video_player/video_player/example/test_driver/video_player_e2e.dart b/packages/video_player/video_player/example/test_driver/video_player_e2e.dart index bf35cf50b728..0953c8feb6c0 100644 --- a/packages/video_player/video_player/example/test_driver/video_player_e2e.dart +++ b/packages/video_player/video_player/example/test_driver/video_player_e2e.dart @@ -3,14 +3,14 @@ // BSD-style license that can be found in the LICENSE file. import 'dart:io'; -import 'package:e2e/e2e.dart'; +import 'package:integration_test/integration_test.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:video_player/video_player.dart'; const Duration _playDuration = Duration(seconds: 1); void main() { - E2EWidgetsFlutterBinding.ensureInitialized(); + IntegrationTestWidgetsFlutterBinding.ensureInitialized(); VideoPlayerController _controller; tearDown(() async => _controller.dispose()); diff --git a/packages/video_player/video_player/example/test_driver/video_player_e2e_test.dart b/packages/video_player/video_player/example/test_driver/video_player_e2e_test.dart index f3aa9e218d82..7a2c21338786 100644 --- a/packages/video_player/video_player/example/test_driver/video_player_e2e_test.dart +++ b/packages/video_player/video_player/example/test_driver/video_player_e2e_test.dart @@ -3,13 +3,15 @@ // BSD-style license that can be found in the LICENSE file. import 'dart:async'; +import 'dart:convert'; import 'dart:io'; import 'package:flutter_driver/flutter_driver.dart'; Future main() async { final FlutterDriver driver = await FlutterDriver.connect(); - final String result = + final String data = await driver.requestData(null, timeout: const Duration(minutes: 1)); await driver.close(); - exit(result == 'pass' ? 0 : 1); + final Map result = jsonDecode(data); + exit(result['result'] == 'true' ? 0 : 1); } diff --git a/packages/video_player/video_player/ios/Classes/FLTVideoPlayerPlugin.m b/packages/video_player/video_player/ios/Classes/FLTVideoPlayerPlugin.m index 7dbc1b0bfd11..a834fe32b87b 100644 --- a/packages/video_player/video_player/ios/Classes/FLTVideoPlayerPlugin.m +++ b/packages/video_player/video_player/ios/Classes/FLTVideoPlayerPlugin.m @@ -560,4 +560,15 @@ - (void)pause:(FLTTextureMessage*)input error:(FlutterError**)error { [player pause]; } +- (void)setMixWithOthers:(FLTMixWithOthersMessage*)input + error:(FlutterError* _Nullable __autoreleasing*)error { + if ([input.mixWithOthers boolValue]) { + [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback + withOptions:AVAudioSessionCategoryOptionMixWithOthers + error:nil]; + } else { + [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil]; + } +} + @end diff --git a/packages/video_player/video_player/ios/Classes/messages.h b/packages/video_player/video_player/ios/Classes/messages.h index 3c89b1f203d1..27025ef27413 100644 --- a/packages/video_player/video_player/ios/Classes/messages.h +++ b/packages/video_player/video_player/ios/Classes/messages.h @@ -12,6 +12,7 @@ NS_ASSUME_NONNULL_BEGIN @class FLTLoopingMessage; @class FLTVolumeMessage; @class FLTPositionMessage; +@class FLTMixWithOthersMessage; @interface FLTTextureMessage : NSObject @property(nonatomic, strong, nullable) NSNumber *textureId; @@ -39,6 +40,10 @@ NS_ASSUME_NONNULL_BEGIN @property(nonatomic, strong, nullable) NSNumber *position; @end +@interface FLTMixWithOthersMessage : NSObject +@property(nonatomic, strong, nullable) NSNumber *mixWithOthers; +@end + @protocol FLTVideoPlayerApi - (void)initialize:(FlutterError *_Nullable *_Nonnull)error; - (nullable FLTTextureMessage *)create:(FLTCreateMessage *)input @@ -51,6 +56,8 @@ NS_ASSUME_NONNULL_BEGIN error:(FlutterError *_Nullable *_Nonnull)error; - (void)seekTo:(FLTPositionMessage *)input error:(FlutterError *_Nullable *_Nonnull)error; - (void)pause:(FLTTextureMessage *)input error:(FlutterError *_Nullable *_Nonnull)error; +- (void)setMixWithOthers:(FLTMixWithOthersMessage *)input + error:(FlutterError *_Nullable *_Nonnull)error; @end extern void FLTVideoPlayerApiSetup(id binaryMessenger, diff --git a/packages/video_player/video_player/ios/Classes/messages.m b/packages/video_player/video_player/ios/Classes/messages.m index 3694a11622dc..64fcd75cc6bf 100644 --- a/packages/video_player/video_player/ios/Classes/messages.m +++ b/packages/video_player/video_player/ios/Classes/messages.m @@ -40,6 +40,10 @@ @interface FLTPositionMessage () + (FLTPositionMessage *)fromMap:(NSDictionary *)dict; - (NSDictionary *)toMap; @end +@interface FLTMixWithOthersMessage () ++ (FLTMixWithOthersMessage *)fromMap:(NSDictionary *)dict; +- (NSDictionary *)toMap; +@end @implementation FLTTextureMessage + (FLTTextureMessage *)fromMap:(NSDictionary *)dict { @@ -154,6 +158,22 @@ - (NSDictionary *)toMap { } @end +@implementation FLTMixWithOthersMessage ++ (FLTMixWithOthersMessage *)fromMap:(NSDictionary *)dict { + FLTMixWithOthersMessage *result = [[FLTMixWithOthersMessage alloc] init]; + result.mixWithOthers = dict[@"mixWithOthers"]; + if ((NSNull *)result.mixWithOthers == [NSNull null]) { + result.mixWithOthers = nil; + } + return result; +} +- (NSDictionary *)toMap { + return [NSDictionary + dictionaryWithObjectsAndKeys:(self.mixWithOthers != nil ? self.mixWithOthers : [NSNull null]), + @"mixWithOthers", nil]; +} +@end + void FLTVideoPlayerApiSetup(id binaryMessenger, id api) { { FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel @@ -289,4 +309,19 @@ void FLTVideoPlayerApiSetup(id binaryMessenger, id { /// null. The [package] argument must be non-null when the asset comes from a /// package and null otherwise. VideoPlayerController.asset(this.dataSource, - {this.package, this.closedCaptionFile}) + {this.package, this.closedCaptionFile, this.videoPlayerOptions}) : dataSourceType = DataSourceType.asset, formatHint = null, super(VideoPlayerValue(duration: null)); @@ -181,7 +181,7 @@ class VideoPlayerController extends ValueNotifier { /// **Android only**: The [formatHint] option allows the caller to override /// the video format detection code. VideoPlayerController.network(this.dataSource, - {this.formatHint, this.closedCaptionFile}) + {this.formatHint, this.closedCaptionFile, this.videoPlayerOptions}) : dataSourceType = DataSourceType.network, package = null, super(VideoPlayerValue(duration: null)); @@ -190,7 +190,8 @@ class VideoPlayerController extends ValueNotifier { /// /// This will load the file from the file-URI given by: /// `'file://${file.path}'`. - VideoPlayerController.file(File file, {this.closedCaptionFile}) + VideoPlayerController.file(File file, + {this.closedCaptionFile, this.videoPlayerOptions}) : dataSource = 'file://${file.path}', dataSourceType = DataSourceType.file, package = null, @@ -211,6 +212,9 @@ class VideoPlayerController extends ValueNotifier { /// is constructed with. final DataSourceType dataSourceType; + /// Provide additional configuration options (optional). Like setting the audio mode to mix + final VideoPlayerOptions videoPlayerOptions; + /// Only set for [asset] videos. The package that the asset was loaded from. final String package; @@ -262,6 +266,12 @@ class VideoPlayerController extends ValueNotifier { ); break; } + + if (videoPlayerOptions?.mixWithOthers != null) { + await _videoPlayerPlatform + .setMixWithOthers(videoPlayerOptions.mixWithOthers); + } + _textureId = await _videoPlayerPlatform.create(dataSourceDescription); _creatingCompleter.complete(null); final Completer initializingCompleter = Completer(); diff --git a/packages/video_player/video_player/pigeons/messages.dart b/packages/video_player/video_player/pigeons/messages.dart index 2df5b78f13f8..074eef023b94 100644 --- a/packages/video_player/video_player/pigeons/messages.dart +++ b/packages/video_player/video_player/pigeons/messages.dart @@ -26,6 +26,10 @@ class CreateMessage { String formatHint; } +class MixWithOthersMessage { + bool mixWithOthers; +} + @HostApi() abstract class VideoPlayerApi { void initialize(); @@ -37,6 +41,7 @@ abstract class VideoPlayerApi { PositionMessage position(TextureMessage msg); void seekTo(PositionMessage msg); void pause(TextureMessage msg); + void setMixWithOthers(MixWithOthersMessage msg); } void configurePigeon(PigeonOptions opts) { diff --git a/packages/video_player/video_player/pubspec.yaml b/packages/video_player/video_player/pubspec.yaml index 03f71bf4f412..a62f6f09a202 100644 --- a/packages/video_player/video_player/pubspec.yaml +++ b/packages/video_player/video_player/pubspec.yaml @@ -4,7 +4,7 @@ description: Flutter plugin for displaying inline video with other Flutter # 0.10.y+z is compatible with 1.0.0, if you land a breaking change bump # the version to 2.0.0. # See more details: https://github.com/flutter/flutter/wiki/Package-migration-to-1.0.0 -version: 0.10.11+2 +version: 0.10.12 homepage: https://github.com/flutter/plugins/tree/master/packages/video_player/video_player flutter: diff --git a/packages/video_player/video_player/test/video_player_test.dart b/packages/video_player/video_player/test/video_player_test.dart index ae236def4e57..67722594989c 100644 --- a/packages/video_player/video_player/test/video_player_test.dart +++ b/packages/video_player/video_player/test/video_player_test.dart @@ -10,8 +10,8 @@ import 'package:flutter/services.dart'; import 'package:flutter/widgets.dart'; import 'package:video_player/video_player.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:video_player_platform_interface/video_player_platform_interface.dart'; import 'package:video_player_platform_interface/messages.dart'; +import 'package:video_player_platform_interface/video_player_platform_interface.dart'; class FakeController extends ValueNotifier implements VideoPlayerController { @@ -52,6 +52,9 @@ class FakeController extends ValueNotifier @override Future get closedCaptionFile => _loadClosedCaption(); + + @override + VideoPlayerOptions get videoPlayerOptions => null; } Future _loadClosedCaption() async => @@ -575,6 +578,14 @@ void main() { expect(colors.bufferedColor, bufferedColor); expect(colors.backgroundColor, backgroundColor); }); + + test('setMixWithOthers', () { + final VideoPlayerController controller = VideoPlayerController.file( + File(''), + videoPlayerOptions: VideoPlayerOptions(mixWithOthers: true)); + controller.initialize(); + expect(controller.videoPlayerOptions.mixWithOthers, true); + }); } class FakeVideoPlayerPlatform extends VideoPlayerApiTest { diff --git a/packages/video_player/video_player_platform_interface/CHANGELOG.md b/packages/video_player/video_player_platform_interface/CHANGELOG.md index f5aa5208e93c..0920582abad0 100644 --- a/packages/video_player/video_player_platform_interface/CHANGELOG.md +++ b/packages/video_player/video_player_platform_interface/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.1.0 + +* Add VideoPlayerOptions with audo mix mode + ## 2.0.2 * Migrated tests to use pigeon correctly. diff --git a/packages/video_player/video_player_platform_interface/lib/messages.dart b/packages/video_player/video_player_platform_interface/lib/messages.dart index ea117a51bb07..a75ece0db850 100644 --- a/packages/video_player/video_player_platform_interface/lib/messages.dart +++ b/packages/video_player/video_player_platform_interface/lib/messages.dart @@ -1,4 +1,4 @@ -// Autogenerated from Pigeon (v0.1.0-experimental.10), do not edit directly. +// Autogenerated from Pigeon (v0.1.0-experimental.11), do not edit directly. // See also: https://pub.dev/packages/pigeon // ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import import 'dart:async'; @@ -107,6 +107,23 @@ class PositionMessage { } } +class MixWithOthersMessage { + bool mixWithOthers; + // ignore: unused_element + Map _toMap() { + final Map pigeonMap = {}; + pigeonMap['mixWithOthers'] = mixWithOthers; + return pigeonMap; + } + + // ignore: unused_element + static MixWithOthersMessage _fromMap(Map pigeonMap) { + final MixWithOthersMessage result = MixWithOthersMessage(); + result.mixWithOthers = pigeonMap['mixWithOthers']; + return result; + } +} + abstract class VideoPlayerApiTest { void initialize(); TextureMessage create(CreateMessage arg); @@ -407,4 +424,27 @@ class VideoPlayerApi { // noop } } + + Future setMixWithOthers(MixWithOthersMessage arg) async { + final Map requestMap = arg._toMap(); + const BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.VideoPlayerApi.setMixWithOthers', + StandardMessageCodec()); + + final Map replyMap = await channel.send(requestMap); + if (replyMap == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + details: null); + } else if (replyMap['error'] != null) { + final Map error = replyMap['error']; + throw PlatformException( + code: error['code'], + message: error['message'], + details: error['details']); + } else { + // noop + } + } } diff --git a/packages/video_player/video_player_platform_interface/lib/method_channel_video_player.dart b/packages/video_player/video_player_platform_interface/lib/method_channel_video_player.dart index 4b28100e1642..8c0f1de39661 100644 --- a/packages/video_player/video_player_platform_interface/lib/method_channel_video_player.dart +++ b/packages/video_player/video_player_platform_interface/lib/method_channel_video_player.dart @@ -125,6 +125,13 @@ class MethodChannelVideoPlayer extends VideoPlayerPlatform { return Texture(textureId: textureId); } + @override + Future setMixWithOthers(bool mixWithOthers) { + return _api.setMixWithOthers( + MixWithOthersMessage()..mixWithOthers = mixWithOthers, + ); + } + EventChannel _eventChannelFor(int textureId) { return EventChannel('flutter.io/videoPlayer/videoEvents$textureId'); } diff --git a/packages/video_player/video_player_platform_interface/lib/video_player_platform_interface.dart b/packages/video_player/video_player_platform_interface/lib/video_player_platform_interface.dart index 4c1f2b67c4fc..279810aaaf63 100644 --- a/packages/video_player/video_player_platform_interface/lib/video_player_platform_interface.dart +++ b/packages/video_player/video_player_platform_interface/lib/video_player_platform_interface.dart @@ -110,6 +110,11 @@ abstract class VideoPlayerPlatform { throw UnimplementedError('buildView() has not been implemented.'); } + /// Sets the audio mode to mix with other sources + Future setMixWithOthers(bool mixWithOthers) { + throw UnimplementedError('setMixWithOthers() has not been implemented.'); + } + // This method makes sure that VideoPlayer isn't implemented with `implements`. // // See class doc for more details on why implementing this class is forbidden. @@ -331,3 +336,13 @@ class DurationRange { @override int get hashCode => start.hashCode ^ end.hashCode; } + +/// [VideoPlayerOptions] can be optionally used to set additional player settings +class VideoPlayerOptions { + /// Set this to true to mix the video players audio with other audio sources. + /// The default value is false + final bool mixWithOthers; + + /// set additional optional player settings + VideoPlayerOptions({this.mixWithOthers = false}); +} diff --git a/packages/video_player/video_player_platform_interface/pubspec.yaml b/packages/video_player/video_player_platform_interface/pubspec.yaml index b4462679fcfc..4740605d7669 100644 --- a/packages/video_player/video_player_platform_interface/pubspec.yaml +++ b/packages/video_player/video_player_platform_interface/pubspec.yaml @@ -3,7 +3,7 @@ description: A common platform interface for the video_player plugin. homepage: https://github.com/flutter/plugins/tree/master/packages/video_player/video_player_platform_interface # NOTE: We strongly prefer non-breaking changes, even at the expense of a # less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes -version: 2.0.2 +version: 2.1.0 dependencies: flutter: diff --git a/packages/webview_flutter/CHANGELOG.md b/packages/webview_flutter/CHANGELOG.md index 04155a509b80..baa485ba5b17 100644 --- a/packages/webview_flutter/CHANGELOG.md +++ b/packages/webview_flutter/CHANGELOG.md @@ -1,3 +1,8 @@ +## 0.3.22+2 + +* Update package:e2e reference to use the local version in the flutter/plugins + repository. + ## 0.3.22+1 * Update the `setAndGetScrollPosition` to use hard coded values and add a `pumpAndSettle` call. diff --git a/packages/webview_flutter/example/android/app/src/androidTestDebug/java/io/flutter/plugins/webviewflutterexample/EmbeddingV1ActivityTest.java b/packages/webview_flutter/example/android/app/src/androidTestDebug/java/io/flutter/plugins/webviewflutterexample/EmbeddingV1ActivityTest.java index fe10c6155e5a..8f253d8dc74f 100644 --- a/packages/webview_flutter/example/android/app/src/androidTestDebug/java/io/flutter/plugins/webviewflutterexample/EmbeddingV1ActivityTest.java +++ b/packages/webview_flutter/example/android/app/src/androidTestDebug/java/io/flutter/plugins/webviewflutterexample/EmbeddingV1ActivityTest.java @@ -1,11 +1,11 @@ package io.flutter.plugins.webviewflutterexample; import androidx.test.rule.ActivityTestRule; -import dev.flutter.plugins.e2e.FlutterRunner; +import dev.flutter.plugins.integration_test.FlutterTestRunner; import org.junit.Rule; import org.junit.runner.RunWith; -@RunWith(FlutterRunner.class) +@RunWith(FlutterTestRunner.class) public class EmbeddingV1ActivityTest { @Rule public ActivityTestRule rule = diff --git a/packages/webview_flutter/example/android/app/src/androidTestDebug/java/io/flutter/plugins/webviewflutterexample/MainActivityTest.java b/packages/webview_flutter/example/android/app/src/androidTestDebug/java/io/flutter/plugins/webviewflutterexample/MainActivityTest.java index 73387b8d1160..a9b1a9412cbd 100644 --- a/packages/webview_flutter/example/android/app/src/androidTestDebug/java/io/flutter/plugins/webviewflutterexample/MainActivityTest.java +++ b/packages/webview_flutter/example/android/app/src/androidTestDebug/java/io/flutter/plugins/webviewflutterexample/MainActivityTest.java @@ -1,12 +1,12 @@ package io.flutter.plugins.webviewflutterexample; import androidx.test.rule.ActivityTestRule; -import dev.flutter.plugins.e2e.FlutterRunner; +import dev.flutter.plugins.integration_test.FlutterTestRunner; import io.flutter.embedding.android.FlutterActivity; import org.junit.Rule; import org.junit.runner.RunWith; -@RunWith(FlutterRunner.class) +@RunWith(FlutterTestRunner.class) public class MainActivityTest { @Rule public ActivityTestRule rule = new ActivityTestRule<>(FlutterActivity.class); diff --git a/packages/webview_flutter/example/android/app/src/main/java/io/flutter/plugins/webviewflutterexample/EmbeddingV1Activity.java b/packages/webview_flutter/example/android/app/src/main/java/io/flutter/plugins/webviewflutterexample/EmbeddingV1Activity.java index d0f538e89ce3..3a88496594a3 100644 --- a/packages/webview_flutter/example/android/app/src/main/java/io/flutter/plugins/webviewflutterexample/EmbeddingV1Activity.java +++ b/packages/webview_flutter/example/android/app/src/main/java/io/flutter/plugins/webviewflutterexample/EmbeddingV1Activity.java @@ -5,7 +5,7 @@ package io.flutter.plugins.webviewflutterexample; import android.os.Bundle; -import dev.flutter.plugins.e2e.E2EPlugin; +import dev.flutter.plugins.integration_test.IntegrationTestPlugin; import io.flutter.app.FlutterActivity; import io.flutter.plugins.webviewflutter.WebViewFlutterPlugin; @@ -13,7 +13,8 @@ public class EmbeddingV1Activity extends FlutterActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - E2EPlugin.registerWith(registrarFor("dev.flutter.plugins.e2e.E2EPlugin")); + IntegrationTestPlugin.registerWith( + registrarFor("dev.flutter.plugins.integration_test.IntegrationTestPlugin")); WebViewFlutterPlugin.registerWith( registrarFor("io.flutter.plugins.webviewflutter.WebViewFlutterPlugin")); } diff --git a/packages/webview_flutter/example/pubspec.yaml b/packages/webview_flutter/example/pubspec.yaml index f5842fc6c163..44c740ae9739 100644 --- a/packages/webview_flutter/example/pubspec.yaml +++ b/packages/webview_flutter/example/pubspec.yaml @@ -15,7 +15,8 @@ dev_dependencies: sdk: flutter flutter_driver: sdk: flutter - e2e: "^0.2.0" + integration_test: + path: ../../integration_test pedantic: ^1.8.0 flutter: diff --git a/packages/webview_flutter/example/test_driver/webview_flutter_e2e.dart b/packages/webview_flutter/example/test_driver/webview_flutter_e2e.dart index 3468067de603..162ca2cdcd9a 100644 --- a/packages/webview_flutter/example/test_driver/webview_flutter_e2e.dart +++ b/packages/webview_flutter/example/test_driver/webview_flutter_e2e.dart @@ -13,10 +13,10 @@ import 'package:flutter/widgets.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:webview_flutter/platform_interface.dart'; import 'package:webview_flutter/webview_flutter.dart'; -import 'package:e2e/e2e.dart'; +import 'package:integration_test/integration_test.dart'; void main() { - E2EWidgetsFlutterBinding.ensureInitialized(); + IntegrationTestWidgetsFlutterBinding.ensureInitialized(); testWidgets('initalUrl', (WidgetTester tester) async { final Completer controllerCompleter = diff --git a/packages/webview_flutter/example/test_driver/webview_flutter_e2e_test.dart b/packages/webview_flutter/example/test_driver/webview_flutter_e2e_test.dart index ccd716607d60..7a2c21338786 100644 --- a/packages/webview_flutter/example/test_driver/webview_flutter_e2e_test.dart +++ b/packages/webview_flutter/example/test_driver/webview_flutter_e2e_test.dart @@ -3,14 +3,15 @@ // BSD-style license that can be found in the LICENSE file. import 'dart:async'; +import 'dart:convert'; import 'dart:io'; - import 'package:flutter_driver/flutter_driver.dart'; Future main() async { final FlutterDriver driver = await FlutterDriver.connect(); - final String result = + final String data = await driver.requestData(null, timeout: const Duration(minutes: 1)); await driver.close(); - exit(result == 'pass' ? 0 : 1); + final Map result = jsonDecode(data); + exit(result['result'] == 'true' ? 0 : 1); } diff --git a/packages/webview_flutter/pubspec.yaml b/packages/webview_flutter/pubspec.yaml index 2ccc3efcccef..ec811833c9b8 100644 --- a/packages/webview_flutter/pubspec.yaml +++ b/packages/webview_flutter/pubspec.yaml @@ -1,6 +1,6 @@ name: webview_flutter description: A Flutter plugin that provides a WebView widget on Android and iOS. -version: 0.3.22+1 +version: 0.3.22+2 homepage: https://github.com/flutter/plugins/tree/master/packages/webview_flutter environment: diff --git a/script/incremental_build.sh b/script/incremental_build.sh index 3b0b97f0dbe6..5351926b0051 100755 --- a/script/incremental_build.sh +++ b/script/incremental_build.sh @@ -17,6 +17,7 @@ CUSTOM_ANALYSIS_PLUGINS=( "in_app_purchase" "camera" "video_player/video_player_web" + "google_maps_flutter/google_maps_flutter_web" ) # Comma-separated string of the list above readonly CUSTOM_FLAG=$(IFS=, ; echo "${CUSTOM_ANALYSIS_PLUGINS[*]}") @@ -29,9 +30,14 @@ elif [[ "${ACTIONS[@]}" == "analyze" ]]; then fi BRANCH_NAME="${BRANCH_NAME:-"$(git rev-parse --abbrev-ref HEAD)"}" + +# This has to be turned into a list and then split out to the command line, +# otherwise it gets treated as a single argument. +PLUGIN_SHARDING=($PLUGIN_SHARDING) + if [[ "${BRANCH_NAME}" == "master" ]]; then echo "Running for all packages" - (cd "$REPO_DIR" && pub global run flutter_plugin_tools "${ACTIONS[@]}" $PLUGIN_SHARDING) + (cd "$REPO_DIR" && pub global run flutter_plugin_tools "${ACTIONS[@]}" ${PLUGIN_SHARDING[@]}) else # Sets CHANGED_PACKAGES check_changed_packages @@ -39,10 +45,10 @@ else if [[ "$CHANGED_PACKAGES" == "" ]]; then echo "No changes detected in packages." echo "Running for all packages" - (cd "$REPO_DIR" && pub global run flutter_plugin_tools "${ACTIONS[@]}" $PLUGIN_SHARDING) + (cd "$REPO_DIR" && pub global run flutter_plugin_tools "${ACTIONS[@]}" ${PLUGIN_SHARDING[@]}) else echo running "${ACTIONS[@]}" - (cd "$REPO_DIR" && pub global run flutter_plugin_tools "${ACTIONS[@]}" --plugins="$CHANGED_PACKAGES" $PLUGIN_SHARDING) + (cd "$REPO_DIR" && pub global run flutter_plugin_tools "${ACTIONS[@]}" --plugins="$CHANGED_PACKAGES" ${PLUGIN_SHARDING[@]}) echo "Running version check for changed packages" (cd "$REPO_DIR" && pub global run flutter_plugin_tools version-check --base_sha="$(get_branch_base_sha)") fi