diff --git a/.github/workflows/pr_validation.yaml b/.github/workflows/pr_validation.yaml new file mode 100644 index 0000000..93295ab --- /dev/null +++ b/.github/workflows/pr_validation.yaml @@ -0,0 +1,251 @@ +name: Validate PR + +on: [pull_request, workflow_dispatch] + +jobs: +# test_flutter-test-runners_deep-links_android: +# runs-on: ubuntu-latest +# defaults: +# run: +# working-directory: ./packages/flutter_test_runners/example_deep_links +# +# steps: +# - name: Checkout Repository +# uses: actions/checkout@v3 +# +# # Need JDK 17 for Android build. +# - name: Set up JDK 17 +# uses: actions/setup-java@v3 +# with: +# distribution: 'temurin' +# java-version: '17' +# +# # The Android emulator action seems to want to include this. +# - name: enable KVM for linux runners +# working-directory: ~ +# run: | +# echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules +# sudo udevadm control --reload-rules +# sudo udevadm trigger --name-match=kvm +# +# - name: Set up Flutter +# uses: subosito/flutter-action@v2 +# with: +# channel: stable +# architecture: x64 +# +# - name: Install Flutter Dependencies +# run: flutter pub get +# +# - name: Build Flutter App (Debug Mode) +# # Must be debug mode so we can enable Flutter Driver. +# run: flutter build apk --debug +# +# - name: Install Android SDK and launch emulator +# uses: reactivecircus/android-emulator-runner@v2 +# with: +# api-level: 35 +# target: default +# arch: x86_64 +# profile: Galaxy Nexus +# cores: 2 +# disk-size: 6000M +# heap-size: 600M +# sdcard-path-or-size: 100M +# avd-name: github-ci-emulator +# force-avd-creation: false +# emulator-options: -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none +# disable-animations: false +# script: | +# echo "Running emulator..." +# echo "Working directory: $(pwd)" +# +# echo "Unlocking the screen" +# adb shell input keyevent 82 # Unlock the emulator screen if it's locked +# echo "" +# +# echo "Installing the APK" +# cd packages/flutter_test_runners/example_deep_links && flutter install --debug -d emulator-5554 +# echo "" +# +# echo "Running Flutter tests" +# cd packages/flutter_test_runners/example_deep_links && flutter test test_driver/deep_link_android_test.dart + + test_flutter-test-runners_deep-links_ios: + runs-on: macos-latest + + defaults: + run: + working-directory: ./packages/flutter_test_runners/example_deep_links + + steps: + - name: Set location for ExportOptions.plist + working-directory: ~ + run: | + echo "EXPORT_OPTS_PATH=$RUNNER_TEMP/ExportOptions.plist" >> $GITHUB_ENV + + - name: Install the Apple certificate and provisioning profile + working-directory: ~ + env: + BUILD_CERTIFICATE_BASE64: ${{ secrets.SIGNING_CERTIFICATE }} + P12_PASSWORD: ${{ secrets.SIGNING_CERTIFICATE_PASSWORD }} + BUILD_PROVISION_PROFILE_BASE64: ${{ secrets.PROVISIONING_PROFILE }} + PP_FILE_NAME: fbh_deep_link_example_app_profile.mobileprovision + EXPORT_OPTIONS_PLIST: ${{ secrets.EXPORT_OPTIONS_PLIST }} + run: | + # Create variables + CERTIFICATE_PATH=$RUNNER_TEMP/build_certificate.p12 + PP_PATH=$RUNNER_TEMP/$PP_FILE_NAME + KEYCHAIN_PATH=~/Library/Keychains/login.keychain-db + + # Check keychain status + echo "All keychains:" + security list-keychains + + echo "Is keychain unlocked?" + security show-keychain-info $KEYCHAIN_PATH + + # Import certificate and provisioning profile from secrets + echo -n "$BUILD_CERTIFICATE_BASE64" | base64 --decode -o $CERTIFICATE_PATH + echo -n "$BUILD_PROVISION_PROFILE_BASE64" | base64 --decode -o $PP_PATH + + # create temporary keychain + #security create-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH + #security set-keychain-settings -lut 21600 $KEYCHAIN_PATH + #security unlock-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH + + # Import certificate to keychain + security import $CERTIFICATE_PATH -P "$P12_PASSWORD" -A -t cert -f pkcs12 -k $KEYCHAIN_PATH + security list-keychain -d user -s $KEYCHAIN_PATH + + # Verify certificate was loaded into keychain + echo "Verifying that the signing certificate was loaded into the keychain" + security find-identity -p codesigning -v + + # Apply provisioning profile + mkdir -p ~/Library/MobileDevice/Provisioning\ Profiles + cp $PP_PATH ~/Library/MobileDevice/Provisioning\ Profiles + + # List all provisioning profiles to make sure we placed it correctly + echo "Listing all provisioning profiles in the CI server" + ls ~/Library/MobileDevice/Provisioning\ Profiles/ + echo "" + + # Check provisioning profile data + echo "Provisioning profile data:" + security cms -D -i ~/Library/MobileDevice/Provisioning\ Profiles/$PP_FILE_NAME + echo "" + + # Save ExportOptions.plist from Base64 to file + echo "Saving the base64 encoded ExportOptions.plist to $EXPORT_OPTS_PATH" + echo -n "$EXPORT_OPTIONS_PLIST" | base64 --decode -o $EXPORT_OPTS_PATH + + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Set up Xcode + run: | + sudo xcode-select -s /Applications/Xcode.app + xcodebuild -version + + - name: Check Xcode build settings + run: | + echo "Listing all the build settings for the project:" + cd ios && xcodebuild -showBuildSettings + + - name: Check Xcode project Runner build settings + run: | + echo "Listing all the build settings for the Runner scheme:" + cd ios && xcodebuild -workspace Runner.xcworkspace -scheme Runner -showBuildSettings + + - name: Set up Flutter + uses: subosito/flutter-action@v2 + with: + channel: stable + architecture: x64 + + - name: Install Flutter Dependencies + run: flutter pub get + + - name: Build the app + run: flutter build ios --debug --verbose --simulator --no-codesign + + - name: Check for built app + run: | + echo "Checking for app build artifacts..." + echo "build/" + ls -la build + echo "" + + echo "build/ios/" + ls -la build/ios + echo "" + + echo "build/ios/Debug-iphonesimulator/" + ls -la build/ios/Debug-iphonesimulator + echo "" + + echo "build/ios/iphonesimulator/" + ls -la build/ios/iphonesimulator + echo "" + +# - name: Build iOS App +# run: flutter build ipa --debug --verbose --export-options-plist=$EXPORT_OPTS_PATH +# +# - name: Install iOS App +# run: flutter install ipa + + - name: Create and Boot iOS Simulator + run: | + # List available devices and runtimes + xcrun simctl list devices + xcrun simctl list runtimes + + # Create a new simulator (if needed) + SIMULATOR_ID=$(xcrun simctl create "GitHubActions-Simulator" "iPhone 14" "com.apple.CoreSimulator.SimRuntime.iOS-17-0") + + # Boot the simulator + xcrun simctl boot "$SIMULATOR_ID" + xcrun simctl list devices booted + + # Install the app using xcrun. Apparently, there's no Flutter command to + # install an unsigned iOS app. The "flutter install" command only works if + # the app is signed. + - name: Install the app + run: xcrun simctl install booted build/ios/iphonesimulator/Runner.app + + - name: Ensure simulator is booted + run: xcrun simctl bootstatus booted + + - name: Check the simulator UI + run: xcrun simctl ui booted appearance + + - name: Take a screenshot of the simulator + run: | + mkdir -p ~/simulator-screenshots + xcrun simctl io booted screenshot ~/simulator-screenshots/screenshot.png + + - name: Upload simulator screenshot as Artifact + uses: actions/upload-artifact@v3 + with: + name: simulator-screenshot + path: ~/simulator-screenshots/screenshot.png + + - name: Check for installed app on simulator + run: | + echo "Checking for app's container on the booted simulator:" + xcrun simctl get_app_container booted com.flutterbountyhunters.deeplinks.example + +# - name: Kill any simctl processes +# run: pkill -f runner +# +# - name: Check for other processes using the simulator +# run: ps aux | grep simctl + + # - name: Launch the app on the simulator just to prove we can +# run: | +# echo "Launching the installed app to prove that we can..." +# xcrun simctl launch booted com.flutterbountyhunters.deeplinks.example + + - name: Run the iOS deep link tests + run: flutter test test_driver/deep_link_ios_test.dart diff --git a/.run/Example_ Deep Links.run.xml b/.run/Example_ Deep Links.run.xml new file mode 100644 index 0000000..fe7fa30 --- /dev/null +++ b/.run/Example_ Deep Links.run.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/melos_flutter_testing.iml b/melos_flutter_testing.iml index 9681559..01e7ecf 100644 --- a/melos_flutter_testing.iml +++ b/melos_flutter_testing.iml @@ -4,9 +4,12 @@ + + + - + \ No newline at end of file diff --git a/packages/flutter_test_runners/example_deep_links/.gitignore b/packages/flutter_test_runners/example_deep_links/.gitignore new file mode 100644 index 0000000..79c113f --- /dev/null +++ b/packages/flutter_test_runners/example_deep_links/.gitignore @@ -0,0 +1,45 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.build/ +.buildlog/ +.history +.svn/ +.swiftpm/ +migrate_working_dir/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# The .vscode folder contains launch configuration and tasks you configure in +# VS Code which you may wish to be included in version control, so this line +# is commented out by default. +#.vscode/ + +# Flutter/Dart/Pub related +**/doc/api/ +**/ios/Flutter/.last_build_id +.dart_tool/ +.flutter-plugins +.flutter-plugins-dependencies +.pub-cache/ +.pub/ +/build/ + +# Symbolication related +app.*.symbols + +# Obfuscation related +app.*.map.json + +# Android Studio will place build artifacts here +/android/app/debug +/android/app/profile +/android/app/release diff --git a/packages/flutter_test_runners/example_deep_links/.metadata b/packages/flutter_test_runners/example_deep_links/.metadata new file mode 100644 index 0000000..556b647 --- /dev/null +++ b/packages/flutter_test_runners/example_deep_links/.metadata @@ -0,0 +1,33 @@ +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled and should not be manually edited. + +version: + revision: "17025dd88227cd9532c33fa78f5250d548d87e9a" + channel: "stable" + +project_type: app + +# Tracks metadata for the flutter migrate command +migration: + platforms: + - platform: root + create_revision: 17025dd88227cd9532c33fa78f5250d548d87e9a + base_revision: 17025dd88227cd9532c33fa78f5250d548d87e9a + - platform: android + create_revision: 17025dd88227cd9532c33fa78f5250d548d87e9a + base_revision: 17025dd88227cd9532c33fa78f5250d548d87e9a + - platform: ios + create_revision: 17025dd88227cd9532c33fa78f5250d548d87e9a + base_revision: 17025dd88227cd9532c33fa78f5250d548d87e9a + + # User provided section + + # List of Local paths (relative to this file) that should be + # ignored by the migrate tool. + # + # Files that are not part of the templates will be ignored by default. + unmanaged_files: + - 'lib/main.dart' + - 'ios/Runner.xcodeproj/project.pbxproj' diff --git a/packages/flutter_test_runners/example_deep_links/README.md b/packages/flutter_test_runners/example_deep_links/README.md new file mode 100644 index 0000000..3b05925 --- /dev/null +++ b/packages/flutter_test_runners/example_deep_links/README.md @@ -0,0 +1,3 @@ +# Example: Deep Links +This app is configured for deep links so that `flutter_test_runner` deep link +verification tools can be validated. diff --git a/packages/flutter_test_runners/example_deep_links/analysis_options.yaml b/packages/flutter_test_runners/example_deep_links/analysis_options.yaml new file mode 100644 index 0000000..0d29021 --- /dev/null +++ b/packages/flutter_test_runners/example_deep_links/analysis_options.yaml @@ -0,0 +1,28 @@ +# This file configures the analyzer, which statically analyzes Dart code to +# check for errors, warnings, and lints. +# +# The issues identified by the analyzer are surfaced in the UI of Dart-enabled +# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be +# invoked from the command line by running `flutter analyze`. + +# The following line activates a set of recommended lints for Flutter apps, +# packages, and plugins designed to encourage good coding practices. +include: package:flutter_lints/flutter.yaml + +linter: + # The lint rules applied to this project can be customized in the + # section below to disable rules from the `package:flutter_lints/flutter.yaml` + # included above or to enable additional rules. A list of all available lints + # and their documentation is published at https://dart.dev/lints. + # + # Instead of disabling a lint rule for the entire project in the + # section below, it can also be suppressed for a single line of code + # or a specific dart file by using the `// ignore: name_of_lint` and + # `// ignore_for_file: name_of_lint` syntax on the line or in the file + # producing the lint. + rules: + # avoid_print: false # Uncomment to disable the `avoid_print` rule + # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule + +# Additional information about this file can be found at +# https://dart.dev/guides/language/analysis-options diff --git a/packages/flutter_test_runners/example_deep_links/android/.gitignore b/packages/flutter_test_runners/example_deep_links/android/.gitignore new file mode 100644 index 0000000..55afd91 --- /dev/null +++ b/packages/flutter_test_runners/example_deep_links/android/.gitignore @@ -0,0 +1,13 @@ +gradle-wrapper.jar +/.gradle +/captures/ +/gradlew +/gradlew.bat +/local.properties +GeneratedPluginRegistrant.java + +# Remember to never publicly share your keystore. +# See https://flutter.dev/to/reference-keystore +key.properties +**/*.keystore +**/*.jks diff --git a/packages/flutter_test_runners/example_deep_links/android/app/build.gradle b/packages/flutter_test_runners/example_deep_links/android/app/build.gradle new file mode 100644 index 0000000..d38b7ef --- /dev/null +++ b/packages/flutter_test_runners/example_deep_links/android/app/build.gradle @@ -0,0 +1,43 @@ +plugins { + id "com.android.application" + id "kotlin-android" + // The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins. + id "dev.flutter.flutter-gradle-plugin" +} + +android { + namespace = "com.flutterbountyhunters.deeplinks.example" + compileSdk = flutter.compileSdkVersion + ndkVersion = flutter.ndkVersion + + compileOptions { + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 + } + + kotlinOptions { + jvmTarget = JavaVersion.VERSION_1_8 + } + + defaultConfig { + applicationId = "com.flutterbountyhunters.deeplinks.example" + // You can update the following values to match your application needs. + // For more information, see: https://flutter.dev/to/review-gradle-config. + minSdk = flutter.minSdkVersion + targetSdk = flutter.targetSdkVersion + versionCode = flutter.versionCode + versionName = flutter.versionName + } + + buildTypes { + release { + // TODO: Add your own signing config for the release build. + // Signing with the debug keys for now, so `flutter run --release` works. + signingConfig = signingConfigs.debug + } + } +} + +flutter { + source = "../.." +} diff --git a/packages/flutter_test_runners/example_deep_links/android/app/src/debug/AndroidManifest.xml b/packages/flutter_test_runners/example_deep_links/android/app/src/debug/AndroidManifest.xml new file mode 100644 index 0000000..399f698 --- /dev/null +++ b/packages/flutter_test_runners/example_deep_links/android/app/src/debug/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/packages/flutter_test_runners/example_deep_links/android/app/src/main/AndroidManifest.xml b/packages/flutter_test_runners/example_deep_links/android/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..f21c4cd --- /dev/null +++ b/packages/flutter_test_runners/example_deep_links/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/flutter_test_runners/example_deep_links/android/app/src/main/kotlin/com/flutterbountyhunters/deeplinks/example/MainActivity.kt b/packages/flutter_test_runners/example_deep_links/android/app/src/main/kotlin/com/flutterbountyhunters/deeplinks/example/MainActivity.kt new file mode 100644 index 0000000..1cdafcc --- /dev/null +++ b/packages/flutter_test_runners/example_deep_links/android/app/src/main/kotlin/com/flutterbountyhunters/deeplinks/example/MainActivity.kt @@ -0,0 +1,5 @@ +package com.flutterbountyhunters.deeplinks.example; + +import io.flutter.embedding.android.FlutterActivity + +class MainActivity: FlutterActivity() diff --git a/packages/flutter_test_runners/example_deep_links/android/app/src/main/res/drawable-v21/launch_background.xml b/packages/flutter_test_runners/example_deep_links/android/app/src/main/res/drawable-v21/launch_background.xml new file mode 100644 index 0000000..f74085f --- /dev/null +++ b/packages/flutter_test_runners/example_deep_links/android/app/src/main/res/drawable-v21/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/packages/flutter_test_runners/example_deep_links/android/app/src/main/res/drawable/launch_background.xml b/packages/flutter_test_runners/example_deep_links/android/app/src/main/res/drawable/launch_background.xml new file mode 100644 index 0000000..304732f --- /dev/null +++ b/packages/flutter_test_runners/example_deep_links/android/app/src/main/res/drawable/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/packages/flutter_test_runners/example_deep_links/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/packages/flutter_test_runners/example_deep_links/android/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 0000000..db77bb4 Binary files /dev/null and b/packages/flutter_test_runners/example_deep_links/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/packages/flutter_test_runners/example_deep_links/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/packages/flutter_test_runners/example_deep_links/android/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 0000000..17987b7 Binary files /dev/null and b/packages/flutter_test_runners/example_deep_links/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/packages/flutter_test_runners/example_deep_links/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/packages/flutter_test_runners/example_deep_links/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 0000000..09d4391 Binary files /dev/null and b/packages/flutter_test_runners/example_deep_links/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/packages/flutter_test_runners/example_deep_links/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/packages/flutter_test_runners/example_deep_links/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 0000000..d5f1c8d Binary files /dev/null and b/packages/flutter_test_runners/example_deep_links/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/packages/flutter_test_runners/example_deep_links/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/packages/flutter_test_runners/example_deep_links/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 0000000..4d6372e Binary files /dev/null and b/packages/flutter_test_runners/example_deep_links/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/packages/flutter_test_runners/example_deep_links/android/app/src/main/res/values-night/styles.xml b/packages/flutter_test_runners/example_deep_links/android/app/src/main/res/values-night/styles.xml new file mode 100644 index 0000000..06952be --- /dev/null +++ b/packages/flutter_test_runners/example_deep_links/android/app/src/main/res/values-night/styles.xml @@ -0,0 +1,18 @@ + + + + + + + diff --git a/packages/flutter_test_runners/example_deep_links/android/app/src/main/res/values/styles.xml b/packages/flutter_test_runners/example_deep_links/android/app/src/main/res/values/styles.xml new file mode 100644 index 0000000..cb1ef88 --- /dev/null +++ b/packages/flutter_test_runners/example_deep_links/android/app/src/main/res/values/styles.xml @@ -0,0 +1,18 @@ + + + + + + + diff --git a/packages/flutter_test_runners/example_deep_links/android/app/src/profile/AndroidManifest.xml b/packages/flutter_test_runners/example_deep_links/android/app/src/profile/AndroidManifest.xml new file mode 100644 index 0000000..399f698 --- /dev/null +++ b/packages/flutter_test_runners/example_deep_links/android/app/src/profile/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/packages/flutter_test_runners/example_deep_links/android/build.gradle b/packages/flutter_test_runners/example_deep_links/android/build.gradle new file mode 100644 index 0000000..d2ffbff --- /dev/null +++ b/packages/flutter_test_runners/example_deep_links/android/build.gradle @@ -0,0 +1,18 @@ +allprojects { + repositories { + google() + mavenCentral() + } +} + +rootProject.buildDir = "../build" +subprojects { + project.buildDir = "${rootProject.buildDir}/${project.name}" +} +subprojects { + project.evaluationDependsOn(":app") +} + +tasks.register("clean", Delete) { + delete rootProject.buildDir +} diff --git a/packages/flutter_test_runners/example_deep_links/android/gradle.properties b/packages/flutter_test_runners/example_deep_links/android/gradle.properties new file mode 100644 index 0000000..2597170 --- /dev/null +++ b/packages/flutter_test_runners/example_deep_links/android/gradle.properties @@ -0,0 +1,3 @@ +org.gradle.jvmargs=-Xmx4G -XX:MaxMetaspaceSize=2G -XX:+HeapDumpOnOutOfMemoryError +android.useAndroidX=true +android.enableJetifier=true diff --git a/packages/flutter_test_runners/example_deep_links/android/gradle/wrapper/gradle-wrapper.properties b/packages/flutter_test_runners/example_deep_links/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..7bb2df6 --- /dev/null +++ b/packages/flutter_test_runners/example_deep_links/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-all.zip diff --git a/packages/flutter_test_runners/example_deep_links/android/settings.gradle b/packages/flutter_test_runners/example_deep_links/android/settings.gradle new file mode 100644 index 0000000..b9e43bd --- /dev/null +++ b/packages/flutter_test_runners/example_deep_links/android/settings.gradle @@ -0,0 +1,25 @@ +pluginManagement { + def flutterSdkPath = { + def properties = new Properties() + file("local.properties").withInputStream { properties.load(it) } + def flutterSdkPath = properties.getProperty("flutter.sdk") + assert flutterSdkPath != null, "flutter.sdk not set in local.properties" + return flutterSdkPath + }() + + includeBuild("$flutterSdkPath/packages/flutter_tools/gradle") + + repositories { + google() + mavenCentral() + gradlePluginPortal() + } +} + +plugins { + id "dev.flutter.flutter-plugin-loader" version "1.0.0" + id "com.android.application" version "8.1.0" apply false + id "org.jetbrains.kotlin.android" version "1.8.22" apply false +} + +include ":app" diff --git a/packages/flutter_test_runners/example_deep_links/apple_deep_links_hosting/.firebaserc b/packages/flutter_test_runners/example_deep_links/apple_deep_links_hosting/.firebaserc new file mode 100644 index 0000000..6b945cd --- /dev/null +++ b/packages/flutter_test_runners/example_deep_links/apple_deep_links_hosting/.firebaserc @@ -0,0 +1,15 @@ +{ + "projects": { + "default": "flutter-bounty-hunters" + }, + "targets": { + "flutter-bounty-hunters": { + "hosting": { + "deeplinks-flutter-bounty-hunters": [ + "deeplinks-flutter-bounty-hunters" + ] + } + } + }, + "etags": {} +} \ No newline at end of file diff --git a/packages/flutter_test_runners/example_deep_links/apple_deep_links_hosting/.gitignore b/packages/flutter_test_runners/example_deep_links/apple_deep_links_hosting/.gitignore new file mode 100644 index 0000000..b17f631 --- /dev/null +++ b/packages/flutter_test_runners/example_deep_links/apple_deep_links_hosting/.gitignore @@ -0,0 +1,69 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +firebase-debug.log* +firebase-debug.*.log* + +# Firebase cache +.firebase/ + +# Firebase config + +# Uncomment this if you'd like others to create their own Firebase project. +# For a team working on the same Firebase project(s), it is recommended to leave +# it commented so all members can deploy to the same project(s) in .firebaserc. +# .firebaserc + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (http://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variables file +.env + +# dataconnect generated files +.dataconnect diff --git a/packages/flutter_test_runners/example_deep_links/apple_deep_links_hosting/README.md b/packages/flutter_test_runners/example_deep_links/apple_deep_links_hosting/README.md new file mode 100644 index 0000000..da49598 --- /dev/null +++ b/packages/flutter_test_runners/example_deep_links/apple_deep_links_hosting/README.md @@ -0,0 +1,23 @@ +# Apple Deep Link Hosting Website +This directory holds a website with the explicit purpose of hosting a +`apple-app-site-association` file, as required by Apple, to associate +an app with a Universal Link. + +This website defines an association for `deeplinks.flutterbountyhunters.com`, +which is used only by `example_deep_links` in this repository. This +association makes it possible for the FBH team to run the iOS deep link +tests locally, and (maybe) run them in CI. + +If you're not a member of the FBH team, you won't be able to run the deep +links in this example project, as-is. That's because you can't sign the app, +because you're not a member of our Apple developer organization. If you +want to run the iOS deep link code in this repository, you should do the following: + + 1. Change the example app iOS app bundle ID to one that you own, e.g., `com.mydomain.myapp`. + 2. Change the Universal Links in this repo to point to a domain you own, e.g., `https://myapp.mydomain.com`. + 3. (If not done already) Upload an `apple-app-site-association` file to the domain you own. + +### Hosting +This website is hosted on Firebase. This was chosen only because it was trivial +to setup, and the configuration can be saved in this directory. It doesn't generally +matter how the hosting is accomplished. diff --git a/packages/flutter_test_runners/example_deep_links/apple_deep_links_hosting/firebase.json b/packages/flutter_test_runners/example_deep_links/apple_deep_links_hosting/firebase.json new file mode 100644 index 0000000..4497ded --- /dev/null +++ b/packages/flutter_test_runners/example_deep_links/apple_deep_links_hosting/firebase.json @@ -0,0 +1,22 @@ +{ + "hosting": { + "target": "deeplinks-flutter-bounty-hunters", + "public": "public", + "headers": [ + { + "source": ".well-known/apple-app-site-association", + "headers": [ + { + "key": "Content-Type", + "value": "application/json" + } + ] + } + ], + "ignore": [ + "firebase.json", + "**/.*", + "**/node_modules/**" + ] + } +} diff --git a/packages/flutter_test_runners/example_deep_links/apple_deep_links_hosting/public/.well-known/apple-app-site-association b/packages/flutter_test_runners/example_deep_links/apple_deep_links_hosting/public/.well-known/apple-app-site-association new file mode 100644 index 0000000..5ce8221 --- /dev/null +++ b/packages/flutter_test_runners/example_deep_links/apple_deep_links_hosting/public/.well-known/apple-app-site-association @@ -0,0 +1,25 @@ +{ + "applinks": { + "apps": [], + "details": [ + { + "appIDs": [ + "2X9AB296W2.com.flutterbountyhunters.deeplinks.example" + ], + "paths": [ + "*" + ], + "components": [ + { + "/": "/*" + } + ] + } + ] + }, + "webcredentials": { + "apps": [ + "2X9AB296W2.com.flutterbountyhunters.deeplinks.example" + ] + } +} \ No newline at end of file diff --git a/packages/flutter_test_runners/example_deep_links/ios/.gitignore b/packages/flutter_test_runners/example_deep_links/ios/.gitignore new file mode 100644 index 0000000..7a7f987 --- /dev/null +++ b/packages/flutter_test_runners/example_deep_links/ios/.gitignore @@ -0,0 +1,34 @@ +**/dgph +*.mode1v3 +*.mode2v3 +*.moved-aside +*.pbxuser +*.perspectivev3 +**/*sync/ +.sconsign.dblite +.tags* +**/.vagrant/ +**/DerivedData/ +Icon? +**/Pods/ +**/.symlinks/ +profile +xcuserdata +**/.generated/ +Flutter/App.framework +Flutter/Flutter.framework +Flutter/Flutter.podspec +Flutter/Generated.xcconfig +Flutter/ephemeral/ +Flutter/app.flx +Flutter/app.zip +Flutter/flutter_assets/ +Flutter/flutter_export_environment.sh +ServiceDefinitions.json +Runner/GeneratedPluginRegistrant.* + +# Exceptions to above rules. +!default.mode1v3 +!default.mode2v3 +!default.pbxuser +!default.perspectivev3 diff --git a/packages/flutter_test_runners/example_deep_links/ios/Flutter/AppFrameworkInfo.plist b/packages/flutter_test_runners/example_deep_links/ios/Flutter/AppFrameworkInfo.plist new file mode 100644 index 0000000..7c56964 --- /dev/null +++ b/packages/flutter_test_runners/example_deep_links/ios/Flutter/AppFrameworkInfo.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + App + CFBundleIdentifier + io.flutter.flutter.app + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + App + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1.0 + MinimumOSVersion + 12.0 + + diff --git a/packages/flutter_test_runners/example_deep_links/ios/Flutter/Debug.xcconfig b/packages/flutter_test_runners/example_deep_links/ios/Flutter/Debug.xcconfig new file mode 100644 index 0000000..592ceee --- /dev/null +++ b/packages/flutter_test_runners/example_deep_links/ios/Flutter/Debug.xcconfig @@ -0,0 +1 @@ +#include "Generated.xcconfig" diff --git a/packages/flutter_test_runners/example_deep_links/ios/Flutter/Release.xcconfig b/packages/flutter_test_runners/example_deep_links/ios/Flutter/Release.xcconfig new file mode 100644 index 0000000..592ceee --- /dev/null +++ b/packages/flutter_test_runners/example_deep_links/ios/Flutter/Release.xcconfig @@ -0,0 +1 @@ +#include "Generated.xcconfig" diff --git a/packages/flutter_test_runners/example_deep_links/ios/Runner.xcodeproj/project.pbxproj b/packages/flutter_test_runners/example_deep_links/ios/Runner.xcodeproj/project.pbxproj new file mode 100644 index 0000000..ceed118 --- /dev/null +++ b/packages/flutter_test_runners/example_deep_links/ios/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,633 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 54; + objects = { + +/* Begin PBXBuildFile section */ + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; + 331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C807B294A618700263BE5 /* RunnerTests.swift */; }; + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; + 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 331C8085294A63A400263BE5 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 97C146E61CF9000F007C117D /* Project object */; + proxyType = 1; + remoteGlobalIDString = 97C146ED1CF9000F007C117D; + remoteInfo = Runner; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 9705A1C41CF9048500538489 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; + 331C807B294A618700263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = ""; }; + 331C8081294A63A400263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; + 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; + 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; + 84F387BE2D1FE87400CD6E2C /* Runner.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Runner.entitlements; sourceTree = ""; }; + 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; + 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; + 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 97C146EB1CF9000F007C117D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 331C8082294A63A400263BE5 /* RunnerTests */ = { + isa = PBXGroup; + children = ( + 331C807B294A618700263BE5 /* RunnerTests.swift */, + ); + path = RunnerTests; + sourceTree = ""; + }; + 9740EEB11CF90186004384FC /* Flutter */ = { + isa = PBXGroup; + children = ( + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, + 9740EEB21CF90195004384FC /* Debug.xcconfig */, + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, + 9740EEB31CF90195004384FC /* Generated.xcconfig */, + ); + name = Flutter; + sourceTree = ""; + }; + 97C146E51CF9000F007C117D = { + isa = PBXGroup; + children = ( + 9740EEB11CF90186004384FC /* Flutter */, + 97C146F01CF9000F007C117D /* Runner */, + 97C146EF1CF9000F007C117D /* Products */, + 331C8082294A63A400263BE5 /* RunnerTests */, + ); + sourceTree = ""; + }; + 97C146EF1CF9000F007C117D /* Products */ = { + isa = PBXGroup; + children = ( + 97C146EE1CF9000F007C117D /* Runner.app */, + 331C8081294A63A400263BE5 /* RunnerTests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + 97C146F01CF9000F007C117D /* Runner */ = { + isa = PBXGroup; + children = ( + 84F387BE2D1FE87400CD6E2C /* Runner.entitlements */, + 97C146FA1CF9000F007C117D /* Main.storyboard */, + 97C146FD1CF9000F007C117D /* Assets.xcassets */, + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, + 97C147021CF9000F007C117D /* Info.plist */, + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, + 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, + 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, + ); + path = Runner; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 331C8080294A63A400263BE5 /* RunnerTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */; + buildPhases = ( + 331C807D294A63A400263BE5 /* Sources */, + 331C807F294A63A400263BE5 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 331C8086294A63A400263BE5 /* PBXTargetDependency */, + ); + name = RunnerTests; + productName = RunnerTests; + productReference = 331C8081294A63A400263BE5 /* RunnerTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + 97C146ED1CF9000F007C117D /* Runner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; + buildPhases = ( + 9740EEB61CF901F6004384FC /* Run Script */, + 97C146EA1CF9000F007C117D /* Sources */, + 97C146EB1CF9000F007C117D /* Frameworks */, + 97C146EC1CF9000F007C117D /* Resources */, + 9705A1C41CF9048500538489 /* Embed Frameworks */, + 3B06AD1E1E4923F5004D2608 /* Thin Binary */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Runner; + productName = Runner; + productReference = 97C146EE1CF9000F007C117D /* Runner.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 97C146E61CF9000F007C117D /* Project object */ = { + isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = YES; + LastUpgradeCheck = 1510; + ORGANIZATIONNAME = ""; + TargetAttributes = { + 331C8080294A63A400263BE5 = { + CreatedOnToolsVersion = 14.0; + TestTargetID = 97C146ED1CF9000F007C117D; + }; + 97C146ED1CF9000F007C117D = { + CreatedOnToolsVersion = 7.3.1; + LastSwiftMigration = 1100; + }; + }; + }; + buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 97C146E51CF9000F007C117D; + productRefGroup = 97C146EF1CF9000F007C117D /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 97C146ED1CF9000F007C117D /* Runner */, + 331C8080294A63A400263BE5 /* RunnerTests */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 331C807F294A63A400263BE5 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 97C146EC1CF9000F007C117D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { + isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}", + ); + name = "Thin Binary"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; + }; + 9740EEB61CF901F6004384FC /* Run Script */ = { + isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Run Script"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 331C807D294A63A400263BE5 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 97C146EA1CF9000F007C117D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 331C8086294A63A400263BE5 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 97C146ED1CF9000F007C117D /* Runner */; + targetProxy = 331C8085294A63A400263BE5 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + 97C146FA1CF9000F007C117D /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C146FB1CF9000F007C117D /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C147001CF9000F007C117D /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 249021D3217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_USER_SCRIPT_SANDBOXING = NO; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SUPPORTED_PLATFORMS = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Profile; + }; + 249021D4217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = 2X9AB296W2; + ENABLE_BITCODE = NO; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.flutterbountyhunters.deeplinks.example; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Profile; + }; + 331C8088294A63A400263BE5 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.flutterbountyhunters.deeplinks.example.exampleDeepLinks.RunnerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; + }; + name = Debug; + }; + 331C8089294A63A400263BE5 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.flutterbountyhunters.deeplinks.example.exampleDeepLinks.RunnerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; + }; + name = Release; + }; + 331C808A294A63A400263BE5 /* Profile */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.flutterbountyhunters.deeplinks.example.exampleDeepLinks.RunnerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; + }; + name = Profile; + }; + 97C147031CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + ENABLE_USER_SCRIPT_SANDBOXING = NO; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 97C147041CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_USER_SCRIPT_SANDBOXING = NO; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SUPPORTED_PLATFORMS = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 97C147061CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = 2X9AB296W2; + ENABLE_BITCODE = NO; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.flutterbountyhunters.deeplinks.example; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Debug; + }; + 97C147071CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = 2X9AB296W2; + ENABLE_BITCODE = NO; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.flutterbountyhunters.deeplinks.example; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 331C8088294A63A400263BE5 /* Debug */, + 331C8089294A63A400263BE5 /* Release */, + 331C808A294A63A400263BE5 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97C147031CF9000F007C117D /* Debug */, + 97C147041CF9000F007C117D /* Release */, + 249021D3217E4FDB00AE95B9 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97C147061CF9000F007C117D /* Debug */, + 97C147071CF9000F007C117D /* Release */, + 249021D4217E4FDB00AE95B9 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 97C146E61CF9000F007C117D /* Project object */; +} diff --git a/packages/flutter_test_runners/example_deep_links/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/packages/flutter_test_runners/example_deep_links/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..919434a --- /dev/null +++ b/packages/flutter_test_runners/example_deep_links/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/packages/flutter_test_runners/example_deep_links/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/packages/flutter_test_runners/example_deep_links/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/packages/flutter_test_runners/example_deep_links/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/packages/flutter_test_runners/example_deep_links/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/packages/flutter_test_runners/example_deep_links/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 0000000..f9b0d7c --- /dev/null +++ b/packages/flutter_test_runners/example_deep_links/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + PreviewsEnabled + + + diff --git a/packages/flutter_test_runners/example_deep_links/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/packages/flutter_test_runners/example_deep_links/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme new file mode 100644 index 0000000..8e3ca5d --- /dev/null +++ b/packages/flutter_test_runners/example_deep_links/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -0,0 +1,98 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/flutter_test_runners/example_deep_links/ios/Runner.xcworkspace/contents.xcworkspacedata b/packages/flutter_test_runners/example_deep_links/ios/Runner.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..1d526a1 --- /dev/null +++ b/packages/flutter_test_runners/example_deep_links/ios/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/packages/flutter_test_runners/example_deep_links/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/packages/flutter_test_runners/example_deep_links/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/packages/flutter_test_runners/example_deep_links/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/packages/flutter_test_runners/example_deep_links/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/packages/flutter_test_runners/example_deep_links/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 0000000..f9b0d7c --- /dev/null +++ b/packages/flutter_test_runners/example_deep_links/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + PreviewsEnabled + + + diff --git a/packages/flutter_test_runners/example_deep_links/ios/Runner/AppDelegate.swift b/packages/flutter_test_runners/example_deep_links/ios/Runner/AppDelegate.swift new file mode 100644 index 0000000..6266644 --- /dev/null +++ b/packages/flutter_test_runners/example_deep_links/ios/Runner/AppDelegate.swift @@ -0,0 +1,13 @@ +import Flutter +import UIKit + +@main +@objc class AppDelegate: FlutterAppDelegate { + override func application( + _ application: UIApplication, + didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? + ) -> Bool { + GeneratedPluginRegistrant.register(with: self) + return super.application(application, didFinishLaunchingWithOptions: launchOptions) + } +} diff --git a/packages/flutter_test_runners/example_deep_links/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/packages/flutter_test_runners/example_deep_links/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..d36b1fa --- /dev/null +++ b/packages/flutter_test_runners/example_deep_links/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,122 @@ +{ + "images" : [ + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "Icon-App-20x20@2x.png", + "scale" : "2x" + }, + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "Icon-App-20x20@3x.png", + "scale" : "3x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@1x.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@2x.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@3x.png", + "scale" : "3x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "Icon-App-40x40@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "Icon-App-40x40@3x.png", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "Icon-App-60x60@2x.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "Icon-App-60x60@3x.png", + "scale" : "3x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "Icon-App-20x20@1x.png", + "scale" : "1x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "Icon-App-20x20@2x.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "Icon-App-29x29@1x.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "Icon-App-29x29@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "Icon-App-40x40@1x.png", + "scale" : "1x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "Icon-App-40x40@2x.png", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "Icon-App-76x76@1x.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "Icon-App-76x76@2x.png", + "scale" : "2x" + }, + { + "size" : "83.5x83.5", + "idiom" : "ipad", + "filename" : "Icon-App-83.5x83.5@2x.png", + "scale" : "2x" + }, + { + "size" : "1024x1024", + "idiom" : "ios-marketing", + "filename" : "Icon-App-1024x1024@1x.png", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/packages/flutter_test_runners/example_deep_links/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/packages/flutter_test_runners/example_deep_links/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png new file mode 100644 index 0000000..dc9ada4 Binary files /dev/null and b/packages/flutter_test_runners/example_deep_links/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png differ diff --git a/packages/flutter_test_runners/example_deep_links/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/packages/flutter_test_runners/example_deep_links/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png new file mode 100644 index 0000000..7353c41 Binary files /dev/null and b/packages/flutter_test_runners/example_deep_links/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png differ diff --git a/packages/flutter_test_runners/example_deep_links/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/packages/flutter_test_runners/example_deep_links/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png new file mode 100644 index 0000000..797d452 Binary files /dev/null and b/packages/flutter_test_runners/example_deep_links/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png differ diff --git a/packages/flutter_test_runners/example_deep_links/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/packages/flutter_test_runners/example_deep_links/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png new file mode 100644 index 0000000..6ed2d93 Binary files /dev/null and b/packages/flutter_test_runners/example_deep_links/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png differ diff --git a/packages/flutter_test_runners/example_deep_links/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/packages/flutter_test_runners/example_deep_links/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png new file mode 100644 index 0000000..4cd7b00 Binary files /dev/null and b/packages/flutter_test_runners/example_deep_links/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png differ diff --git a/packages/flutter_test_runners/example_deep_links/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/packages/flutter_test_runners/example_deep_links/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png new file mode 100644 index 0000000..fe73094 Binary files /dev/null and b/packages/flutter_test_runners/example_deep_links/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png differ diff --git a/packages/flutter_test_runners/example_deep_links/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/packages/flutter_test_runners/example_deep_links/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png new file mode 100644 index 0000000..321773c Binary files /dev/null and b/packages/flutter_test_runners/example_deep_links/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png differ diff --git a/packages/flutter_test_runners/example_deep_links/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/packages/flutter_test_runners/example_deep_links/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png new file mode 100644 index 0000000..797d452 Binary files /dev/null and b/packages/flutter_test_runners/example_deep_links/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png differ diff --git a/packages/flutter_test_runners/example_deep_links/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/packages/flutter_test_runners/example_deep_links/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png new file mode 100644 index 0000000..502f463 Binary files /dev/null and b/packages/flutter_test_runners/example_deep_links/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png differ diff --git a/packages/flutter_test_runners/example_deep_links/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/packages/flutter_test_runners/example_deep_links/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png new file mode 100644 index 0000000..0ec3034 Binary files /dev/null and b/packages/flutter_test_runners/example_deep_links/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png differ diff --git a/packages/flutter_test_runners/example_deep_links/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/packages/flutter_test_runners/example_deep_links/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png new file mode 100644 index 0000000..0ec3034 Binary files /dev/null and b/packages/flutter_test_runners/example_deep_links/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png differ diff --git a/packages/flutter_test_runners/example_deep_links/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/packages/flutter_test_runners/example_deep_links/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png new file mode 100644 index 0000000..e9f5fea Binary files /dev/null and b/packages/flutter_test_runners/example_deep_links/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png differ diff --git a/packages/flutter_test_runners/example_deep_links/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/packages/flutter_test_runners/example_deep_links/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png new file mode 100644 index 0000000..84ac32a Binary files /dev/null and b/packages/flutter_test_runners/example_deep_links/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png differ diff --git a/packages/flutter_test_runners/example_deep_links/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/packages/flutter_test_runners/example_deep_links/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png new file mode 100644 index 0000000..8953cba Binary files /dev/null and b/packages/flutter_test_runners/example_deep_links/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png differ diff --git a/packages/flutter_test_runners/example_deep_links/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/packages/flutter_test_runners/example_deep_links/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png new file mode 100644 index 0000000..0467bf1 Binary files /dev/null and b/packages/flutter_test_runners/example_deep_links/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png differ diff --git a/packages/flutter_test_runners/example_deep_links/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json b/packages/flutter_test_runners/example_deep_links/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json new file mode 100644 index 0000000..0bedcf2 --- /dev/null +++ b/packages/flutter_test_runners/example_deep_links/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "LaunchImage.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "LaunchImage@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "LaunchImage@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/packages/flutter_test_runners/example_deep_links/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png b/packages/flutter_test_runners/example_deep_links/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png new file mode 100644 index 0000000..9da19ea Binary files /dev/null and b/packages/flutter_test_runners/example_deep_links/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png differ diff --git a/packages/flutter_test_runners/example_deep_links/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/packages/flutter_test_runners/example_deep_links/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png new file mode 100644 index 0000000..9da19ea Binary files /dev/null and b/packages/flutter_test_runners/example_deep_links/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png differ diff --git a/packages/flutter_test_runners/example_deep_links/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/packages/flutter_test_runners/example_deep_links/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png new file mode 100644 index 0000000..9da19ea Binary files /dev/null and b/packages/flutter_test_runners/example_deep_links/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png differ diff --git a/packages/flutter_test_runners/example_deep_links/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/packages/flutter_test_runners/example_deep_links/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md new file mode 100644 index 0000000..89c2725 --- /dev/null +++ b/packages/flutter_test_runners/example_deep_links/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md @@ -0,0 +1,5 @@ +# Launch Screen Assets + +You can customize the launch screen with your own desired assets by replacing the image files in this directory. + +You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. \ No newline at end of file diff --git a/packages/flutter_test_runners/example_deep_links/ios/Runner/Base.lproj/LaunchScreen.storyboard b/packages/flutter_test_runners/example_deep_links/ios/Runner/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..f2e259c --- /dev/null +++ b/packages/flutter_test_runners/example_deep_links/ios/Runner/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/flutter_test_runners/example_deep_links/ios/Runner/Base.lproj/Main.storyboard b/packages/flutter_test_runners/example_deep_links/ios/Runner/Base.lproj/Main.storyboard new file mode 100644 index 0000000..f3c2851 --- /dev/null +++ b/packages/flutter_test_runners/example_deep_links/ios/Runner/Base.lproj/Main.storyboard @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/flutter_test_runners/example_deep_links/ios/Runner/Info.plist b/packages/flutter_test_runners/example_deep_links/ios/Runner/Info.plist new file mode 100644 index 0000000..9fa709d --- /dev/null +++ b/packages/flutter_test_runners/example_deep_links/ios/Runner/Info.plist @@ -0,0 +1,49 @@ + + + + + CADisableMinimumFrameDurationOnPhone + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleDisplayName + Example Deep Links + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + example_deep_links + CFBundlePackageType + APPL + CFBundleShortVersionString + $(FLUTTER_BUILD_NAME) + CFBundleSignature + ???? + CFBundleVersion + $(FLUTTER_BUILD_NUMBER) + LSRequiresIPhoneOS + + UIApplicationSupportsIndirectInputEvents + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/packages/flutter_test_runners/example_deep_links/ios/Runner/Runner-Bridging-Header.h b/packages/flutter_test_runners/example_deep_links/ios/Runner/Runner-Bridging-Header.h new file mode 100644 index 0000000..308a2a5 --- /dev/null +++ b/packages/flutter_test_runners/example_deep_links/ios/Runner/Runner-Bridging-Header.h @@ -0,0 +1 @@ +#import "GeneratedPluginRegistrant.h" diff --git a/packages/flutter_test_runners/example_deep_links/ios/Runner/Runner.entitlements b/packages/flutter_test_runners/example_deep_links/ios/Runner/Runner.entitlements new file mode 100644 index 0000000..c16c78e --- /dev/null +++ b/packages/flutter_test_runners/example_deep_links/ios/Runner/Runner.entitlements @@ -0,0 +1,10 @@ + + + + + com.apple.developer.associated-domains + + applinks:deeplinks.flutterbountyhunters.com + + + diff --git a/packages/flutter_test_runners/example_deep_links/ios/RunnerTests/RunnerTests.swift b/packages/flutter_test_runners/example_deep_links/ios/RunnerTests/RunnerTests.swift new file mode 100644 index 0000000..86a7c3b --- /dev/null +++ b/packages/flutter_test_runners/example_deep_links/ios/RunnerTests/RunnerTests.swift @@ -0,0 +1,12 @@ +import Flutter +import UIKit +import XCTest + +class RunnerTests: XCTestCase { + + func testExample() { + // If you add code to the Runner application, consider adding tests here. + // See https://developer.apple.com/documentation/xctest for more information about using XCTest. + } + +} diff --git a/packages/flutter_test_runners/example_deep_links/lib/main.dart b/packages/flutter_test_runners/example_deep_links/lib/main.dart new file mode 100644 index 0000000..cf26659 --- /dev/null +++ b/packages/flutter_test_runners/example_deep_links/lib/main.dart @@ -0,0 +1,129 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_driver/driver_extension.dart'; +import 'package:go_router/go_router.dart'; + +void main() { + enableFlutterDriverExtension(); + + runApp(const MyApp()); +} + +class MyApp extends StatelessWidget { + const MyApp({super.key}); + + @override + Widget build(BuildContext context) { + return MaterialApp.router( + title: 'Flutter Demo', + theme: ThemeData( + colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple), + useMaterial3: true, + ), + routerConfig: router, + ); + } +} + +final router = GoRouter( + routes: [ + GoRoute( + path: '/', + builder: (_, __) => Scaffold( + appBar: AppBar(title: const Text('Home Screen')), + ), + routes: [ + GoRoute( + path: 'signup', + builder: (_, __) => Scaffold( + appBar: AppBar(title: const Text('Sign Up')), + ), + ), + GoRoute( + path: 'user/profile', + builder: (_, __) => Scaffold( + appBar: AppBar(title: const Text('User Profile')), + ), + ), + ], + ), + ], +); + +class MyHomePage extends StatefulWidget { + const MyHomePage({super.key, required this.title}); + + final String title; + + @override + State createState() => _MyHomePageState(); +} + +class _MyHomePageState extends State { + int _counter = 0; + + void _incrementCounter() { + setState(() { + // This call to setState tells the Flutter framework that something has + // changed in this State, which causes it to rerun the build method below + // so that the display can reflect the updated values. If we changed + // _counter without calling setState(), then the build method would not be + // called again, and so nothing would appear to happen. + _counter++; + }); + } + + @override + Widget build(BuildContext context) { + // This method is rerun every time setState is called, for instance as done + // by the _incrementCounter method above. + // + // The Flutter framework has been optimized to make rerunning build methods + // fast, so that you can just rebuild anything that needs updating rather + // than having to individually change instances of widgets. + return Scaffold( + appBar: AppBar( + // TRY THIS: Try changing the color here to a specific color (to + // Colors.amber, perhaps?) and trigger a hot reload to see the AppBar + // change color while the other colors stay the same. + backgroundColor: Theme.of(context).colorScheme.inversePrimary, + // Here we take the value from the MyHomePage object that was created by + // the App.build method, and use it to set our appbar title. + title: Text(widget.title), + ), + body: Center( + // Center is a layout widget. It takes a single child and positions it + // in the middle of the parent. + child: Column( + // Column is also a layout widget. It takes a list of children and + // arranges them vertically. By default, it sizes itself to fit its + // children horizontally, and tries to be as tall as its parent. + // + // Column has various properties to control how it sizes itself and + // how it positions its children. Here we use mainAxisAlignment to + // center the children vertically; the main axis here is the vertical + // axis because Columns are vertical (the cross axis would be + // horizontal). + // + // TRY THIS: Invoke "debug painting" (choose the "Toggle Debug Paint" + // action in the IDE, or press "p" in the console), to see the + // wireframe for each widget. + mainAxisAlignment: MainAxisAlignment.center, + children: [ + const Text( + 'You have pushed the button this many times:', + ), + Text( + '$_counter', + style: Theme.of(context).textTheme.headlineMedium, + ), + ], + ), + ), + floatingActionButton: FloatingActionButton( + onPressed: _incrementCounter, + tooltip: 'Increment', + child: const Icon(Icons.add), + ), // This trailing comma makes auto-formatting nicer for build methods. + ); + } +} diff --git a/packages/flutter_test_runners/example_deep_links/pubspec.lock b/packages/flutter_test_runners/example_deep_links/pubspec.lock new file mode 100644 index 0000000..f999e31 --- /dev/null +++ b/packages/flutter_test_runners/example_deep_links/pubspec.lock @@ -0,0 +1,560 @@ +# Generated by pub +# See https://dart.dev/tools/pub/glossary#lockfile +packages: + _fe_analyzer_shared: + dependency: transitive + description: + name: _fe_analyzer_shared + sha256: "16e298750b6d0af7ce8a3ba7c18c69c3785d11b15ec83f6dcd0ad2a0009b3cab" + url: "https://pub.dev" + source: hosted + version: "76.0.0" + _macros: + dependency: transitive + description: dart + source: sdk + version: "0.3.3" + analyzer: + dependency: transitive + description: + name: analyzer + sha256: "1f14db053a8c23e260789e9b0980fa27f2680dd640932cae5e1137cce0e46e1e" + url: "https://pub.dev" + source: hosted + version: "6.11.0" + args: + dependency: transitive + description: + name: args + sha256: bf9f5caeea8d8fe6721a9c358dd8a5c1947b27f1cfaa18b39c301273594919e6 + url: "https://pub.dev" + source: hosted + version: "2.6.0" + async: + dependency: transitive + description: + name: async + sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" + url: "https://pub.dev" + source: hosted + version: "2.11.0" + boolean_selector: + dependency: transitive + description: + name: boolean_selector + sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" + url: "https://pub.dev" + source: hosted + version: "2.1.1" + characters: + dependency: transitive + description: + name: characters + sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" + url: "https://pub.dev" + source: hosted + version: "1.3.0" + clock: + dependency: transitive + description: + name: clock + sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf + url: "https://pub.dev" + source: hosted + version: "1.1.1" + collection: + dependency: transitive + description: + name: collection + sha256: a1ace0a119f20aabc852d165077c036cd864315bd99b7eaa10a60100341941bf + url: "https://pub.dev" + source: hosted + version: "1.19.0" + convert: + dependency: transitive + description: + name: convert + sha256: b30acd5944035672bc15c6b7a8b47d773e41e2f17de064350988c5d02adb1c68 + url: "https://pub.dev" + source: hosted + version: "3.1.2" + coverage: + dependency: transitive + description: + name: coverage + sha256: e3493833ea012784c740e341952298f1cc77f1f01b1bbc3eb4eecf6984fb7f43 + url: "https://pub.dev" + source: hosted + version: "1.11.1" + crypto: + dependency: transitive + description: + name: crypto + sha256: "1e445881f28f22d6140f181e07737b22f1e099a5e1ff94b0af2f9e4a463f4855" + url: "https://pub.dev" + source: hosted + version: "3.0.6" + cupertino_icons: + dependency: "direct main" + description: + name: cupertino_icons + sha256: ba631d1c7f7bef6b729a622b7b752645a2d076dba9976925b8f25725a30e1ee6 + url: "https://pub.dev" + source: hosted + version: "1.0.8" + fake_async: + dependency: transitive + description: + name: fake_async + sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" + url: "https://pub.dev" + source: hosted + version: "1.3.1" + file: + dependency: transitive + description: + name: file + sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c" + url: "https://pub.dev" + source: hosted + version: "7.0.0" + flutter: + dependency: "direct main" + description: flutter + source: sdk + version: "0.0.0" + flutter_driver: + dependency: "direct main" + description: flutter + source: sdk + version: "0.0.0" + flutter_lints: + dependency: "direct dev" + description: + name: flutter_lints + sha256: "5398f14efa795ffb7a33e9b6a08798b26a180edac4ad7db3f231e40f82ce11e1" + url: "https://pub.dev" + source: hosted + version: "5.0.0" + flutter_test: + dependency: "direct dev" + description: flutter + source: sdk + version: "0.0.0" + flutter_test_runners: + dependency: "direct dev" + description: + path: ".." + relative: true + source: path + version: "0.0.4" + flutter_web_plugins: + dependency: transitive + description: flutter + source: sdk + version: "0.0.0" + frontend_server_client: + dependency: transitive + description: + name: frontend_server_client + sha256: f64a0333a82f30b0cca061bc3d143813a486dc086b574bfb233b7c1372427694 + url: "https://pub.dev" + source: hosted + version: "4.0.0" + fuchsia_remote_debug_protocol: + dependency: transitive + description: flutter + source: sdk + version: "0.0.0" + glob: + dependency: transitive + description: + name: glob + sha256: "0e7014b3b7d4dac1ca4d6114f82bf1782ee86745b9b42a92c9289c23d8a0ab63" + url: "https://pub.dev" + source: hosted + version: "2.1.2" + go_router: + dependency: "direct main" + description: + name: go_router + sha256: "2fd11229f59e23e967b0775df8d5948a519cd7e1e8b6e849729e010587b46539" + url: "https://pub.dev" + source: hosted + version: "14.6.2" + http_multi_server: + dependency: transitive + description: + name: http_multi_server + sha256: aa6199f908078bb1c5efb8d8638d4ae191aac11b311132c3ef48ce352fb52ef8 + url: "https://pub.dev" + source: hosted + version: "3.2.2" + http_parser: + dependency: transitive + description: + name: http_parser + sha256: "76d306a1c3afb33fe82e2bbacad62a61f409b5634c915fceb0d799de1a913360" + url: "https://pub.dev" + source: hosted + version: "4.1.1" + io: + dependency: transitive + description: + name: io + sha256: dfd5a80599cf0165756e3181807ed3e77daf6dd4137caaad72d0b7931597650b + url: "https://pub.dev" + source: hosted + version: "1.0.5" + js: + dependency: transitive + description: + name: js + sha256: c1b2e9b5ea78c45e1a0788d29606ba27dc5f71f019f32ca5140f61ef071838cf + url: "https://pub.dev" + source: hosted + version: "0.7.1" + leak_tracker: + dependency: transitive + description: + name: leak_tracker + sha256: "7bb2830ebd849694d1ec25bf1f44582d6ac531a57a365a803a6034ff751d2d06" + url: "https://pub.dev" + source: hosted + version: "10.0.7" + leak_tracker_flutter_testing: + dependency: transitive + description: + name: leak_tracker_flutter_testing + sha256: "9491a714cca3667b60b5c420da8217e6de0d1ba7a5ec322fab01758f6998f379" + url: "https://pub.dev" + source: hosted + version: "3.0.8" + leak_tracker_testing: + dependency: transitive + description: + name: leak_tracker_testing + sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3" + url: "https://pub.dev" + source: hosted + version: "3.0.1" + lints: + dependency: transitive + description: + name: lints + sha256: c35bb79562d980e9a453fc715854e1ed39e24e7d0297a880ef54e17f9874a9d7 + url: "https://pub.dev" + source: hosted + version: "5.1.1" + logging: + dependency: transitive + description: + name: logging + sha256: c8245ada5f1717ed44271ed1c26b8ce85ca3228fd2ffdb75468ab01979309d61 + url: "https://pub.dev" + source: hosted + version: "1.3.0" + macros: + dependency: transitive + description: + name: macros + sha256: "1d9e801cd66f7ea3663c45fc708450db1fa57f988142c64289142c9b7ee80656" + url: "https://pub.dev" + source: hosted + version: "0.1.3-main.0" + matcher: + dependency: transitive + description: + name: matcher + sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb + url: "https://pub.dev" + source: hosted + version: "0.12.16+1" + material_color_utilities: + dependency: transitive + description: + name: material_color_utilities + sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec + url: "https://pub.dev" + source: hosted + version: "0.11.1" + meta: + dependency: transitive + description: + name: meta + sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7 + url: "https://pub.dev" + source: hosted + version: "1.15.0" + mime: + dependency: transitive + description: + name: mime + sha256: "41a20518f0cb1256669420fdba0cd90d21561e560ac240f26ef8322e45bb7ed6" + url: "https://pub.dev" + source: hosted + version: "2.0.0" + node_preamble: + dependency: transitive + description: + name: node_preamble + sha256: "6e7eac89047ab8a8d26cf16127b5ed26de65209847630400f9aefd7cd5c730db" + url: "https://pub.dev" + source: hosted + version: "2.0.2" + package_config: + dependency: transitive + description: + name: package_config + sha256: "92d4488434b520a62570293fbd33bb556c7d49230791c1b4bbd973baf6d2dc67" + url: "https://pub.dev" + source: hosted + version: "2.1.1" + path: + dependency: transitive + description: + name: path + sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" + url: "https://pub.dev" + source: hosted + version: "1.9.0" + platform: + dependency: transitive + description: + name: platform + sha256: "9b71283fc13df574056616011fb138fd3b793ea47cc509c189a6c3fa5f8a1a65" + url: "https://pub.dev" + source: hosted + version: "3.1.5" + pool: + dependency: transitive + description: + name: pool + sha256: "20fe868b6314b322ea036ba325e6fc0711a22948856475e2c2b6306e8ab39c2a" + url: "https://pub.dev" + source: hosted + version: "1.5.1" + process: + dependency: transitive + description: + name: process + sha256: "21e54fd2faf1b5bdd5102afd25012184a6793927648ea81eea80552ac9405b32" + url: "https://pub.dev" + source: hosted + version: "5.0.2" + pub_semver: + dependency: transitive + description: + name: pub_semver + sha256: "7b3cfbf654f3edd0c6298ecd5be782ce997ddf0e00531b9464b55245185bbbbd" + url: "https://pub.dev" + source: hosted + version: "2.1.5" + shelf: + dependency: transitive + description: + name: shelf + sha256: e7dd780a7ffb623c57850b33f43309312fc863fb6aa3d276a754bb299839ef12 + url: "https://pub.dev" + source: hosted + version: "1.4.2" + shelf_packages_handler: + dependency: transitive + description: + name: shelf_packages_handler + sha256: "89f967eca29607c933ba9571d838be31d67f53f6e4ee15147d5dc2934fee1b1e" + url: "https://pub.dev" + source: hosted + version: "3.0.2" + shelf_static: + dependency: transitive + description: + name: shelf_static + sha256: c87c3875f91262785dade62d135760c2c69cb217ac759485334c5857ad89f6e3 + url: "https://pub.dev" + source: hosted + version: "1.1.3" + shelf_web_socket: + dependency: transitive + description: + name: shelf_web_socket + sha256: cc36c297b52866d203dbf9332263c94becc2fe0ceaa9681d07b6ef9807023b67 + url: "https://pub.dev" + source: hosted + version: "2.0.1" + sky_engine: + dependency: transitive + description: flutter + source: sdk + version: "0.0.0" + source_map_stack_trace: + dependency: transitive + description: + name: source_map_stack_trace + sha256: c0713a43e323c3302c2abe2a1cc89aa057a387101ebd280371d6a6c9fa68516b + url: "https://pub.dev" + source: hosted + version: "2.1.2" + source_maps: + dependency: transitive + description: + name: source_maps + sha256: "190222579a448b03896e0ca6eca5998fa810fda630c1d65e2f78b3f638f54812" + url: "https://pub.dev" + source: hosted + version: "0.10.13" + source_span: + dependency: transitive + description: + name: source_span + sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" + url: "https://pub.dev" + source: hosted + version: "1.10.0" + stack_trace: + dependency: transitive + description: + name: stack_trace + sha256: "9f47fd3630d76be3ab26f0ee06d213679aa425996925ff3feffdec504931c377" + url: "https://pub.dev" + source: hosted + version: "1.12.0" + stream_channel: + dependency: transitive + description: + name: stream_channel + sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 + url: "https://pub.dev" + source: hosted + version: "2.1.2" + string_scanner: + dependency: transitive + description: + name: string_scanner + sha256: "688af5ed3402a4bde5b3a6c15fd768dbf2621a614950b17f04626c431ab3c4c3" + url: "https://pub.dev" + source: hosted + version: "1.3.0" + sync_http: + dependency: transitive + description: + name: sync_http + sha256: "7f0cd72eca000d2e026bcd6f990b81d0ca06022ef4e32fb257b30d3d1014a961" + url: "https://pub.dev" + source: hosted + version: "0.3.1" + term_glyph: + dependency: transitive + description: + name: term_glyph + sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 + url: "https://pub.dev" + source: hosted + version: "1.2.1" + test: + dependency: "direct dev" + description: + name: test + sha256: "713a8789d62f3233c46b4a90b174737b2c04cb6ae4500f2aa8b1be8f03f5e67f" + url: "https://pub.dev" + source: hosted + version: "1.25.8" + test_api: + dependency: transitive + description: + name: test_api + sha256: "664d3a9a64782fcdeb83ce9c6b39e78fd2971d4e37827b9b06c3aa1edc5e760c" + url: "https://pub.dev" + source: hosted + version: "0.7.3" + test_core: + dependency: transitive + description: + name: test_core + sha256: "12391302411737c176b0b5d6491f466b0dd56d4763e347b6714efbaa74d7953d" + url: "https://pub.dev" + source: hosted + version: "0.6.5" + typed_data: + dependency: transitive + description: + name: typed_data + sha256: f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006 + url: "https://pub.dev" + source: hosted + version: "1.4.0" + vector_math: + dependency: transitive + description: + name: vector_math + sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" + url: "https://pub.dev" + source: hosted + version: "2.1.4" + vm_service: + dependency: transitive + description: + name: vm_service + sha256: f6be3ed8bd01289b34d679c2b62226f63c0e69f9fd2e50a6b3c1c729a961041b + url: "https://pub.dev" + source: hosted + version: "14.3.0" + watcher: + dependency: transitive + description: + name: watcher + sha256: "69da27e49efa56a15f8afe8f4438c4ec02eff0a117df1b22ea4aad194fe1c104" + url: "https://pub.dev" + source: hosted + version: "1.1.1" + web: + dependency: transitive + description: + name: web + sha256: cd3543bd5798f6ad290ea73d210f423502e71900302dde696f8bff84bf89a1cb + url: "https://pub.dev" + source: hosted + version: "1.1.0" + web_socket: + dependency: transitive + description: + name: web_socket + sha256: "3c12d96c0c9a4eec095246debcea7b86c0324f22df69893d538fcc6f1b8cce83" + url: "https://pub.dev" + source: hosted + version: "0.1.6" + web_socket_channel: + dependency: transitive + description: + name: web_socket_channel + sha256: "9f187088ed104edd8662ca07af4b124465893caf063ba29758f97af57e61da8f" + url: "https://pub.dev" + source: hosted + version: "3.0.1" + webdriver: + dependency: transitive + description: + name: webdriver + sha256: "3d773670966f02a646319410766d3b5e1037efb7f07cc68f844d5e06cd4d61c8" + url: "https://pub.dev" + source: hosted + version: "3.0.4" + webkit_inspection_protocol: + dependency: transitive + description: + name: webkit_inspection_protocol + sha256: "87d3f2333bb240704cd3f1c6b5b7acd8a10e7f0bc28c28dcf14e782014f4a572" + url: "https://pub.dev" + source: hosted + version: "1.2.1" + yaml: + dependency: transitive + description: + name: yaml + sha256: b9da305ac7c39faa3f030eccd175340f968459dae4af175130b3fc47e40d76ce + url: "https://pub.dev" + source: hosted + version: "3.1.3" +sdks: + dart: ">=3.6.0 <4.0.0" + flutter: ">=3.19.0" diff --git a/packages/flutter_test_runners/example_deep_links/pubspec.yaml b/packages/flutter_test_runners/example_deep_links/pubspec.yaml new file mode 100644 index 0000000..b21a890 --- /dev/null +++ b/packages/flutter_test_runners/example_deep_links/pubspec.yaml @@ -0,0 +1,65 @@ +name: example_deep_links +description: "Example app for testing deep links." +publish_to: 'none' # Remove this line if you wish to publish to pub.dev + +version: 1.0.0+1 + +environment: + sdk: ^3.6.0 + +dependencies: + flutter: + sdk: flutter + flutter_driver: + sdk: flutter + + cupertino_icons: ^1.0.8 + go_router: ^14.6.2 + +dev_dependencies: + flutter_test: + sdk: flutter + flutter_lints: ^5.0.0 + + test: any + + flutter_test_runners: + path: ../ + +flutter: + + # The following line ensures that the Material Icons font is + # included with your application, so that you can use the icons in + # the material Icons class. + uses-material-design: true + + # To add assets to your application, add an assets section, like this: + # assets: + # - images/a_dot_burr.jpeg + # - images/a_dot_ham.jpeg + + # An image asset can refer to one or more resolution-specific "variants", see + # https://flutter.dev/to/resolution-aware-images + + # For details regarding adding assets from package dependencies, see + # https://flutter.dev/to/asset-from-package + + # To add custom fonts to your application, add a fonts section here, + # in this "flutter" section. Each entry in this list should have a + # "family" key with the font family name, and a "fonts" key with a + # list giving the asset and other descriptors for the font. For + # example: + # fonts: + # - family: Schyler + # fonts: + # - asset: fonts/Schyler-Regular.ttf + # - asset: fonts/Schyler-Italic.ttf + # style: italic + # - family: Trajan Pro + # fonts: + # - asset: fonts/TrajanPro.ttf + # - asset: fonts/TrajanPro_Bold.ttf + # weight: 700 + # + # For details regarding fonts from package dependencies, + # see https://flutter.dev/to/font-from-package diff --git a/packages/flutter_test_runners/example_deep_links/test_driver/deep_link_android_test.dart b/packages/flutter_test_runners/example_deep_links/test_driver/deep_link_android_test.dart new file mode 100644 index 0000000..e3d16a2 --- /dev/null +++ b/packages/flutter_test_runners/example_deep_links/test_driver/deep_link_android_test.dart @@ -0,0 +1,42 @@ +import 'package:flutter_driver/flutter_driver.dart'; +import 'package:flutter_test_runners/flutter_test_runners.dart'; +import 'package:test/test.dart'; + +void main() { + const appPackage = "com.flutterbountyhunters.deeplinks.example"; + + // Command you can use to directly check a deep link: + // adb shell am start -W -a android.intent.action.VIEW -d "app://deeplinks.flutterbountyhunters.com/user/profile" com.flutterbountyhunters.deeplinks.example + + group("Deep link launches app > Android >", () { + testDeepLinkAndroidAppLaunch( + "home screen", + appPackage: appPackage, + deepLink: "app://deeplinks.flutterbountyhunters.com", + (driver) async { + await driver.waitFor(find.text("Home Screen")); + await Future.delayed(const Duration(seconds: 3)); + }, + ); + + testDeepLinkAndroidAppLaunch( + "sign-up screen", + appPackage: appPackage, + deepLink: "app://deeplinks.flutterbountyhunters.com/signup", + (driver) async { + await driver.waitFor(find.text("Sign Up")); + await Future.delayed(const Duration(seconds: 3)); + }, + ); + + testDeepLinkAndroidAppLaunch( + "profile screen", + appPackage: appPackage, + deepLink: "app://deeplinks.flutterbountyhunters.com/user/profile", + (driver) async { + await driver.waitFor(find.text("User Profile")); + await Future.delayed(const Duration(seconds: 3)); + }, + ); + }); +} diff --git a/packages/flutter_test_runners/example_deep_links/test_driver/deep_link_ios_test.dart b/packages/flutter_test_runners/example_deep_links/test_driver/deep_link_ios_test.dart new file mode 100644 index 0000000..05c849c --- /dev/null +++ b/packages/flutter_test_runners/example_deep_links/test_driver/deep_link_ios_test.dart @@ -0,0 +1,152 @@ +import 'package:flutter_driver/flutter_driver.dart'; +import 'package:flutter_test_runners/flutter_test_runners.dart'; +import 'package:test/test.dart'; + +void main() { + const appBundleId = "com.flutterbountyhunters.deeplinks.example"; + + // Command you can use to directly check a Universal Link: + // xcrun simctl openurl booted https://deeplinks.flutterbountyhunters.com + + group("Deep link launches app > iOS >", () { + // test("xcrun sanity check", () async { + // print("Running xcrun Process sanity check."); + // + // // print("Env variables:"); + // // print(Process.runSync('env', []).stdout); + // + // print("Running the command..."); + // final result = await Process.run( + // "sh", + // [ + // "-c", + // "xcrun", + // "simctl", + // // "list", + // // "--verbose", + // "get_app_container", + // "booted", + // "com.flutterbountyhunters.deeplinks.example", + // ], + // ); + // // process.stdout.transform(utf8.decoder).listen((data) { + // // print("STDOUT:\n$data"); + // // }); + // // process.stderr.transform(utf8.decoder).listen((data) { + // // print("STDERR:\n$data"); + // // }); + // // print("The process started..."); + // // print("Closing stdin"); + // // process.stdin.close(); + // // print("Waiting for exit code..."); + // // final exitCode = await process.exitCode; + // // print("The xcrun call returned with exit code: $exitCode"); + // print("The xcrun call returned with exit code: ${result.exitCode}"); + // }); + + // test("Send terminate command to simulator", () async { + // print("Running device list command:"); + // final result1 = await Process.run( + // "sh", + // [ + // "-c", + // "xcrun simctl list", + // ], + // ); + // print("result1: ${result1.exitCode}"); + // print(""); + // + // print("Running get_app_container command:"); + // final result2 = await Process.run( + // "sh", + // [ + // "-c", + // "xcrun simctl get_app_container booted com.flutterbountyhunters.deeplinks.example", + // ], + // ); + // print("result2: ${result2.exitCode}"); + // print(""); + // + // //-------- + // print("Sending xcrun simctl terminate command..."); + // + // // CI Timeout + // // final process = await Process.start( + // // "xcrun", + // // ["simctl", "terminate", "booted", "'$appBundleId'"], + // // runInShell: true, + // // ); + // + // // CI Timeout + // // final process = await Process.start( + // // "xcrun", + // // ["simctl", "terminate", "booted", "'$appBundleId'"], + // // ); + // + // // CI Timeout + // // final process = await Process.start( + // // "sh", + // // ["-c", "xcrun simctl terminate booted '$appBundleId'"], + // // ); + // // + // // CI Timeout + // // final result = await Process.run( + // // "sh", + // // ["-c", "xcrun simctl terminate booted '$appBundleId'"], + // // ); + // // print("Exit code: ${result.exitCode}"); + // + // // CI Timeout + // // final script = ''' + // // #!/bin/bash + // // xcrun simctl terminate booted $appBundleId + // // '''; + // // final tempFile = File('/tmp/temp_script.sh'); + // // await tempFile.writeAsString(script); + // // await Process.run('chmod', ['+x', tempFile.path]); + // // final process = await Process.start('/bin/bash', [tempFile.path]); + // // + // // print("terminate command process was started"); + // // + // // process.stdin.close(); + // // + // // stdout.addStream(process.stdout); + // // stderr.addStream(process.stderr); + // // + // // print("Waiting for exit code..."); + // // final exitCode = await process.exitCode; + // // print("Killed app - exit code: $exitCode"); + // }); + + testDeepLinkIosAppLaunch( + "home screen", + appBundleId: appBundleId, + deepLink: "https://deeplinks.flutterbountyhunters.com", + verbose: true, + (driver) async { + await driver.waitFor(find.text("Home Screen")); + await Future.delayed(const Duration(seconds: 3)); + }, + ); + + // testDeepLinkIosAppLaunch( + // "sign-up screen", + // appBundleId: appBundleId, + // deepLink: "https://deeplinks.flutterbountyhunters.com/signup", + // (driver) async { + // await driver.waitFor(find.text("Sign Up")); + // await Future.delayed(const Duration(seconds: 3)); + // }, + // ); + // + // testDeepLinkIosAppLaunch( + // "profile screen", + // appBundleId: appBundleId, + // deepLink: "https://deeplinks.flutterbountyhunters.com/user/profile", + // (driver) async { + // await driver.waitFor(find.text("User Profile")); + // await Future.delayed(const Duration(seconds: 3)); + // }, + // ); + }); +} diff --git a/packages/flutter_test_runners/lib/flutter_test_runners.dart b/packages/flutter_test_runners/lib/flutter_test_runners.dart index 53a51c8..6655eaa 100644 --- a/packages/flutter_test_runners/lib/flutter_test_runners.dart +++ b/packages/flutter_test_runners/lib/flutter_test_runners.dart @@ -2,3 +2,6 @@ library flutter_test_runners; export 'src/platform_messages.dart'; export 'src/platform_runners.dart'; + +export 'src/deep_links/deep_links_android.dart'; +export 'src/deep_links/deep_links_ios.dart'; diff --git a/packages/flutter_test_runners/lib/src/deep_links/deep_links_android.dart b/packages/flutter_test_runners/lib/src/deep_links/deep_links_android.dart new file mode 100644 index 0000000..85da259 --- /dev/null +++ b/packages/flutter_test_runners/lib/src/deep_links/deep_links_android.dart @@ -0,0 +1,196 @@ +import 'dart:convert'; + +import 'package:flutter_driver/flutter_driver.dart'; +import 'package:flutter_test_runners/src/platform_comms/android/adb.dart'; +import 'package:logging/logging.dart'; +import 'package:test/test.dart'; +import 'package:vm_service/vm_service.dart'; +import 'package:vm_service/vm_service_io.dart'; + +/// A test that runs after launching the Android app with the given +/// [appPackage], with the given [deepLink]. +/// +/// The test implementation is defined by the caller within [testRunner]. +/// The [testRunner] works the same way as a typical `test()` callback, +/// except that the [testRunner] is given a [FlutterDriver] to inspect +/// the app. +/// +/// Tests that launch apps with deep links must use a [FlutterDriver], +/// instead of a [WidgetTester], because [WidgetTester]s require building +/// and launching the app with instrumentation. Launching an app with a +/// deep link doesn't have instrumentation. Instead, the host machine +/// users the [FlutterDriver] to talk to the running app. +void testDeepLinkAndroidAppLaunch( + String description, + Future Function(FlutterDriver driver) testRunner, { + required String appPackage, + required String deepLink, + bool verbose = false, +}) { + test(description, () async { + _initLogs(verbose); + _log.info("Running deep link test driver..."); + + // Pre-emptively the kill the app, in case it's already running. + await Adb.killApp(appPackage); + + late final FlutterDriver? driver; + addTearDown(() async { + _log.info("Cleaning up after the test"); + // Dispose the FlutterDriver connection. + driver?.serviceClient.dispose(); + + // Kill the app when we're done. + await Adb.killApp(appPackage); + }); + + // Ensure the app isn't running yet. + expect(await Adb.isAppRunning(appPackage), isFalse); + + // Clear previous logcat messages so we don't try to connect to a previous + // Dart VM service listing. + await Adb.clearLogcat(); + + // Listen to logcat to find the Dart VM service for the running app. + String? dartVmService; + await Adb.listenToAdbForFlutterLogs(onLog: (data) { + if (data.contains("Dart VM service")) { + _log.info("Found Dart VM log:\n$data"); + + final regex = RegExp(r'.*Dart VM service.*(http[s]?://[^\s]+)'); + final httpUrl = Uri.parse(regex.firstMatch(data)!.group(1)!); + + dartVmService = Uri(scheme: "ws", host: httpUrl.host, port: httpUrl.port, path: "${httpUrl.path}ws").toString(); + } + }, onError: (error) { + _log.shout("LOGCAT ERROR:"); + _log.shout(error); + }); + + // Send the deep link. + await Adb.launchAppWithDeepLink(appPackage: appPackage, deepLink: deepLink); + + // Wait until the deep link launches the app. + final isAppRunning = await Adb.waitForAppToLaunch(appPackage); + expect( + isAppRunning, + isTrue, + reason: "The app never launched after sending the deeplink. Package: $appPackage, Deeplink: $deepLink", + ); + + // Wait for a moment so that the app has time to start the Dart VM + // service and report it in the ADB logs. + // + // When running locally, waiting 1 second is probably sufficient. But + // when running in GitHub CI, we need to wait longer to make sure the + // Dart VM service reports its URL. + _log.info("Waiting a moment so that app can launch the Dart VM service."); + await Future.delayed(const Duration(seconds: 5)); + + // Ensure that we found the Dart VM service URL. + expect( + dartVmService, + isNotNull, + reason: "Couldn't find the Dart VM service for the app that was launched with a deep link.", + ); + expect( + dartVmService, + isNotEmpty, + reason: "Couldn't find the Dart VM service for the app that was launched with a deep link.", + ); + + // Setup port forwarding between the host machine running the test, and the + // Android device that's running the app, so we can talk to the Dart VM service. + final port = Uri.parse(dartVmService!).port; + await Adb.forwardTcpPort(port); + + // Connect to the Dart VM service in the app with Flutter Driver. + try { + driver = await FlutterDriver.connect( + dartVmServiceUrl: dartVmService, + ); + } catch (exception) { + if (verbose) { + await _logVmDetailsAfterConnectionFailure(dartVmService!); + } + + throw TestFailure( + "Couldn't connect FlutterDriver to the app's Dart VM service (the app successfully launched with the deep link, though)", + ); + } + + // Run the test. + await testRunner(driver); + }); +} + +Future _logVmDetailsAfterConnectionFailure(String dartVmService) async { + _log.warning("Failed to connect to the FlutterDriver!"); + + // Connect to the Dart VM service to query info. + late final VmService vmService; + try { + vmService = await vmServiceConnectUri(dartVmService); + } catch (exception) { + _log.warning("Tried to connect to the Dart VM service to provide more details, but we couldn't connect to it."); + _log.warning(exception); + return; + } + + // Get the VM. + late final VM vm; + try { + vm = await vmService.getVM(); + } catch (exception) { + _log.warning("Tried to get the VM from the Dart VM service, but we failed to query it."); + _log.warning(exception); + return; + } + + _log.info(''' +Additional VM service info: + - name: ${vm.name} + - type: ${vm.type} + - host CPU: ${vm.hostCPU} + - target CPU: ${vm.targetCPU} + - OS: ${vm.operatingSystem} + - PID: ${vm.pid} +'''); + + if (vm.isolates != null) { + _log.info("Isolates attached to the Dart VM service:"); + for (final remoteIsolate in vm.isolates!) { + late final Isolate isolate; + try { + isolate = await vmService.getIsolate(remoteIsolate.id!); + } catch (exception) { + _log.warning("Tried to load isolate data for '${remoteIsolate.id}', but failed."); + continue; + } + + _log.info('''Isolate: + - ID: ${isolate.id} + - name: ${isolate.name} + - type: ${isolate.type} + - is system isolate: ${isolate.isSystemIsolate} + - registered extensions: + + ${isolate.extensionRPCs} +'''); + } + } +} + +void _initLogs(bool writeLogs) { + if (!writeLogs) { + return; + } + + Logger.root.level = Level.ALL; + Logger.root.onRecord.listen((record) { + // ignore: avoid_print + print('${record.level.name}: ${record.time}: ${record.message}'); + }); +} + +final _log = Logger("flutter_test_runners.deep_links"); diff --git a/packages/flutter_test_runners/lib/src/deep_links/deep_links_ios.dart b/packages/flutter_test_runners/lib/src/deep_links/deep_links_ios.dart new file mode 100644 index 0000000..385b0a8 --- /dev/null +++ b/packages/flutter_test_runners/lib/src/deep_links/deep_links_ios.dart @@ -0,0 +1,210 @@ +import 'package:flutter_driver/flutter_driver.dart'; +import 'package:flutter_test_runners/src/platform_comms/ios/xcrun.dart'; +import 'package:logging/logging.dart'; +import 'package:test/test.dart'; +import 'package:vm_service/vm_service.dart'; +import 'package:vm_service/vm_service_io.dart'; + +/// A test that runs after launching the iOS app with the given +/// [appBundleId], with the given [deepLink]. +/// +/// The test implementation is defined by the caller within [testRunner]. +/// The [testRunner] works the same way as a typical `test()` callback, +/// except that the [testRunner] is given a [FlutterDriver] to inspect +/// the app. +/// +/// Tests that launch apps with deep links must use a [FlutterDriver], +/// instead of a [WidgetTester], because [WidgetTester]s require building +/// and launching the app with instrumentation. Launching an app with a +/// deep link doesn't have instrumentation. Instead, the host machine +/// users the [FlutterDriver] to talk to the running app. +void testDeepLinkIosAppLaunch( + String description, + Future Function(FlutterDriver driver) testRunner, { + required String appBundleId, + required String deepLink, + bool verbose = false, + Duration timeout = const Duration(minutes: 5), +}) { + test(description, () async { + _initLogs(verbose); + _log.info("Running deep link test driver..."); + + // // Pre-emptively the kill the app, in case it's already running. + // _log.info("Pre-emptively killing the app"); + // await Xcrun.killApp(appBundleId); + + FlutterDriver? driver; + // addTearDown(() async { + // _log.info("Cleaning up after the test"); + // // Dispose the FlutterDriver connection. + // driver?.serviceClient.dispose(); + // + // // Kill the app when we're done. + // await Xcrun.killApp(appBundleId); + // }); + + // Ensure the app isn't running yet. + _log.info("Checking if the app is running..."); + expect(await Xcrun.isAppRunning(appBundleId), isFalse); + _log.info("We've verified the app isn't running"); + + // FIXME: At the moment GitHub CI is saying this operation isn't permitted. + // // Clear previous logcat messages so we don't try to connect to a previous + // // Dart VM service listing. + // _log.info("Clearing old logs"); + // await Xcrun.clearLogs(); + // _log.info("We've cleared old logs"); + print("NOT clearing logs because GitHub CI says not permitted"); + + // Listen to iOS logs to find the Dart VM service for the running app. + _log.info("Registering for simulator logs"); + String? dartVmService; + await Xcrun.listenToXcrunForFlutterLogs( + appBundleId, + onLog: (log) { + // _log.info(log); + if (log.contains("Dart VM service")) { + _log.info("Found Dart VM log:\n$log"); + + final regex = RegExp(r'.*Dart VM service.*(http[s]?://[^\s]+)'); + final httpUrl = Uri.parse(regex.firstMatch(log)!.group(1)!); + + dartVmService = + Uri(scheme: "ws", host: httpUrl.host, port: httpUrl.port, path: "${httpUrl.path}ws").toString(); + } + }, + onError: (error) { + _log.shout("iOS ERROR:"); + _log.shout(error); + }, + ); + _log.info("We're now listening to logs and errors from iOS"); + + // Send the deep link. + _log.info("Sending the deep link: $deepLink"); + await Xcrun.launchAppWithUniversalLink(universalLink: deepLink); + + // Wait until the deep link launches the app. + _log.info("Waiting for app to launch: $appBundleId"); + final isAppRunning = await Xcrun.waitForAppToLaunch(appBundleId); + expect( + isAppRunning, + isTrue, + reason: "The app never launched after sending the deeplink. Package: $appBundleId, Deeplink: $deepLink", + ); + + // // Wait for a moment so that the app has time to start the Dart VM + // // service and report it in the device logs. + // _log.info("Waiting a moment so that app can launch the Dart VM service."); + // await Future.delayed(const Duration(seconds: 5)); + // + // // Ensure that we found the Dart VM service URL. + // expect( + // dartVmService, + // isNotNull, + // reason: "Couldn't find the Dart VM service for the app that was launched with a deep link.", + // ); + // expect( + // dartVmService, + // isNotEmpty, + // reason: "Couldn't find the Dart VM service for the app that was launched with a deep link.", + // ); + // + // // Setup port forwarding between the host machine running the test, and the + // // Android device that's running the app, so we can talk to the Dart VM service. + // final port = Uri.parse(dartVmService!).port; + // _log.info("Forwarding simulator port: $port"); + // await Xcrun.forwardTcpPort(port); + // + // // Connect to the Dart VM service in the app with Flutter Driver. + // try { + // _log.info("Connecting to Flutter Driver extension in the Dart VM service."); + // driver = await FlutterDriver.connect( + // dartVmServiceUrl: dartVmService, + // ); + // } catch (exception) { + // if (verbose) { + // await _logVmDetailsAfterConnectionFailure(dartVmService!); + // } + // + // throw TestFailure( + // "Couldn't connect FlutterDriver to the app's Dart VM service (the app successfully launched with the deep link, though)", + // ); + // } + // + // // Run the test. + // await testRunner(driver); + }, timeout: Timeout(timeout)); +} + +Future _logVmDetailsAfterConnectionFailure(String dartVmService) async { + _log.warning("Failed to connect to the FlutterDriver!"); + + // Connect to the Dart VM service to query info. + late final VmService vmService; + try { + vmService = await vmServiceConnectUri(dartVmService); + } catch (exception) { + _log.warning("Tried to connect to the Dart VM service to provide more details, but we couldn't connect to it."); + _log.warning(exception); + return; + } + + // Get the VM. + late final VM vm; + try { + vm = await vmService.getVM(); + } catch (exception) { + _log.warning("Tried to get the VM from the Dart VM service, but we failed to query it."); + _log.warning(exception); + return; + } + + _log.info(''' +Additional VM service info: + - name: ${vm.name} + - type: ${vm.type} + - host CPU: ${vm.hostCPU} + - target CPU: ${vm.targetCPU} + - OS: ${vm.operatingSystem} + - PID: ${vm.pid} +'''); + + if (vm.isolates != null) { + _log.info("Isolates attached to the Dart VM service:"); + for (final remoteIsolate in vm.isolates!) { + late final Isolate isolate; + try { + isolate = await vmService.getIsolate(remoteIsolate.id!); + } catch (exception) { + _log.warning("Tried to load isolate data for '${remoteIsolate.id}', but failed."); + continue; + } + + _log.info('''Isolate: + - ID: ${isolate.id} + - name: ${isolate.name} + - type: ${isolate.type} + - is system isolate: ${isolate.isSystemIsolate} + - registered extensions: + + ${isolate.extensionRPCs} +'''); + } + } +} + +void _initLogs(bool writeLogs) { + if (!writeLogs) { + return; + } + + Logger.root.level = Level.ALL; + Logger.root.onRecord.listen((record) { + // ignore: avoid_print + print('${record.level.name}: ${record.time}: ${record.message}'); + }); +} + +final _log = Logger("flutter_test_runners.deep_links"); diff --git a/packages/flutter_test_runners/lib/src/platform_comms/android/adb.dart b/packages/flutter_test_runners/lib/src/platform_comms/android/adb.dart new file mode 100644 index 0000000..1da93a0 --- /dev/null +++ b/packages/flutter_test_runners/lib/src/platform_comms/android/adb.dart @@ -0,0 +1,108 @@ +import 'dart:convert'; +import 'dart:io'; + +/// A Dart interface for common Android Debug Bridge (ADB) commands. +class Adb { + /// Returns `true` if the app with the given [appPackage] ID is currently + /// in memory on the Android device. + /// + /// A return value of `true` doesn't mean the app is visible. The app might + /// be in the background, but still in memory. + static Future isAppRunning(String appPackage) async { + final result = await Process.run( + "sh", + ["-c", "adb shell ps | grep $appPackage"], + ); + final output = result.stdout; + return output != null && output is String && output.isNotEmpty; + } + + /// Starts listening to ADB logcat for Android logs, and returns the + /// [Process] that's listening to logcat. + /// + /// This method assumes that `stdout` and `stderr` from Logcat send messages + /// with UTF8 encoding. If anything else is received, the behavior is undefined, + /// but probably an error. + static Future listenToAdbForFlutterLogs({ + void Function(String)? onLog, + void Function(String)? onError, + }) async { + final result = await Process.start("adb", ["logcat", "-s", "flutter"]); + + result.stdout.transform(utf8.decoder).listen(onLog); + result.stderr.transform(utf8.decoder).listen(onError); + + return result; + } + + /// Connects the given TCP [port] from the host machine to the running Android + /// device. + /// + /// This is useful, for example, when you want to connect to the Dart VM service + /// running in a debug Flutter app on an Android device. + static Future forwardTcpPort(int port) async { + await Process.run("adb", ["forward", "tcp:$port", "tcp:$port"]); + } + + /// Tells Android to launch the app with the given [appPackage] ID using + /// the given [deepLink]. + /// + /// The structure of the deep link is determined by the given app. + static Future launchAppWithDeepLink({ + required String appPackage, + required String deepLink, + }) async { + await Process.start("adb", [ + "shell", + "am", + "start", + "-W", + "-a", + "android.intent.action.VIEW", + "-d", + "\"$deepLink\"", + appPackage, + ]); + } + + /// Waits for the app with the given [appPackage] to appear in memory. + /// + /// This method polls the OS to check if the app is running. To use a custom + /// polling duration, provide a [pollDuration]. + /// + /// This method fails if the app hasn't launched within the given [timeout] + /// duration. + static Future waitForAppToLaunch( + String appPackage, { + Duration pollDuration = const Duration(milliseconds: 250), + Duration timeout = const Duration(seconds: 10), + }) async { + final now = DateTime.now(); + + bool isAppRunning = false; + do { + isAppRunning = await Adb.isAppRunning(appPackage); + if (!isAppRunning) { + await Future.delayed(pollDuration); + } + } while (!isAppRunning && (DateTime.now().difference(now) < timeout)); + + return isAppRunning; + } + + /// Kills the app with the given [package] ID, e.g., com.acme.myapp. + static Future killApp(String package) async { + await Process.run("adb", ["shell", "am", "force-stop", package]); + } + + /// Clears all logs in logcat. + /// + /// Note: Logcat retains logs such that connecting to logcat will + /// initially print a bunch of old logs before printing new logs. + /// When searching logs for specific info, like a URL, those old logs + /// can lead to an attempt to connect to dead services. This method + /// clears those logs before listening for new logs. + static Future clearLogcat() async { + await Process.run("adb", ["logcat", "-b", "all", "-c"]); + } +} diff --git a/packages/flutter_test_runners/lib/src/platform_comms/ios/xcrun.dart b/packages/flutter_test_runners/lib/src/platform_comms/ios/xcrun.dart new file mode 100644 index 0000000..7542f21 --- /dev/null +++ b/packages/flutter_test_runners/lib/src/platform_comms/ios/xcrun.dart @@ -0,0 +1,219 @@ +import 'dart:convert'; +import 'dart:io'; + +import 'package:flutter_test/flutter_test.dart'; + +/// A Dart interface for common `xcrun` commands. +class Xcrun { + /// Returns `true` if the app with the given [appBundleId] ID is currently + /// in memory on the iOS device. + /// + /// A return value of `true` doesn't mean the app is visible. The app might + /// be in the background, but still in memory. + static Future isAppRunning(String appBundleId) async { + print("isAppRunning() - $appBundleId"); + // final result = await Process.run( + // "sh", + // [ + // "-c", + // "xcrun simctl spawn booted launchctl list | grep \"$appBundleId\"", + // ], + // runInShell: true, + // ); + + // final result = await Process.run("sh", [ + // "-c", + // "xcrun simctl spawn booted launchctl list | grep \"$appBundleId\"", + // ]); + + print("Trying command through shell - no grep..."); + var result = await _runInShell([ + "xcrun simctl spawn booted launchctl list", + ]); + print("Done with command without grep:"); + // print(result.stdout); + final output = result.stdout; + if (output is! String) { + // We don't know how to handle this. + print("Received shell output that isn't a String. Don't know what to do with this."); + return false; + } + + final isAppRunning = output.contains(appBundleId); + print("Is app running? $isAppRunning - searched ${output.split("\n").length} running processes"); + return isAppRunning; + + // print("Trying command through shell with '| grep'..."); + // result = await _runInShell([ + // "xcrun simctl spawn booted launchctl list | grep \"$appBundleId\"", + // ]); + // final output = result.stdout; + // print("Is app running? ${output != null && output is String && output.isNotEmpty}"); + // return output != null && output is String && output.isNotEmpty; + } + + /// Starts listening to the running iOS device's log stream, and returns the + /// [Process] that's listening. + /// + /// This method assumes that `stdout` and `stderr` from Logcat send messages + /// with UTF8 encoding. If anything else is received, the behavior is undefined, + /// but probably an error. + static Future listenToXcrunForFlutterLogs( + String appBundleId, { + void Function(String)? onLog, + void Function(String)? onError, + }) async { + // This command doesn't work when run with a "sh -c". It also doesn't + // work when concatenating the args into a single string. + final result = await Process.start( + "xcrun", + [ + "simctl", + "spawn", + "booted", + "log", + "stream", + "--level", + "debug", + // Only log things related to the desired app. + "--predicate", + "(eventMessage CONTAINS '$appBundleId' OR eventMessage CONTAINS 'flutter')", + ], + runInShell: true, + ); + + result.stdout.transform(utf8.decoder).listen(onLog); + result.stderr.transform(utf8.decoder).listen(onError); + + return result; + } + + /// Connects the given TCP [port] from the host machine to the running iOS + /// device. + /// + /// This is useful, for example, when you want to connect to the Dart VM service + /// running in a debug Flutter app on an iOS device. + static Future forwardTcpPort(int port) { + return _runInShell(["xcrun", "simctl", "port", "forward", "booted", "$port:$port"]); + } + + /// Tells iOS to launch the given Universal Link, which might launch an app, if + /// an app is registered to handle the domain of the link. + /// + /// The structure of the deep link is determined by the given app. + static Future launchAppWithUniversalLink({ + required String universalLink, + }) { + // Note: This command only works when run with "sh" and the + // command as a single string. If the command is passed as + // individual arguments, it doesn't work. If the command is + // run without "sh" and `runInShell` is `true`, it won't work. + return _runInShell(["sudo xcrun simctl openurl booted \"$universalLink\""]); + // return Process.run( + // "sh", + // ["-c", "xcrun simctl openurl booted \"$universalLink\""], + // ); + } + + /// Waits for the app with the given [appBundleId] to appear in memory. + /// + /// This method polls the OS to check if the app is running. To use a custom + /// polling duration, provide a [pollDuration]. + /// + /// This method fails if the app hasn't launched within the given [timeout] + /// duration. + static Future waitForAppToLaunch( + String appBundleId, { + Duration pollDuration = const Duration(milliseconds: 250), + Duration timeout = const Duration(seconds: 10), + }) async { + final now = DateTime.now(); + + bool isAppRunning = false; + do { + isAppRunning = await Xcrun.isAppRunning(appBundleId); + if (!isAppRunning) { + await Future.delayed(pollDuration); + } + } while (!isAppRunning && (DateTime.now().difference(now) < timeout)); + + return isAppRunning; + } + + /// Kills the app with the given [appBundleId] ID, e.g., `com.acme.myapp`. + static Future killApp(String appBundleId) async { + // final result = await Process.run( + // "xcrun", + // ["simctl", "terminate", "booted", appBundleId], + // runInShell: true, + // ); + + print("Sending xcrun simctl terminate command..."); + final process = await Process.start( + "sh", + ["-c", "xcrun simctl terminate booted $appBundleId"], + ); + print("terminate command process was started"); + + process.stdin.close(); + + stdout.addStream(process.stdout); + stderr.addStream(process.stderr); + + // process.stdout.transform(utf8.decoder).listen((log) { + // print("terminate command log: $log"); + // }); + // + // process.stderr.transform(utf8.decoder).listen((error) { + // print("terminate command error: $error"); + // }); + + print("Waiting for exit code..."); + final exitCode = await process.exitCode; + print("Killed app - exit code: $exitCode"); + } + + /// Clears all logs in the iOS log stream. + static Future clearLogs() async { + await _runInShell(["xcrun", "simctl", "spawn", "booted", "log", "erase"]); + } + + static Future _startInShell(List commandAndArgs) { + return Process.start("sh", ["-c", ...commandAndArgs]); + + // return Process.start( + // commandAndArgs.first, + // commandAndArgs.length > 1 ? commandAndArgs.sublist(1) : [], + // runInShell: true, + // ); + } + + static Future _runInShell(List commandAndArgs) async { + final command = commandAndArgs.join(" "); + print("Sending shell command: '$command'"); + final result = await Process.run("sh", ["--verbose", "--debug", "-c", command]); + print("Shell command exit code: ${result.exitCode}"); + + if (result.exitCode != 0) { + throw Exception(''' +Failed to execute command in a shell: +'$command' + +Exit code: ${result.exitCode} + +Stdout: +${result.stdout} + +Stderr: +${result.stderr}'''); + } + + return result; + + // return Process.run( + // commandAndArgs.first, + // commandAndArgs.length > 1 ? commandAndArgs.sublist(1) : [], + // runInShell: true, + // ); + } +} diff --git a/packages/flutter_test_runners/pubspec.yaml b/packages/flutter_test_runners/pubspec.yaml index ede39a4..4824344 100644 --- a/packages/flutter_test_runners/pubspec.yaml +++ b/packages/flutter_test_runners/pubspec.yaml @@ -12,7 +12,14 @@ dependencies: sdk: flutter flutter_test: sdk: flutter + flutter_driver: + sdk: flutter + meta: ^1.9.1 + test: any + vm_service: any + logging: ^1.3.0 + dev_dependencies: flutter_lints: ^2.0.0 diff --git a/pubspec.lock b/pubspec.lock index 949529f..5c7e4d3 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1,6 +1,22 @@ # Generated by pub # See https://dart.dev/tools/pub/glossary#lockfile packages: + _fe_analyzer_shared: + dependency: transitive + description: + name: _fe_analyzer_shared + sha256: "0b2f2bd91ba804e53a61d757b986f89f1f9eaed5b11e4b2f5a2468d86d6c9fc7" + url: "https://pub.dev" + source: hosted + version: "67.0.0" + analyzer: + dependency: transitive + description: + name: analyzer + sha256: "37577842a27e4338429a1cbc32679d508836510b056f1eedf0c8d20e39c1383d" + url: "https://pub.dev" + source: hosted + version: "6.4.1" ansi_styles: dependency: transitive description: @@ -73,6 +89,30 @@ packages: url: "https://pub.dev" source: hosted version: "0.6.0+1" + convert: + dependency: transitive + description: + name: convert + sha256: b30acd5944035672bc15c6b7a8b47d773e41e2f17de064350988c5d02adb1c68 + url: "https://pub.dev" + source: hosted + version: "3.1.2" + coverage: + dependency: transitive + description: + name: coverage + sha256: e3493833ea012784c740e341952298f1cc77f1f01b1bbc3eb4eecf6984fb7f43 + url: "https://pub.dev" + source: hosted + version: "1.11.1" + crypto: + dependency: transitive + description: + name: crypto + sha256: "1e445881f28f22d6140f181e07737b22f1e099a5e1ff94b0af2f9e4a463f4855" + url: "https://pub.dev" + source: hosted + version: "3.0.6" file: dependency: transitive description: @@ -81,6 +121,14 @@ packages: url: "https://pub.dev" source: hosted version: "6.1.4" + frontend_server_client: + dependency: transitive + description: + name: frontend_server_client + sha256: f64a0333a82f30b0cca061bc3d143813a486dc086b574bfb233b7c1372427694 + url: "https://pub.dev" + source: hosted + version: "4.0.0" glob: dependency: transitive description: @@ -105,6 +153,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.1.0" + http_multi_server: + dependency: transitive + description: + name: http_multi_server + sha256: aa6199f908078bb1c5efb8d8638d4ae191aac11b311132c3ef48ce352fb52ef8 + url: "https://pub.dev" + source: hosted + version: "3.2.2" http_parser: dependency: transitive description: @@ -121,6 +177,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.4" + js: + dependency: transitive + description: + name: js + sha256: c1b2e9b5ea78c45e1a0788d29606ba27dc5f71f019f32ca5140f61ef071838cf + url: "https://pub.dev" + source: hosted + version: "0.7.1" json_annotation: dependency: transitive description: @@ -129,14 +193,22 @@ packages: url: "https://pub.dev" source: hosted version: "4.8.1" + logging: + dependency: transitive + description: + name: logging + sha256: c8245ada5f1717ed44271ed1c26b8ce85ca3228fd2ffdb75468ab01979309d61 + url: "https://pub.dev" + source: hosted + version: "1.3.0" matcher: dependency: transitive description: name: matcher - sha256: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e" + sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2 url: "https://pub.dev" source: hosted - version: "0.12.16" + version: "0.12.17" melos: dependency: "direct main" description: @@ -149,10 +221,18 @@ packages: dependency: transitive description: name: meta - sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3" + sha256: e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c + url: "https://pub.dev" + source: hosted + version: "1.16.0" + mime: + dependency: transitive + description: + name: mime + sha256: "41a20518f0cb1256669420fdba0cd90d21561e560ac240f26ef8322e45bb7ed6" url: "https://pub.dev" source: hosted - version: "1.9.1" + version: "2.0.0" mustache_template: dependency: transitive description: @@ -161,6 +241,22 @@ packages: url: "https://pub.dev" source: hosted version: "2.0.0" + node_preamble: + dependency: transitive + description: + name: node_preamble + sha256: "6e7eac89047ab8a8d26cf16127b5ed26de65209847630400f9aefd7cd5c730db" + url: "https://pub.dev" + source: hosted + version: "2.0.2" + package_config: + dependency: transitive + description: + name: package_config + sha256: "92d4488434b520a62570293fbd33bb556c7d49230791c1b4bbd973baf6d2dc67" + url: "https://pub.dev" + source: hosted + version: "2.1.1" path: dependency: transitive description: @@ -233,6 +329,54 @@ packages: url: "https://pub.dev" source: hosted version: "3.2.1" + shelf: + dependency: transitive + description: + name: shelf + sha256: ad29c505aee705f41a4d8963641f91ac4cee3c8fad5947e033390a7bd8180fa4 + url: "https://pub.dev" + source: hosted + version: "1.4.1" + shelf_packages_handler: + dependency: transitive + description: + name: shelf_packages_handler + sha256: "89f967eca29607c933ba9571d838be31d67f53f6e4ee15147d5dc2934fee1b1e" + url: "https://pub.dev" + source: hosted + version: "3.0.2" + shelf_static: + dependency: transitive + description: + name: shelf_static + sha256: c87c3875f91262785dade62d135760c2c69cb217ac759485334c5857ad89f6e3 + url: "https://pub.dev" + source: hosted + version: "1.1.3" + shelf_web_socket: + dependency: transitive + description: + name: shelf_web_socket + sha256: cc36c297b52866d203dbf9332263c94becc2fe0ceaa9681d07b6ef9807023b67 + url: "https://pub.dev" + source: hosted + version: "2.0.1" + source_map_stack_trace: + dependency: transitive + description: + name: source_map_stack_trace + sha256: c0713a43e323c3302c2abe2a1cc89aa057a387101ebd280371d6a6c9fa68516b + url: "https://pub.dev" + source: hosted + version: "2.1.2" + source_maps: + dependency: transitive + description: + name: source_maps + sha256: "190222579a448b03896e0ca6eca5998fa810fda630c1d65e2f78b3f638f54812" + url: "https://pub.dev" + source: hosted + version: "0.10.13" source_span: dependency: transitive description: @@ -273,14 +417,30 @@ packages: url: "https://pub.dev" source: hosted version: "1.2.1" + test: + dependency: "direct main" + description: + name: test + sha256: "8391fbe68d520daf2314121764d38e37f934c02fd7301ad18307bd93bd6b725d" + url: "https://pub.dev" + source: hosted + version: "1.25.14" test_api: dependency: transitive description: name: test_api - sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b" + sha256: fb31f383e2ee25fbbfe06b40fe21e1e458d14080e3c67e7ba0acfde4df4e0bbd url: "https://pub.dev" source: hosted - version: "0.6.1" + version: "0.7.4" + test_core: + dependency: transitive + description: + name: test_core + sha256: "84d17c3486c8dfdbe5e12a50c8ae176d15e2a771b96909a9442b40173649ccaa" + url: "https://pub.dev" + source: hosted + version: "0.6.8" typed_data: dependency: transitive description: @@ -297,6 +457,54 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.0" + vm_service: + dependency: "direct main" + description: + name: vm_service + sha256: ddfa8d30d89985b96407efce8acbdd124701f96741f2d981ca860662f1c0dc02 + url: "https://pub.dev" + source: hosted + version: "15.0.0" + watcher: + dependency: transitive + description: + name: watcher + sha256: "69da27e49efa56a15f8afe8f4438c4ec02eff0a117df1b22ea4aad194fe1c104" + url: "https://pub.dev" + source: hosted + version: "1.1.1" + web: + dependency: transitive + description: + name: web + sha256: cd3543bd5798f6ad290ea73d210f423502e71900302dde696f8bff84bf89a1cb + url: "https://pub.dev" + source: hosted + version: "1.1.0" + web_socket: + dependency: transitive + description: + name: web_socket + sha256: "3c12d96c0c9a4eec095246debcea7b86c0324f22df69893d538fcc6f1b8cce83" + url: "https://pub.dev" + source: hosted + version: "0.1.6" + web_socket_channel: + dependency: transitive + description: + name: web_socket_channel + sha256: "9f187088ed104edd8662ca07af4b124465893caf063ba29758f97af57e61da8f" + url: "https://pub.dev" + source: hosted + version: "3.0.1" + webkit_inspection_protocol: + dependency: transitive + description: + name: webkit_inspection_protocol + sha256: "87d3f2333bb240704cd3f1c6b5b7acd8a10e7f0bc28c28dcf14e782014f4a572" + url: "https://pub.dev" + source: hosted + version: "1.2.1" yaml: dependency: transitive description: @@ -314,4 +522,4 @@ packages: source: hosted version: "2.1.1" sdks: - dart: ">=3.2.0-122.0.dev <4.0.0" + dart: ">=3.5.0 <4.0.0" diff --git a/pubspec.yaml b/pubspec.yaml index 3c523ae..9254500 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -5,4 +5,3 @@ environment: dependencies: melos: ^3.1.1 -