diff --git a/.github/workflows/patrol-prepare.yaml b/.github/workflows/patrol-prepare.yaml index 57b24706d..df8d56427 100644 --- a/.github/workflows/patrol-prepare.yaml +++ b/.github/workflows/patrol-prepare.yaml @@ -140,8 +140,8 @@ jobs: brew install xcbeautify # Disabled because of generated protobuf code - #- name: swift-format lint - # run: test -z $(swift-format lint --recursive --strict .) + - name: swift-format lint + run: test -z $(swift-format lint --recursive --strict .) - name: swift-format format if: success() || failure() @@ -154,41 +154,6 @@ jobs: if: success() || failure() run: | find . -iname '*.h' -o -iname '*.m' | xargs -I {} clang-format --dry-run --Werror {} - - - name: Set up Flutter - uses: subosito/flutter-action@v2 - with: - flutter-version: ${{ matrix.flutter-version }} - channel: ${{ matrix.flutter-channel }} - - - name: Preload Flutter artifacts - run: flutter precache --ios - - - name: Generate iOS build files - working-directory: packages/patrol/example - run: flutter build ios --config-only --simulator - - - name: Start iOS simulator - uses: futureware-tech/simulator-action@v2 - with: - model: iPhone 14 - os: iOS - os_version: 16.2 - erase_before_boot: true - shutdown_after_job: true - - - name: Run unit tests - working-directory: packages/patrol/example/ios - run: | - set -o pipefail - xcodebuild test \ - -workspace Runner.xcworkspace \ - -scheme Runner \ - -only-testing RunnerTests \ - -configuration Debug \ - -sdk iphoneos -destination 'platform=iOS Simulator,name=iPhone 14' \ - -derivedDataPath ../build/ios_unit | xcbeautify --renderer github-actions - prepare-flutter: name: Flutter ${{ matrix.flutter-version }} runs-on: ubuntu-latest @@ -224,7 +189,7 @@ jobs: - name: flutter test if: success() || failure() - run: flutter test --coverage + run: flutter test - name: Run analyzer if: success() || failure() diff --git a/.github/workflows/patrol_cli-prepare.yaml b/.github/workflows/patrol_cli-prepare.yaml index 322afdb3d..ee791f4b4 100644 --- a/.github/workflows/patrol_cli-prepare.yaml +++ b/.github/workflows/patrol_cli-prepare.yaml @@ -45,9 +45,7 @@ jobs: run: patrol - name: dart test - run: | - dart test --coverage coverage - dart run coverage:format_coverage --lcov --in coverage --out coverage/lcov.info --report-on lib + run: dart test - name: Run analyzer if: success() || failure() diff --git a/.github/workflows/patrol_devtools_extension-prepare.yaml b/.github/workflows/patrol_devtools_extension-prepare.yaml index 734a557fa..a75877987 100644 --- a/.github/workflows/patrol_devtools_extension-prepare.yaml +++ b/.github/workflows/patrol_devtools_extension-prepare.yaml @@ -36,7 +36,7 @@ jobs: - name: flutter test if: success() || failure() - run: flutter test --coverage + run: flutter test - name: Run analyzer if: success() || failure() diff --git a/.github/workflows/patrol_finders-prepare.yaml b/.github/workflows/patrol_finders-prepare.yaml index 780131fb8..928ca5fe3 100644 --- a/.github/workflows/patrol_finders-prepare.yaml +++ b/.github/workflows/patrol_finders-prepare.yaml @@ -36,7 +36,7 @@ jobs: - name: flutter test if: success() || failure() - run: flutter test --coverage + run: flutter test - name: Run analyzer if: success() || failure() diff --git a/.github/workflows/prepare-e2e_app.yaml b/.github/workflows/prepare-e2e_app.yaml new file mode 100644 index 000000000..310e9b2ec --- /dev/null +++ b/.github/workflows/prepare-e2e_app.yaml @@ -0,0 +1,234 @@ +name: prepare e2e_app + +on: + workflow_dispatch: + pull_request: + paths: + - '**' + - '!**.md' # ignore readmes + - '!**.mdx' # ignore docs + +jobs: + prepare-android-on-windows: + runs-on: ${{ matrix.os }} + name: Android on ${{ matrix.os }} + + strategy: + fail-fast: false + matrix: + os: [windows-latest] + flutter-version: ['3.16.x'] + flutter-channel: ['stable'] + + defaults: + run: + working-directory: dev/e2e_app/android + + steps: + - name: Clone repository + uses: actions/checkout@v4 + + - name: Set up Java + uses: actions/setup-java@v3 + with: + distribution: temurin + java-version: 17 + + - name: Set up Flutter + uses: subosito/flutter-action@v2 + with: + flutter-version: ${{ matrix.flutter-version }} + channel: ${{ matrix.flutter-channel }} + + - name: Preload Flutter artifacts + run: flutter precache --android + + - name: Generate Gradle wrapper + run: flutter build apk --config-only + + - name: ktlint check + run: .\gradlew.bat :patrol:ktlintCheck + + - name: ktlint format + run: .\gradlew.bat :patrol:ktlintFormat + + - name: Build app with Gradle + run: .\gradlew.bat :app:assembleDebug + + - name: Build app with Flutter tool + run: flutter build apk --debug + + prepare-android-on-linux: + runs-on: ${{ matrix.os }} + name: Android on ${{ matrix.os }} + + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest] + flutter-version: ['3.16.x'] + flutter-channel: ['stable'] + + defaults: + run: + working-directory: dev/e2e_app/android + + steps: + - name: Clone repository + uses: actions/checkout@v4 + + - name: Set up Java + uses: actions/setup-java@v3 + with: + distribution: temurin + java-version: 17 + + - name: Set up Flutter + uses: subosito/flutter-action@v2 + with: + flutter-version: ${{ matrix.flutter-version }} + channel: ${{ matrix.flutter-channel }} + + - name: Preload Flutter artifacts + run: flutter precache --android + + - name: Generate Gradle wrapper + run: flutter build apk --config-only + + - name: Run unit tests + if: success() || failure() + run: ./gradlew :patrol:testDebug + + - name: ktlint check + if: success() || failure() + run: ./gradlew :patrol:ktlintCheck + + - name: ktlint format + if: success() || failure() + run: ./gradlew :patrol:ktlintFormat + + - name: Build app with Gradle + run: ./gradlew :app:assembleDebug + + - name: Build app with Flutter tool + run: flutter build apk --debug + + prepare-ios: + runs-on: ${{ matrix.os }} + name: iOS on ${{ matrix.os }} + + strategy: + fail-fast: false + matrix: + os: [macos-latest] + flutter-version: ['3.16.x'] + flutter-channel: ['stable'] + + defaults: + run: + working-directory: dev/e2e_app/ios + + steps: + - name: Clone repository + uses: actions/checkout@v4 + + - name: Install tools + run: | + brew update + brew install swift-format + brew install clang-format + brew install xcbeautify + + - name: swift-format lint + run: test -z $(swift-format lint --recursive --strict .) + + - name: swift-format format + if: success() || failure() + run: | + swift-format format --recursive --in-place . + git update-index --refresh + git diff-index --quiet HEAD -- + + - name: clang-format + if: success() || failure() + run: | + find . -iname '*.h' -o -iname '*.m' | xargs -I {} clang-format --dry-run --Werror {} + + - name: Set up Flutter + uses: subosito/flutter-action@v2 + with: + flutter-version: ${{ matrix.flutter-version }} + channel: ${{ matrix.flutter-channel }} + + - name: Preload Flutter artifacts + run: flutter precache --ios + + - name: Generate iOS build files + run: flutter build ios --config-only --simulator + + - name: Start iOS simulator + uses: futureware-tech/simulator-action@v2 + with: + model: iPhone 14 + os: iOS + os_version: 16.2 + erase_before_boot: true + shutdown_after_job: true + + - name: Run unit tests + run: | + set -o pipefail + xcodebuild test \ + -workspace Runner.xcworkspace \ + -scheme Runner \ + -only-testing RunnerTests \ + -configuration Debug \ + -sdk iphoneos -destination 'platform=iOS Simulator,name=iPhone 14' \ + -derivedDataPath ../build/ios_unit | xcbeautify --renderer github-actions + + prepare-flutter: + name: Flutter ${{ matrix.flutter-version }} + runs-on: ubuntu-latest + + strategy: + fail-fast: false + matrix: + flutter-version: ['3.16.x'] + flutter-channel: ['stable'] + + defaults: + run: + working-directory: dev/e2e_app + + steps: + - name: Clone repository + uses: actions/checkout@v4 + + - name: Set up Flutter + uses: subosito/flutter-action@v2 + with: + flutter-version: ${{ matrix.flutter-version }} + channel: ${{ matrix.flutter-channel }} + + - name: Set up Melos and activate workspace + working-directory: . + run: | + dart pub global activate melos + melos bootstrap + + - name: flutter pub get + run: flutter pub get + + - name: flutter test + if: success() || failure() + run: flutter test + + - name: Run analyzer + if: success() || failure() + run: | + flutter analyze + dart run custom_lint + + - name: dart format + if: success() || failure() + run: dart format --set-exit-if-changed . diff --git a/.github/workflows/test-android-device.yaml b/.github/workflows/test-android-device.yaml index e9398cde4..bfa1ae384 100644 --- a/.github/workflows/test-android-device.yaml +++ b/.github/workflows/test-android-device.yaml @@ -30,7 +30,7 @@ jobs: defaults: run: - working-directory: packages/patrol/example + working-directory: dev/e2e_app steps: - name: Clone repository diff --git a/.github/workflows/test-android-emulator-webview.yaml b/.github/workflows/test-android-emulator-webview.yaml index 19b138dbe..97f9ecdfd 100644 --- a/.github/workflows/test-android-emulator-webview.yaml +++ b/.github/workflows/test-android-emulator-webview.yaml @@ -23,7 +23,7 @@ jobs: defaults: run: - working-directory: packages/patrol/example + working-directory: dev/e2e_app steps: - name: Clone repository diff --git a/.github/workflows/test-android-emulator.yaml b/.github/workflows/test-android-emulator.yaml index 71ab8f890..e3d36935e 100644 --- a/.github/workflows/test-android-emulator.yaml +++ b/.github/workflows/test-android-emulator.yaml @@ -24,7 +24,7 @@ jobs: defaults: run: - working-directory: packages/patrol/example + working-directory: dev/e2e_app steps: - name: Clone repository diff --git a/.github/workflows/test-ios-device.yaml b/.github/workflows/test-ios-device.yaml index 53d2f67f6..a8cedf4b3 100644 --- a/.github/workflows/test-ios-device.yaml +++ b/.github/workflows/test-ios-device.yaml @@ -27,14 +27,14 @@ jobs: defaults: run: - working-directory: packages/patrol/example + working-directory: dev/e2e_app steps: - name: Clone repository uses: actions/checkout@v4 - name: Add current platform to Gemfile - working-directory: packages/patrol/example/ios + working-directory: dev/e2e_app/ios run: bundle lock --add-platform ruby - name: Set up Ruby @@ -42,14 +42,14 @@ jobs: with: ruby-version: '3.2' bundler-cache: true - working-directory: packages/patrol/example/ios + working-directory: dev/e2e_app/ios - name: Set up fastlane - working-directory: packages/patrol/example/ios + working-directory: dev/e2e_app/ios run: bundle install - name: Run fastlane match - working-directory: packages/patrol/example/ios + working-directory: dev/e2e_app/ios env: MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }} GIT_USERNAME: ${{ secrets.PATROL_FASTLANE_CERTS_REPO_TOKEN_USERNAME }} diff --git a/.github/workflows/test-ios-simulator-webview.yaml b/.github/workflows/test-ios-simulator-webview.yaml index 6cf1c03b0..25f7b12e5 100644 --- a/.github/workflows/test-ios-simulator-webview.yaml +++ b/.github/workflows/test-ios-simulator-webview.yaml @@ -27,7 +27,7 @@ jobs: defaults: run: - working-directory: packages/patrol/example + working-directory: dev/e2e_app steps: - name: Clone repository @@ -126,14 +126,14 @@ jobs: with: name: Logs from ${{ matrix.device_model }} path: | - ${{ github.workspace }}/packages/patrol/example/all_simulator_logs.txt + ${{ github.workspace }}/dev/e2e_app/all_simulator_logs.txt - name: Upload captured video to artifacts if: ${{ (failure() || success()) && contains(fromJson('["success", "failure"]'), steps.tests_step.conclusion) }} uses: actions/upload-artifact@v3 with: name: Captured video from ${{ matrix.device_model }}.mp4 - path: ${{ github.workspace }}/packages/patrol/example/${{ matrix.device_model }}.mp4 + path: ${{ github.workspace }}/dev/e2e_app/${{ matrix.device_model }}.mp4 call_send_slack_message: name: Notify on Slack diff --git a/.github/workflows/test-ios-simulator.yaml b/.github/workflows/test-ios-simulator.yaml index 9aab32421..67da6aeb1 100644 --- a/.github/workflows/test-ios-simulator.yaml +++ b/.github/workflows/test-ios-simulator.yaml @@ -28,7 +28,7 @@ jobs: defaults: run: - working-directory: packages/patrol/example + working-directory: dev/e2e_app steps: - name: Clone repository @@ -86,7 +86,7 @@ jobs: echo "EXCLUDED_TESTS=$TESTS_TO_EXCLUDE" >> "$GITHUB_OUTPUT" echo "EXCLUDED_TESTS=$target_paths" >> "$GITHUB_ENV" - - name: Run tests + - name: Run UI tests id: tests_step run: | xcrun simctl io booted recordVideo --codec=h264 "${{ matrix.device_model }}.mp4" & @@ -143,14 +143,14 @@ jobs: with: name: Logs from ${{ matrix.device_model }} path: | - ${{ github.workspace }}/packages/patrol/example/all_simulator_logs.txt + ${{ github.workspace }}/dev/e2e_app/all_simulator_logs.txt - name: Upload captured video to artifacts if: ${{ (failure() || success()) && contains(fromJson('["success", "failure"]'), steps.tests_step.conclusion) }} uses: actions/upload-artifact@v3 with: name: Captured video from ${{ matrix.device_model }}.mp4 - path: ${{ github.workspace }}/packages/patrol/example/${{ matrix.device_model }}.mp4 + path: ${{ github.workspace }}/dev/e2e_app/${{ matrix.device_model }}.mp4 call_send_slack_message: name: Notify on Slack diff --git a/dev/cli_tests/patrol_develop_test.dart b/dev/cli_tests/patrol_develop_test.dart index c61102c66..f9ee4d243 100644 --- a/dev/cli_tests/patrol_develop_test.dart +++ b/dev/cli_tests/patrol_develop_test.dart @@ -46,9 +46,7 @@ void main(List args) async { Timer? inactivityTimer; final output = StringBuffer(); - final exampleAppDirectory = io.Directory( - join('..', '..', 'packages', 'patrol', 'example'), - ); + final exampleAppDirectory = io.Directory(join('..', 'e2e_app')); final exampleTestFile = io.File( join(exampleAppDirectory.path, 'integration_test', 'example_test.dart'), ); diff --git a/dev/e2e_app/.gitignore b/dev/e2e_app/.gitignore new file mode 100644 index 000000000..2c555b0b2 --- /dev/null +++ b/dev/e2e_app/.gitignore @@ -0,0 +1,53 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ + +# 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 +.packages +.pub-cache/ +.pub/ +/build/ + +# Web related +lib/generated_plugin_registrant.dart + +# 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 + +/screenshots +hello.txt +counter_text.txt + +# Generated by Patrol CLI +test_bundle.dart diff --git a/packages/patrol/example/.metadata b/dev/e2e_app/.metadata similarity index 100% rename from packages/patrol/example/.metadata rename to dev/e2e_app/.metadata diff --git a/dev/e2e_app/README.md b/dev/e2e_app/README.md new file mode 100644 index 000000000..dee666b6a --- /dev/null +++ b/dev/e2e_app/README.md @@ -0,0 +1,45 @@ +# patrol e2e app + +This application is used to test Patrol itself. + +## Building + +Make sure to use the compatible Patrol CLI version. The easiest way is to run: + +```console +$ dart pub global activate --source path packages/patrol_cli && patrol +``` + +from the repository root. + +Once you have the right Patrol CLI version, building artifacts for testing is +easy. + +### Android + +Run in the example app's root: + +```console +$ patrol build android +``` + +This builds 2 APKs: + +- the app under test: `/build/app/outputs/apk/debug/app-debug.apk` +- the instrumentation app: `/build/app/outputs/apk/androidTest/debug/app-debug-androidTest.apk` + +### iOS device + +Run in the example app's root: + +```console +$ patrol build ios --release +``` + +### iOS simulator + +Run in the example app's root: + +``` +$ patrol build ios --debug --simulator +``` diff --git a/dev/e2e_app/analysis_options.yaml b/dev/e2e_app/analysis_options.yaml new file mode 100644 index 000000000..98093f93d --- /dev/null +++ b/dev/e2e_app/analysis_options.yaml @@ -0,0 +1,6 @@ +include: package:leancode_lint/analysis_options.yaml + +linter: + rules: + prefer_const_constructors: false + avoid_print: false diff --git a/dev/e2e_app/android/.gitignore b/dev/e2e_app/android/.gitignore new file mode 100644 index 000000000..ea6a81579 --- /dev/null +++ b/dev/e2e_app/android/.gitignore @@ -0,0 +1,16 @@ +gradle-wrapper.jar +/.gradle +/captures/ +/gradlew +/gradlew.bat +/local.properties +GeneratedPluginRegistrant.java + +# Remember to never publicly share your keystore. +# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app +key.properties +**/*.keystore +**/*.jks + +test-reports +test-results diff --git a/dev/e2e_app/android/app/build.gradle b/dev/e2e_app/android/app/build.gradle new file mode 100644 index 000000000..1aea450db --- /dev/null +++ b/dev/e2e_app/android/app/build.gradle @@ -0,0 +1,65 @@ +plugins { + id "com.android.application" + id "org.jetbrains.kotlin.android" + id "dev.flutter.flutter-gradle-plugin" +} + +def localProperties = new Properties() +def localPropertiesFile = rootProject.file("local.properties") +if (localPropertiesFile.exists()) { + localPropertiesFile.withReader("UTF-8") { reader -> + localProperties.load(reader) + } +} + +def flutterVersionCode = localProperties.getProperty("flutter.versionCode") +if (flutterVersionCode == null) { + flutterVersionCode = "1" +} + +def flutterVersionName = localProperties.getProperty("flutter.versionName") +if (flutterVersionName == null) { + flutterVersionName = "1.0" +} + +android { + compileSdk 33 + namespace "pl.leancode.patrol.e2e_app" + + kotlinOptions { + jvmTarget = "1.8" + } + + sourceSets { + main.java.srcDirs += "src/main/kotlin" + } + + defaultConfig { + applicationId "pl.leancode.patrol.e2e_app" + minSdk 21 + targetSdk 33 + versionCode flutterVersionCode.toInteger() + versionName flutterVersionName + testInstrumentationRunner "pl.leancode.patrol.PatrolJUnitRunner" + testInstrumentationRunnerArguments clearPackageData: "true" + } + + buildTypes { + release { + signingConfig signingConfigs.debug + } + } + + testOptions { + execution "ANDROIDX_TEST_ORCHESTRATOR" + } +} + +flutter { + source "../.." +} + +dependencies { + implementation "org.jetbrains.kotlin:kotlin-stdlib:1.9.20" + androidTestUtil "androidx.test:orchestrator:1.4.2" +} diff --git a/dev/e2e_app/android/app/src/androidTest/java/pl/leancode/patrol/e2e_app/MainActivityTest.java b/dev/e2e_app/android/app/src/androidTest/java/pl/leancode/patrol/e2e_app/MainActivityTest.java new file mode 100644 index 000000000..c59e67de8 --- /dev/null +++ b/dev/e2e_app/android/app/src/androidTest/java/pl/leancode/patrol/e2e_app/MainActivityTest.java @@ -0,0 +1,31 @@ +package pl.leancode.patrol.e2e_app; + +import androidx.test.platform.app.InstrumentationRegistry; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameters; +import pl.leancode.patrol.PatrolJUnitRunner; + +@RunWith(Parameterized.class) +public class MainActivityTest { + @Parameters(name = "{0}") + public static Object[] testCases() { + PatrolJUnitRunner instrumentation = (PatrolJUnitRunner) InstrumentationRegistry.getInstrumentation(); + instrumentation.setUp(MainActivity.class); + instrumentation.waitForPatrolAppService(); + return instrumentation.listDartTests(); + } + + public MainActivityTest(String dartTestName) { + this.dartTestName = dartTestName; + } + + private final String dartTestName; + + @Test + public void runDartTest() { + PatrolJUnitRunner instrumentation = (PatrolJUnitRunner) InstrumentationRegistry.getInstrumentation(); + instrumentation.runDartTest(dartTestName); + } +} diff --git a/dev/e2e_app/android/app/src/main/AndroidManifest.xml b/dev/e2e_app/android/app/src/main/AndroidManifest.xml new file mode 100644 index 000000000..0fc4be994 --- /dev/null +++ b/dev/e2e_app/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dev/e2e_app/android/app/src/main/kotlin/pl/leancode/patrol/e2e_app/MainActivity.kt b/dev/e2e_app/android/app/src/main/kotlin/pl/leancode/patrol/e2e_app/MainActivity.kt new file mode 100644 index 000000000..2ebf56819 --- /dev/null +++ b/dev/e2e_app/android/app/src/main/kotlin/pl/leancode/patrol/e2e_app/MainActivity.kt @@ -0,0 +1,5 @@ +package pl.leancode.patrol.e2e_app + +import io.flutter.embedding.android.FlutterActivity + +class MainActivity : FlutterActivity() diff --git a/dev/e2e_app/android/app/src/main/res/drawable-v21/launch_background.xml b/dev/e2e_app/android/app/src/main/res/drawable-v21/launch_background.xml new file mode 100644 index 000000000..f74085f3f --- /dev/null +++ b/dev/e2e_app/android/app/src/main/res/drawable-v21/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/dev/e2e_app/android/app/src/main/res/drawable/launch_background.xml b/dev/e2e_app/android/app/src/main/res/drawable/launch_background.xml new file mode 100644 index 000000000..304732f88 --- /dev/null +++ b/dev/e2e_app/android/app/src/main/res/drawable/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/dev/e2e_app/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/dev/e2e_app/android/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 000000000..db77bb4b7 Binary files /dev/null and b/dev/e2e_app/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/dev/e2e_app/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/dev/e2e_app/android/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 000000000..17987b79b Binary files /dev/null and b/dev/e2e_app/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/dev/e2e_app/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/dev/e2e_app/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 000000000..09d439148 Binary files /dev/null and b/dev/e2e_app/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/dev/e2e_app/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/dev/e2e_app/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 000000000..d5f1c8d34 Binary files /dev/null and b/dev/e2e_app/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/dev/e2e_app/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/dev/e2e_app/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 000000000..4d6372eeb Binary files /dev/null and b/dev/e2e_app/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/dev/e2e_app/android/app/src/main/res/values-night/styles.xml b/dev/e2e_app/android/app/src/main/res/values-night/styles.xml new file mode 100644 index 000000000..3db14bb53 --- /dev/null +++ b/dev/e2e_app/android/app/src/main/res/values-night/styles.xml @@ -0,0 +1,18 @@ + + + + + + + diff --git a/dev/e2e_app/android/app/src/main/res/values/styles.xml b/dev/e2e_app/android/app/src/main/res/values/styles.xml new file mode 100644 index 000000000..d460d1e92 --- /dev/null +++ b/dev/e2e_app/android/app/src/main/res/values/styles.xml @@ -0,0 +1,18 @@ + + + + + + + diff --git a/dev/e2e_app/android/build.gradle b/dev/e2e_app/android/build.gradle new file mode 100644 index 000000000..da0d8da81 --- /dev/null +++ b/dev/e2e_app/android/build.gradle @@ -0,0 +1,9 @@ +rootProject.buildDir = "../build" +subprojects { + project.buildDir = "${rootProject.buildDir}/${project.name}" + project.evaluationDependsOn(":app") +} + +tasks.register("clean", Delete) { + delete rootProject.buildDir +} diff --git a/dev/e2e_app/android/gradle.properties b/dev/e2e_app/android/gradle.properties new file mode 100644 index 000000000..d9cf55df7 --- /dev/null +++ b/dev/e2e_app/android/gradle.properties @@ -0,0 +1,2 @@ +org.gradle.jvmargs=-Xmx1536M +android.useAndroidX=true diff --git a/dev/e2e_app/android/gradle/wrapper/gradle-wrapper.properties b/dev/e2e_app/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 000000000..cb046be63 --- /dev/null +++ b/dev/e2e_app/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Fri Jun 23 08:50:38 CEST 2017 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.2-all.zip diff --git a/dev/e2e_app/android/settings.gradle b/dev/e2e_app/android/settings.gradle new file mode 100644 index 000000000..6cf68fd84 --- /dev/null +++ b/dev/e2e_app/android/settings.gradle @@ -0,0 +1,26 @@ +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 + } + settings.ext.flutterSdkPath = flutterSdkPath() + + includeBuild("${settings.ext.flutterSdkPath}/packages/flutter_tools/gradle") + + repositories { + google() + mavenCentral() + gradlePluginPortal() + } +} + +plugins { + id "dev.flutter.flutter-plugin-loader" + id "com.android.application" version "7.4.2" apply false + id "org.jetbrains.kotlin.android" version "1.9.20" apply false +} + +include ":app" diff --git a/dev/e2e_app/devtools_options.yaml b/dev/e2e_app/devtools_options.yaml new file mode 100644 index 000000000..59984d36c --- /dev/null +++ b/dev/e2e_app/devtools_options.yaml @@ -0,0 +1,2 @@ +extensions: + - patrol: true diff --git a/packages/patrol/example/emulatorwtf.yaml b/dev/e2e_app/emulatorwtf.yaml similarity index 100% rename from packages/patrol/example/emulatorwtf.yaml rename to dev/e2e_app/emulatorwtf.yaml diff --git a/packages/patrol/example/integration_test/android_app_test.dart b/dev/e2e_app/integration_test/android_app_test.dart similarity index 100% rename from packages/patrol/example/integration_test/android_app_test.dart rename to dev/e2e_app/integration_test/android_app_test.dart diff --git a/packages/patrol/example/integration_test/common.dart b/dev/e2e_app/integration_test/common.dart similarity index 94% rename from packages/patrol/example/integration_test/common.dart rename to dev/e2e_app/integration_test/common.dart index 6cdfff56e..75ed61f96 100644 --- a/packages/patrol/example/integration_test/common.dart +++ b/dev/e2e_app/integration_test/common.dart @@ -1,6 +1,6 @@ +import 'package:e2e_app/main.dart' as app_main; import 'package:flutter_test/flutter_test.dart'; import 'package:patrol/patrol.dart'; -import 'package:patrol_example/main.dart' as app_main; export 'package:flutter_test/flutter_test.dart'; export 'package:patrol/patrol.dart'; diff --git a/packages/patrol/example/integration_test/example_test.dart b/dev/e2e_app/integration_test/example_test.dart similarity index 100% rename from packages/patrol/example/integration_test/example_test.dart rename to dev/e2e_app/integration_test/example_test.dart diff --git a/packages/patrol/example/integration_test/internal/README b/dev/e2e_app/integration_test/internal/README similarity index 100% rename from packages/patrol/example/integration_test/internal/README rename to dev/e2e_app/integration_test/internal/README diff --git a/packages/patrol/example/integration_test/internal/group_test.dart b/dev/e2e_app/integration_test/internal/group_test.dart similarity index 100% rename from packages/patrol/example/integration_test/internal/group_test.dart rename to dev/e2e_app/integration_test/internal/group_test.dart diff --git a/packages/patrol/example/integration_test/internal/long_name_test.dart b/dev/e2e_app/integration_test/internal/long_name_test.dart similarity index 100% rename from packages/patrol/example/integration_test/internal/long_name_test.dart rename to dev/e2e_app/integration_test/internal/long_name_test.dart diff --git a/packages/patrol/example/integration_test/open_app_test.dart b/dev/e2e_app/integration_test/open_app_test.dart similarity index 100% rename from packages/patrol/example/integration_test/open_app_test.dart rename to dev/e2e_app/integration_test/open_app_test.dart diff --git a/packages/patrol/example/integration_test/open_quick_settings_test.dart b/dev/e2e_app/integration_test/open_quick_settings_test.dart similarity index 100% rename from packages/patrol/example/integration_test/open_quick_settings_test.dart rename to dev/e2e_app/integration_test/open_quick_settings_test.dart diff --git a/packages/patrol/example/integration_test/permissions/notifications_test.dart b/dev/e2e_app/integration_test/permissions/notifications_test.dart similarity index 100% rename from packages/patrol/example/integration_test/permissions/notifications_test.dart rename to dev/e2e_app/integration_test/permissions/notifications_test.dart diff --git a/packages/patrol/example/integration_test/permissions/permissions_location_test.dart b/dev/e2e_app/integration_test/permissions/permissions_location_test.dart similarity index 100% rename from packages/patrol/example/integration_test/permissions/permissions_location_test.dart rename to dev/e2e_app/integration_test/permissions/permissions_location_test.dart diff --git a/packages/patrol/example/integration_test/permissions/permissions_many_test.dart b/dev/e2e_app/integration_test/permissions/permissions_many_test.dart similarity index 100% rename from packages/patrol/example/integration_test/permissions/permissions_many_test.dart rename to dev/e2e_app/integration_test/permissions/permissions_many_test.dart diff --git a/packages/patrol/example/integration_test/service_airplane_mode_test.dart b/dev/e2e_app/integration_test/service_airplane_mode_test.dart similarity index 100% rename from packages/patrol/example/integration_test/service_airplane_mode_test.dart rename to dev/e2e_app/integration_test/service_airplane_mode_test.dart diff --git a/packages/patrol/example/integration_test/service_bluetooth_test.dart b/dev/e2e_app/integration_test/service_bluetooth_test.dart similarity index 100% rename from packages/patrol/example/integration_test/service_bluetooth_test.dart rename to dev/e2e_app/integration_test/service_bluetooth_test.dart diff --git a/packages/patrol/example/integration_test/service_cellular_test.dart b/dev/e2e_app/integration_test/service_cellular_test.dart similarity index 100% rename from packages/patrol/example/integration_test/service_cellular_test.dart rename to dev/e2e_app/integration_test/service_cellular_test.dart diff --git a/packages/patrol/example/integration_test/service_dark_mode_test.dart b/dev/e2e_app/integration_test/service_dark_mode_test.dart similarity index 100% rename from packages/patrol/example/integration_test/service_dark_mode_test.dart rename to dev/e2e_app/integration_test/service_dark_mode_test.dart diff --git a/packages/patrol/example/integration_test/service_wifi_test.dart b/dev/e2e_app/integration_test/service_wifi_test.dart similarity index 100% rename from packages/patrol/example/integration_test/service_wifi_test.dart rename to dev/e2e_app/integration_test/service_wifi_test.dart diff --git a/packages/patrol/example/integration_test/swipe_test.dart b/dev/e2e_app/integration_test/swipe_test.dart similarity index 100% rename from packages/patrol/example/integration_test/swipe_test.dart rename to dev/e2e_app/integration_test/swipe_test.dart diff --git a/packages/patrol/example/integration_test/webview_hackernews_test.dart b/dev/e2e_app/integration_test/webview_hackernews_test.dart similarity index 100% rename from packages/patrol/example/integration_test/webview_hackernews_test.dart rename to dev/e2e_app/integration_test/webview_hackernews_test.dart diff --git a/packages/patrol/example/integration_test/webview_leancode_test.dart b/dev/e2e_app/integration_test/webview_leancode_test.dart similarity index 100% rename from packages/patrol/example/integration_test/webview_leancode_test.dart rename to dev/e2e_app/integration_test/webview_leancode_test.dart diff --git a/packages/patrol/example/integration_test/webview_stackoverflow_test.dart b/dev/e2e_app/integration_test/webview_stackoverflow_test.dart similarity index 100% rename from packages/patrol/example/integration_test/webview_stackoverflow_test.dart rename to dev/e2e_app/integration_test/webview_stackoverflow_test.dart diff --git a/dev/e2e_app/ios/.gitignore b/dev/e2e_app/ios/.gitignore new file mode 100644 index 000000000..3cbd03717 --- /dev/null +++ b/dev/e2e_app/ios/.gitignore @@ -0,0 +1,39 @@ +**/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 + +# Files for XCTestHTMLReport +TestResults +TestResults.xcresult +index.html diff --git a/dev/e2e_app/ios/Flutter/AppFrameworkInfo.plist b/dev/e2e_app/ios/Flutter/AppFrameworkInfo.plist new file mode 100644 index 000000000..9625e105d --- /dev/null +++ b/dev/e2e_app/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 + 11.0 + + diff --git a/dev/e2e_app/ios/Flutter/Debug.xcconfig b/dev/e2e_app/ios/Flutter/Debug.xcconfig new file mode 100644 index 000000000..ec97fc6f3 --- /dev/null +++ b/dev/e2e_app/ios/Flutter/Debug.xcconfig @@ -0,0 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" +#include "Generated.xcconfig" diff --git a/dev/e2e_app/ios/Flutter/Release.xcconfig b/dev/e2e_app/ios/Flutter/Release.xcconfig new file mode 100644 index 000000000..c4855bfe2 --- /dev/null +++ b/dev/e2e_app/ios/Flutter/Release.xcconfig @@ -0,0 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" +#include "Generated.xcconfig" diff --git a/packages/patrol/example/ios/Gemfile b/dev/e2e_app/ios/Gemfile similarity index 100% rename from packages/patrol/example/ios/Gemfile rename to dev/e2e_app/ios/Gemfile diff --git a/packages/patrol/example/ios/Gemfile.lock b/dev/e2e_app/ios/Gemfile.lock similarity index 100% rename from packages/patrol/example/ios/Gemfile.lock rename to dev/e2e_app/ios/Gemfile.lock diff --git a/packages/patrol/example/ios/Matchfile b/dev/e2e_app/ios/Matchfile similarity index 100% rename from packages/patrol/example/ios/Matchfile rename to dev/e2e_app/ios/Matchfile diff --git a/dev/e2e_app/ios/Podfile b/dev/e2e_app/ios/Podfile new file mode 100644 index 000000000..30eedc704 --- /dev/null +++ b/dev/e2e_app/ios/Podfile @@ -0,0 +1,95 @@ +# Uncomment this line to define a global platform for your project +ios_deployment_target = '11.0' +platform :ios, ios_deployment_target + +# CocoaPods analytics sends network stats synchronously affecting flutter build latency. +ENV['COCOAPODS_DISABLE_STATS'] = 'true' + +project 'Runner', { + 'Debug' => :debug, + 'Profile' => :release, + 'Release' => :release, +} + +def flutter_root + generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) + unless File.exist?(generated_xcode_build_settings_path) + raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" + end + + File.foreach(generated_xcode_build_settings_path) do |line| + matches = line.match(/FLUTTER_ROOT\=(.*)/) + return matches[1].strip if matches + end + raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" +end + +require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) + +flutter_ios_podfile_setup + +target 'Runner' do + use_frameworks! + use_modular_headers! + + target 'RunnerUITests' do + inherit! :complete + end + + flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) +end + +post_install do |installer| + installer.pods_project.targets.each do |target| + flutter_additional_ios_build_settings(target) + + target.build_configurations.each do |config| + config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = ios_deployment_target + config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [ + '$(inherited)', + + ## dart: PermissionGroup.calendar + # 'PERMISSION_EVENTS=1', + + ## dart: PermissionGroup.reminders + # 'PERMISSION_REMINDERS=1', + + ## dart: PermissionGroup.contacts + 'PERMISSION_CONTACTS=1', + + ## dart: PermissionGroup.camera + 'PERMISSION_CAMERA=1', + + ## dart: PermissionGroup.microphone + 'PERMISSION_MICROPHONE=1', + + ## dart: PermissionGroup.speech + # 'PERMISSION_SPEECH_RECOGNIZER=1', + + ## dart: PermissionGroup.photos + # 'PERMISSION_PHOTOS=1', + + ## dart: [PermissionGroup.location, PermissionGroup.locationAlways, PermissionGroup.locationWhenInUse] + 'PERMISSION_LOCATION=1', + + ## dart: PermissionGroup.notification + # 'PERMISSION_NOTIFICATIONS=1', + + ## dart: PermissionGroup.mediaLibrary + # 'PERMISSION_MEDIA_LIBRARY=1', + + ## dart: PermissionGroup.sensors + # 'PERMISSION_SENSORS=1', + + ## dart: PermissionGroup.bluetooth + # 'PERMISSION_BLUETOOTH=1', + + ## dart: PermissionGroup.appTrackingTransparency + # 'PERMISSION_APP_TRACKING_TRANSPARENCY=1', + + ## dart: PermissionGroup.criticalAlerts + # 'PERMISSION_CRITICAL_ALERTS=1' + ] + end + end +end diff --git a/dev/e2e_app/ios/Podfile.lock b/dev/e2e_app/ios/Podfile.lock new file mode 100644 index 000000000..4e0d4d622 --- /dev/null +++ b/dev/e2e_app/ios/Podfile.lock @@ -0,0 +1,67 @@ +PODS: + - CocoaAsyncSocket (7.6.5) + - Flutter (1.0.0) + - flutter_local_notifications (0.0.1): + - Flutter + - flutter_timezone (0.0.1): + - Flutter + - geolocator_apple (1.2.0): + - Flutter + - HTTPParserC (2.9.4) + - patrol (0.0.1): + - Flutter + - Telegraph (~> 0.30.0) + - permission_handler_apple (9.1.1): + - Flutter + - Telegraph (0.30.0): + - CocoaAsyncSocket (~> 7.6) + - HTTPParserC (~> 2.9) + - webview_flutter_wkwebview (0.0.1): + - Flutter + +DEPENDENCIES: + - Flutter (from `Flutter`) + - flutter_local_notifications (from `.symlinks/plugins/flutter_local_notifications/ios`) + - flutter_timezone (from `.symlinks/plugins/flutter_timezone/ios`) + - geolocator_apple (from `.symlinks/plugins/geolocator_apple/ios`) + - patrol (from `.symlinks/plugins/patrol/ios`) + - permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/ios`) + - webview_flutter_wkwebview (from `.symlinks/plugins/webview_flutter_wkwebview/ios`) + +SPEC REPOS: + trunk: + - CocoaAsyncSocket + - HTTPParserC + - Telegraph + +EXTERNAL SOURCES: + Flutter: + :path: Flutter + flutter_local_notifications: + :path: ".symlinks/plugins/flutter_local_notifications/ios" + flutter_timezone: + :path: ".symlinks/plugins/flutter_timezone/ios" + geolocator_apple: + :path: ".symlinks/plugins/geolocator_apple/ios" + patrol: + :path: ".symlinks/plugins/patrol/ios" + permission_handler_apple: + :path: ".symlinks/plugins/permission_handler_apple/ios" + webview_flutter_wkwebview: + :path: ".symlinks/plugins/webview_flutter_wkwebview/ios" + +SPEC CHECKSUMS: + CocoaAsyncSocket: 065fd1e645c7abab64f7a6a2007a48038fdc6a99 + Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854 + flutter_local_notifications: 0c0b1ae97e741e1521e4c1629a459d04b9aec743 + flutter_timezone: ffb07bdad3c6276af8dada0f11978d8a1f8a20bb + geolocator_apple: cc556e6844d508c95df1e87e3ea6fa4e58c50401 + HTTPParserC: aea14c3d2d4ac5beb3988781daa36dfa62e0d9ef + patrol: 792c0bb6cc4d552fc8b37f49266341c39e659b4d + permission_handler_apple: e76247795d700c14ea09e3a2d8855d41ee80a2e6 + Telegraph: 12576b119324138e4929792af9e5a1085c2ecbc1 + webview_flutter_wkwebview: 2e2d318f21a5e036e2c3f26171342e95908bd60a + +PODFILE CHECKSUM: b2bb71756d032256bcb4043384dd40772d5e6a93 + +COCOAPODS: 1.14.3 diff --git a/dev/e2e_app/ios/Runner.xcodeproj/project.pbxproj b/dev/e2e_app/ios/Runner.xcodeproj/project.pbxproj new file mode 100644 index 000000000..de113a8ae --- /dev/null +++ b/dev/e2e_app/ios/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,976 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 54; + objects = { + +/* Begin PBXBuildFile section */ + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; + 6090F033F64EF2E6EC73E939 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B67A70BD9498C1A200C5D078 /* Pods_Runner.framework */; }; + 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 */; }; + 983964DC2978A956007EB76F /* RunnerUITests.m in Sources */ = {isa = PBXBuildFile; fileRef = 983964DB2978A956007EB76F /* RunnerUITests.m */; }; + 9862560529F9A72100B267FA /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9862560429F9A72100B267FA /* RunnerTests.swift */; }; + FA27315210C24EEDF8E3A8C2 /* Pods_Runner_RunnerUITests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 93E89E9CC733F51B93EF71E1 /* Pods_Runner_RunnerUITests.framework */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 983964DF2978A956007EB76F /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 97C146E61CF9000F007C117D /* Project object */; + proxyType = 1; + remoteGlobalIDString = 97C146ED1CF9000F007C117D; + remoteInfo = Runner; + }; + 9862560629F9A72100B267FA /* 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 */ + 039FF0702EF7414DA773B859 /* Pods-Runner-RunnerUITests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner-RunnerUITests.profile.xcconfig"; path = "Target Support Files/Pods-Runner-RunnerUITests/Pods-Runner-RunnerUITests.profile.xcconfig"; sourceTree = ""; }; + 0CD8ADEABA35D9D53F0DF923 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; + 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 = ""; }; + 2F26359F19FF5877E6D9BB4A /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; + 6AD63AC0BB42D464CC8ABFC5 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; + 714A2CF42B7519C44AFD56B9 /* Pods-Runner-RunnerUITests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner-RunnerUITests.debug.xcconfig"; path = "Target Support Files/Pods-Runner-RunnerUITests/Pods-Runner-RunnerUITests.debug.xcconfig"; 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 = ""; }; + 93E89E9CC733F51B93EF71E1 /* Pods_Runner_RunnerUITests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner_RunnerUITests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 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 = ""; }; + 983964D92978A956007EB76F /* RunnerUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 983964DB2978A956007EB76F /* RunnerUITests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RunnerUITests.m; sourceTree = ""; }; + 98575F2E29FA960A00AF8421 /* RunnerTests-Bridging-Header.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "RunnerTests-Bridging-Header.h"; sourceTree = ""; }; + 9862560229F9A72100B267FA /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 9862560429F9A72100B267FA /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = ""; }; + B447E7B3C41089DE3953018D /* Pods-Runner-RunnerUITests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner-RunnerUITests.release.xcconfig"; path = "Target Support Files/Pods-Runner-RunnerUITests/Pods-Runner-RunnerUITests.release.xcconfig"; sourceTree = ""; }; + B67A70BD9498C1A200C5D078 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 97C146EB1CF9000F007C117D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 6090F033F64EF2E6EC73E939 /* Pods_Runner.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 983964D62978A956007EB76F /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + FA27315210C24EEDF8E3A8C2 /* Pods_Runner_RunnerUITests.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 986255FF29F9A72100B267FA /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 71514460146D120DA8711EC5 /* Pods */ = { + isa = PBXGroup; + children = ( + 6AD63AC0BB42D464CC8ABFC5 /* Pods-Runner.debug.xcconfig */, + 0CD8ADEABA35D9D53F0DF923 /* Pods-Runner.release.xcconfig */, + 2F26359F19FF5877E6D9BB4A /* Pods-Runner.profile.xcconfig */, + 714A2CF42B7519C44AFD56B9 /* Pods-Runner-RunnerUITests.debug.xcconfig */, + B447E7B3C41089DE3953018D /* Pods-Runner-RunnerUITests.release.xcconfig */, + 039FF0702EF7414DA773B859 /* Pods-Runner-RunnerUITests.profile.xcconfig */, + ); + path = Pods; + 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 */, + 983964DA2978A956007EB76F /* RunnerUITests */, + 9862560329F9A72100B267FA /* RunnerTests */, + 97C146EF1CF9000F007C117D /* Products */, + 71514460146D120DA8711EC5 /* Pods */, + E54C552FCC7A91D75B1E4F09 /* Frameworks */, + ); + sourceTree = ""; + }; + 97C146EF1CF9000F007C117D /* Products */ = { + isa = PBXGroup; + children = ( + 97C146EE1CF9000F007C117D /* Runner.app */, + 983964D92978A956007EB76F /* RunnerUITests.xctest */, + 9862560229F9A72100B267FA /* RunnerTests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + 97C146F01CF9000F007C117D /* Runner */ = { + isa = PBXGroup; + children = ( + 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 = ""; + }; + 983964DA2978A956007EB76F /* RunnerUITests */ = { + isa = PBXGroup; + children = ( + 983964DB2978A956007EB76F /* RunnerUITests.m */, + ); + path = RunnerUITests; + sourceTree = ""; + }; + 9862560329F9A72100B267FA /* RunnerTests */ = { + isa = PBXGroup; + children = ( + 98575F2E29FA960A00AF8421 /* RunnerTests-Bridging-Header.h */, + 9862560429F9A72100B267FA /* RunnerTests.swift */, + ); + path = RunnerTests; + sourceTree = ""; + }; + E54C552FCC7A91D75B1E4F09 /* Frameworks */ = { + isa = PBXGroup; + children = ( + B67A70BD9498C1A200C5D078 /* Pods_Runner.framework */, + 93E89E9CC733F51B93EF71E1 /* Pods_Runner_RunnerUITests.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 97C146ED1CF9000F007C117D /* Runner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; + buildPhases = ( + 01FBF9092C877C4910CAC196 /* [CP] Check Pods Manifest.lock */, + 9740EEB61CF901F6004384FC /* xcode_backend build */, + 97C146EA1CF9000F007C117D /* Sources */, + 97C146EB1CF9000F007C117D /* Frameworks */, + 97C146EC1CF9000F007C117D /* Resources */, + 9705A1C41CF9048500538489 /* Embed Frameworks */, + 3B06AD1E1E4923F5004D2608 /* xcode_backend embed_and_thin */, + E621EC4C03882F1FC407353C /* [CP] Embed Pods Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Runner; + productName = Runner; + productReference = 97C146EE1CF9000F007C117D /* Runner.app */; + productType = "com.apple.product-type.application"; + }; + 983964D82978A956007EB76F /* RunnerUITests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 983964E12978A956007EB76F /* Build configuration list for PBXNativeTarget "RunnerUITests" */; + buildPhases = ( + CCBA4E2120CD0A4549A78A05 /* [CP] Check Pods Manifest.lock */, + 983964E62978A9F4007EB76F /* xcode_backend build */, + 983964D52978A956007EB76F /* Sources */, + 983964D62978A956007EB76F /* Frameworks */, + 983964D72978A956007EB76F /* Resources */, + 983964E52978A9D4007EB76F /* xcode_backend embed_and_thin */, + FB0F1ED3C61A5044791AC712 /* [CP] Embed Pods Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 983964E02978A956007EB76F /* PBXTargetDependency */, + ); + name = RunnerUITests; + productName = RunnerUITests; + productReference = 983964D92978A956007EB76F /* RunnerUITests.xctest */; + productType = "com.apple.product-type.bundle.ui-testing"; + }; + 9862560129F9A72100B267FA /* RunnerTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 9862560B29F9A72100B267FA /* Build configuration list for PBXNativeTarget "RunnerTests" */; + buildPhases = ( + 986255FE29F9A72100B267FA /* Sources */, + 986255FF29F9A72100B267FA /* Frameworks */, + 9862560029F9A72100B267FA /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 9862560729F9A72100B267FA /* PBXTargetDependency */, + ); + name = RunnerTests; + productName = RunnerTests; + productReference = 9862560229F9A72100B267FA /* RunnerTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 97C146E61CF9000F007C117D /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 1430; + LastUpgradeCheck = 1430; + ORGANIZATIONNAME = ""; + TargetAttributes = { + 97C146ED1CF9000F007C117D = { + CreatedOnToolsVersion = 7.3.1; + LastSwiftMigration = 1100; + }; + 983964D82978A956007EB76F = { + CreatedOnToolsVersion = 14.2; + TestTargetID = 97C146ED1CF9000F007C117D; + }; + 9862560129F9A72100B267FA = { + CreatedOnToolsVersion = 14.3; + LastSwiftMigration = 1430; + TestTargetID = 97C146ED1CF9000F007C117D; + }; + }; + }; + 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 */, + 983964D82978A956007EB76F /* RunnerUITests */, + 9862560129F9A72100B267FA /* RunnerTests */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 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; + }; + 983964D72978A956007EB76F /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 9862560029F9A72100B267FA /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 01FBF9092C877C4910CAC196 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + 3B06AD1E1E4923F5004D2608 /* xcode_backend embed_and_thin */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "xcode_backend embed_and_thin"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "echo \"Runner xcode_backend embed_and_thin\"\n/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin\n"; + }; + 9740EEB61CF901F6004384FC /* xcode_backend build */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "xcode_backend build"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "echo \"Runner xcode_backend build\"\n/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build\n"; + }; + 983964E52978A9D4007EB76F /* xcode_backend embed_and_thin */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + ); + name = "xcode_backend embed_and_thin"; + outputFileListPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "echo \"RunnerUITests xcode_backend embed_and_thin\"\n/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin\n"; + }; + 983964E62978A9F4007EB76F /* xcode_backend build */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + ); + name = "xcode_backend build"; + outputFileListPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "echo \"RunnerUITests xcode_backend build\"\n/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build\n"; + }; + CCBA4E2120CD0A4549A78A05 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-Runner-RunnerUITests-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + E621EC4C03882F1FC407353C /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + FB0F1ED3C61A5044791AC712 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner-RunnerUITests/Pods-Runner-RunnerUITests-frameworks-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner-RunnerUITests/Pods-Runner-RunnerUITests-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner-RunnerUITests/Pods-Runner-RunnerUITests-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 97C146EA1CF9000F007C117D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 983964D52978A956007EB76F /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 983964DC2978A956007EB76F /* RunnerUITests.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 986255FE29F9A72100B267FA /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 9862560529F9A72100B267FA /* RunnerTests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 983964E02978A956007EB76F /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 97C146ED1CF9000F007C117D /* Runner */; + targetProxy = 983964DF2978A956007EB76F /* PBXContainerItemProxy */; + }; + 9862560729F9A72100B267FA /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 97C146ED1CF9000F007C117D /* Runner */; + targetProxy = 9862560629F9A72100B267FA /* 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; + 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; + 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 = 11.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; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = U3EG6EALX7; + ENABLE_BITCODE = NO; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = pl.leancode.patrol.Example; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Profile; + }; + 97C147031CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + 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; + 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 = 11.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; + 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; + 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 = 11.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; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = U3EG6EALX7; + ENABLE_BITCODE = NO; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = pl.leancode.patrol.Example; + PRODUCT_NAME = "$(TARGET_NAME)"; + 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; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = U3EG6EALX7; + ENABLE_BITCODE = NO; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = pl.leancode.patrol.Example; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Release; + }; + 983964E22978A956007EB76F /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = U3EG6EALX7; + GCC_C_LANGUAGE_STANDARD = gnu11; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = pl.leancode.patrol.Example.RunnerUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = NO; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = Runner; + }; + name = Debug; + }; + 983964E32978A956007EB76F /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = U3EG6EALX7; + GCC_C_LANGUAGE_STANDARD = gnu11; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = pl.leancode.patrol.Example.RunnerUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = NO; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = Runner; + }; + name = Release; + }; + 983964E42978A956007EB76F /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = U3EG6EALX7; + GCC_C_LANGUAGE_STANDARD = gnu11; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = pl.leancode.patrol.Example.RunnerUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = NO; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = Runner; + }; + name = Profile; + }; + 9862560829F9A72100B267FA /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = U3EG6EALX7; + GCC_C_LANGUAGE_STANDARD = gnu11; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = pl.leancode.patrol.Example.RunnerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_OBJC_BRIDGING_HEADER = "RunnerTests/RunnerTests-Bridging-Header.h"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; + }; + name = Debug; + }; + 9862560929F9A72100B267FA /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = U3EG6EALX7; + GCC_C_LANGUAGE_STANDARD = gnu11; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = pl.leancode.patrol.Example.RunnerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_OBJC_BRIDGING_HEADER = "RunnerTests/RunnerTests-Bridging-Header.h"; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; + }; + name = Release; + }; + 9862560A29F9A72100B267FA /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = U3EG6EALX7; + GCC_C_LANGUAGE_STANDARD = gnu11; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = pl.leancode.patrol.Example.RunnerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_OBJC_BRIDGING_HEADER = "RunnerTests/RunnerTests-Bridging-Header.h"; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; + }; + name = Profile; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97C147031CF9000F007C117D /* Debug */, + 97C147041CF9000F007C117D /* Release */, + 249021D3217E4FDB00AE95B9 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Debug; + }; + 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97C147061CF9000F007C117D /* Debug */, + 97C147071CF9000F007C117D /* Release */, + 249021D4217E4FDB00AE95B9 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Debug; + }; + 983964E12978A956007EB76F /* Build configuration list for PBXNativeTarget "RunnerUITests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 983964E22978A956007EB76F /* Debug */, + 983964E32978A956007EB76F /* Release */, + 983964E42978A956007EB76F /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Debug; + }; + 9862560B29F9A72100B267FA /* Build configuration list for PBXNativeTarget "RunnerTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 9862560829F9A72100B267FA /* Debug */, + 9862560929F9A72100B267FA /* Release */, + 9862560A29F9A72100B267FA /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Debug; + }; +/* End XCConfigurationList section */ + }; + rootObject = 97C146E61CF9000F007C117D /* Project object */; +} diff --git a/dev/e2e_app/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/dev/e2e_app/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 000000000..919434a62 --- /dev/null +++ b/dev/e2e_app/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/dev/e2e_app/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/dev/e2e_app/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 000000000..18d981003 --- /dev/null +++ b/dev/e2e_app/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/dev/e2e_app/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/dev/e2e_app/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 000000000..f9b0d7c5e --- /dev/null +++ b/dev/e2e_app/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + PreviewsEnabled + + + diff --git a/dev/e2e_app/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/dev/e2e_app/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme new file mode 100644 index 000000000..05552f28c --- /dev/null +++ b/dev/e2e_app/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -0,0 +1,107 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dev/e2e_app/ios/Runner.xcworkspace/contents.xcworkspacedata b/dev/e2e_app/ios/Runner.xcworkspace/contents.xcworkspacedata new file mode 100644 index 000000000..21a3cc14c --- /dev/null +++ b/dev/e2e_app/ios/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/dev/e2e_app/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/dev/e2e_app/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 000000000..18d981003 --- /dev/null +++ b/dev/e2e_app/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/dev/e2e_app/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/dev/e2e_app/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 000000000..f9b0d7c5e --- /dev/null +++ b/dev/e2e_app/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + PreviewsEnabled + + + diff --git a/dev/e2e_app/ios/Runner/AppDelegate.swift b/dev/e2e_app/ios/Runner/AppDelegate.swift new file mode 100644 index 000000000..f778914dd --- /dev/null +++ b/dev/e2e_app/ios/Runner/AppDelegate.swift @@ -0,0 +1,14 @@ +import Flutter +import UIKit + +@UIApplicationMain +@objc class AppDelegate: FlutterAppDelegate { + override func application( + _ application: UIApplication, + didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? + ) -> Bool { + GeneratedPluginRegistrant.register(with: self) + UNUserNotificationCenter.current().delegate = self as UNUserNotificationCenterDelegate + return super.application(application, didFinishLaunchingWithOptions: launchOptions) + } +} diff --git a/dev/e2e_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/dev/e2e_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 000000000..d36b1fab2 --- /dev/null +++ b/dev/e2e_app/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/dev/e2e_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/dev/e2e_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png new file mode 100644 index 000000000..dc9ada472 Binary files /dev/null and b/dev/e2e_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png differ diff --git a/dev/e2e_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/dev/e2e_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png new file mode 100644 index 000000000..28c6bf030 Binary files /dev/null and b/dev/e2e_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png differ diff --git a/dev/e2e_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/dev/e2e_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png new file mode 100644 index 000000000..2ccbfd967 Binary files /dev/null and b/dev/e2e_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png differ diff --git a/dev/e2e_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/dev/e2e_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png new file mode 100644 index 000000000..f091b6b0b Binary files /dev/null and b/dev/e2e_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png differ diff --git a/dev/e2e_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/dev/e2e_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png new file mode 100644 index 000000000..4cde12118 Binary files /dev/null and b/dev/e2e_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png differ diff --git a/dev/e2e_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/dev/e2e_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png new file mode 100644 index 000000000..d0ef06e7e Binary files /dev/null and b/dev/e2e_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png differ diff --git a/dev/e2e_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/dev/e2e_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png new file mode 100644 index 000000000..dcdc2306c Binary files /dev/null and b/dev/e2e_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png differ diff --git a/dev/e2e_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/dev/e2e_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png new file mode 100644 index 000000000..2ccbfd967 Binary files /dev/null and b/dev/e2e_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png differ diff --git a/dev/e2e_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/dev/e2e_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png new file mode 100644 index 000000000..c8f9ed8f5 Binary files /dev/null and b/dev/e2e_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png differ diff --git a/dev/e2e_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/dev/e2e_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png new file mode 100644 index 000000000..a6d6b8609 Binary files /dev/null and b/dev/e2e_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png differ diff --git a/dev/e2e_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/dev/e2e_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png new file mode 100644 index 000000000..a6d6b8609 Binary files /dev/null and b/dev/e2e_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png differ diff --git a/dev/e2e_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/dev/e2e_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png new file mode 100644 index 000000000..75b2d164a Binary files /dev/null and b/dev/e2e_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png differ diff --git a/dev/e2e_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/dev/e2e_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png new file mode 100644 index 000000000..c4df70d39 Binary files /dev/null and b/dev/e2e_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png differ diff --git a/dev/e2e_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/dev/e2e_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png new file mode 100644 index 000000000..6a84f41e1 Binary files /dev/null and b/dev/e2e_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png differ diff --git a/dev/e2e_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/dev/e2e_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png new file mode 100644 index 000000000..d0e1f5853 Binary files /dev/null and b/dev/e2e_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png differ diff --git a/dev/e2e_app/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json b/dev/e2e_app/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json new file mode 100644 index 000000000..0bedcf2fd --- /dev/null +++ b/dev/e2e_app/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/dev/e2e_app/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png b/dev/e2e_app/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png new file mode 100644 index 000000000..9da19eaca Binary files /dev/null and b/dev/e2e_app/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png differ diff --git a/dev/e2e_app/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/dev/e2e_app/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png new file mode 100644 index 000000000..9da19eaca Binary files /dev/null and b/dev/e2e_app/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png differ diff --git a/dev/e2e_app/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/dev/e2e_app/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png new file mode 100644 index 000000000..9da19eaca Binary files /dev/null and b/dev/e2e_app/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png differ diff --git a/dev/e2e_app/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/dev/e2e_app/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md new file mode 100644 index 000000000..89c2725b7 --- /dev/null +++ b/dev/e2e_app/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/dev/e2e_app/ios/Runner/Base.lproj/LaunchScreen.storyboard b/dev/e2e_app/ios/Runner/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 000000000..f2e259c7c --- /dev/null +++ b/dev/e2e_app/ios/Runner/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dev/e2e_app/ios/Runner/Base.lproj/Main.storyboard b/dev/e2e_app/ios/Runner/Base.lproj/Main.storyboard new file mode 100644 index 000000000..f3c28516f --- /dev/null +++ b/dev/e2e_app/ios/Runner/Base.lproj/Main.storyboard @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dev/e2e_app/ios/Runner/Info.plist b/dev/e2e_app/ios/Runner/Info.plist new file mode 100644 index 000000000..24a67c646 --- /dev/null +++ b/dev/e2e_app/ios/Runner/Info.plist @@ -0,0 +1,69 @@ + + + + + NSBonjourServices + + _dartobservatory._tcp + + CADisableMinimumFrameDurationOnPhone + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleDisplayName + Example + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + example + CFBundlePackageType + APPL + CFBundleShortVersionString + $(FLUTTER_BUILD_NAME) + CFBundleSignature + ???? + CFBundleVersion + $(FLUTTER_BUILD_NUMBER) + LSRequiresIPhoneOS + + NSCameraUsageDescription + camera + NSContactsUsageDescription + contacts + NSLocationAlwaysAndWhenInUseUsageDescription + Always and when in use! + NSLocationAlwaysUsageDescription + Can I have location always? + NSLocationUsageDescription + Older devices need location. + NSLocationWhenInUseUsageDescription + Need location when in use + NSMicrophoneUsageDescription + microphone + UIApplicationSupportsIndirectInputEvents + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UIViewControllerBasedStatusBarAppearance + + + diff --git a/dev/e2e_app/ios/Runner/Runner-Bridging-Header.h b/dev/e2e_app/ios/Runner/Runner-Bridging-Header.h new file mode 100644 index 000000000..308a2a560 --- /dev/null +++ b/dev/e2e_app/ios/Runner/Runner-Bridging-Header.h @@ -0,0 +1 @@ +#import "GeneratedPluginRegistrant.h" diff --git a/packages/patrol/example/ios/RunnerTests/RunnerTests-Bridging-Header.h b/dev/e2e_app/ios/RunnerTests/RunnerTests-Bridging-Header.h similarity index 100% rename from packages/patrol/example/ios/RunnerTests/RunnerTests-Bridging-Header.h rename to dev/e2e_app/ios/RunnerTests/RunnerTests-Bridging-Header.h diff --git a/packages/patrol/example/ios/RunnerTests/RunnerTests.swift b/dev/e2e_app/ios/RunnerTests/RunnerTests.swift similarity index 100% rename from packages/patrol/example/ios/RunnerTests/RunnerTests.swift rename to dev/e2e_app/ios/RunnerTests/RunnerTests.swift diff --git a/dev/e2e_app/ios/RunnerUITests/RunnerUITests.m b/dev/e2e_app/ios/RunnerUITests/RunnerUITests.m new file mode 100644 index 000000000..bfc5dbda2 --- /dev/null +++ b/dev/e2e_app/ios/RunnerUITests/RunnerUITests.m @@ -0,0 +1,5 @@ +@import XCTest; +@import patrol; +@import ObjectiveC.runtime; + +PATROL_INTEGRATION_TEST_IOS_RUNNER(RunnerUITests) diff --git a/packages/patrol/example/ios/fastlane/Appfile b/dev/e2e_app/ios/fastlane/Appfile similarity index 100% rename from packages/patrol/example/ios/fastlane/Appfile rename to dev/e2e_app/ios/fastlane/Appfile diff --git a/packages/patrol/example/ios/fastlane/Fastfile b/dev/e2e_app/ios/fastlane/Fastfile similarity index 100% rename from packages/patrol/example/ios/fastlane/Fastfile rename to dev/e2e_app/ios/fastlane/Fastfile diff --git a/packages/patrol/example/lib/keys.dart b/dev/e2e_app/lib/keys.dart similarity index 100% rename from packages/patrol/example/lib/keys.dart rename to dev/e2e_app/lib/keys.dart diff --git a/packages/patrol/example/lib/loading_screen.dart b/dev/e2e_app/lib/loading_screen.dart similarity index 100% rename from packages/patrol/example/lib/loading_screen.dart rename to dev/e2e_app/lib/loading_screen.dart diff --git a/packages/patrol/example/lib/location_screen.dart b/dev/e2e_app/lib/location_screen.dart similarity index 100% rename from packages/patrol/example/lib/location_screen.dart rename to dev/e2e_app/lib/location_screen.dart diff --git a/dev/e2e_app/lib/main.dart b/dev/e2e_app/lib/main.dart new file mode 100644 index 000000000..363aefb64 --- /dev/null +++ b/dev/e2e_app/lib/main.dart @@ -0,0 +1,250 @@ +import 'package:e2e_app/loading_screen.dart'; +import 'package:e2e_app/location_screen.dart'; +import 'package:e2e_app/notifications_screen.dart'; +import 'package:e2e_app/overlay_screen.dart'; +import 'package:e2e_app/permissions_screen.dart'; +import 'package:e2e_app/scrolling_screen.dart'; +import 'package:e2e_app/webview_screen.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_timezone/flutter_timezone.dart'; +import 'package:timezone/data/latest.dart' as tz_data; +import 'package:timezone/timezone.dart' as tz; + +Future main() async { + WidgetsFlutterBinding.ensureInitialized(); + await setUpTimezone(); + + runApp(const ExampleApp()); +} + +Future setUpTimezone() async { + tz_data.initializeTimeZones(); + final timezone = await FlutterTimezone.getLocalTimezone(); + final location = tz.getLocation(timezone); + tz.setLocalLocation(location); +} + +class ExampleApp extends StatelessWidget { + const ExampleApp({super.key}); + + @override + Widget build(BuildContext context) { + return MaterialApp( + title: 'Flutter Demo', + darkTheme: ThemeData( + primarySwatch: Colors.blue, + brightness: Brightness.dark, + ), + theme: ThemeData( + primarySwatch: Colors.blue, + brightness: Brightness.light, + ), + home: const ExampleHomePage(title: 'Flutter Demo Home Page'), + ); + } +} + +class ExampleHomePage extends StatefulWidget { + const ExampleHomePage({super.key, required this.title}); + + final String title; + + @override + State createState() => _ExampleHomePageState(); +} + +class _ExampleHomePageState extends State { + var _counter = 0; + + void _incrementCounter([int value = 1]) { + final newValue = _counter + value; + setState(() { + _counter = newValue; + }); + } + + void _decrementCounter([int value = 1]) { + final newValue = _counter - value; + setState(() { + _counter = newValue; + }); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + key: const Key('scaffold'), + appBar: AppBar( + title: Text(widget.title), + ), + body: ListView( + padding: EdgeInsets.all(8), + key: const Key('listViewKey'), + children: [ + const Text( + 'You have pushed the button this many times:', + ), + Text( + '$_counter', + key: const Key('counterText'), + style: Theme.of(context).textTheme.headlineMedium, + ), + const TextField( + key: Key('textField'), + decoration: InputDecoration( + border: OutlineInputBorder(), + hintText: 'You have entered this text', + ), + ), + SizedBox(height: 8), + Container( + key: const Key('box1'), + color: Theme.of(context).colorScheme.background, + padding: const EdgeInsets.all(8), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const Text('box 1'), + ListTile( + onTap: () => _incrementCounter(10), + key: const Key('tile1'), + title: const Text('Add'), + trailing: IconButton( + icon: const Icon(Icons.add, key: Key('icon1')), + onPressed: _incrementCounter, + ), + ), + ListTile( + onTap: () => _decrementCounter(10), + key: const Key('tile2'), + title: const Text('Subtract'), + trailing: IconButton( + icon: const Icon(Icons.remove, key: Key('icon2')), + onPressed: _decrementCounter, + ), + ), + ], + ), + ), + const SizedBox(height: 16), + Container( + key: const Key('box2'), + color: Theme.of(context).colorScheme.background, + padding: const EdgeInsets.all(8), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const Text('box 2'), + ListTile( + onTap: () => _incrementCounter(10), + key: const Key('tile1'), + title: const Text('Add'), + trailing: IconButton( + icon: const Icon(Icons.add, key: Key('icon1')), + onPressed: _incrementCounter, + ), + ), + ListTile( + onTap: () => _decrementCounter(10), + key: const Key('tile2'), + title: const Text('Subtract'), + trailing: IconButton( + icon: const Icon(Icons.remove, key: Key('icon2')), + onPressed: _decrementCounter, + ), + ), + ], + ), + ), + TextButton( + onPressed: () async => Navigator.of(context).push( + MaterialPageRoute( + builder: (_) => const LoadingScreen(), + ), + ), + child: const Text('Open loading screen'), + ), + TextButton( + onPressed: () async => Navigator.of(context).push( + MaterialPageRoute( + builder: (_) => const LocationScreen(), + ), + ), + child: const Text('Open location screen'), + ), + TextButton( + onPressed: () async => Navigator.of(context).push( + MaterialPageRoute( + builder: (_) => const NotificationsScreen(), + ), + ), + child: const Text('Open notifications screen'), + ), + TextButton( + onPressed: () async => Navigator.of(context).push( + MaterialPageRoute( + builder: (_) => const OverlayScreen(), + ), + ), + child: const Text('Open overlay screen'), + ), + TextButton( + onPressed: () async => Navigator.of(context).push( + MaterialPageRoute( + builder: (_) => const ScrollingScreen(), + ), + ), + child: const Text('Open scrolling screen'), + ), + TextButton( + onPressed: () async => Navigator.of(context).push( + MaterialPageRoute( + builder: (_) => const WebViewScreen( + title: 'WebView (LeanCode)', + url: 'https://leancode.co', + ), + ), + ), + child: const Text('Open webview (LeanCode)'), + ), + TextButton( + onPressed: () async => Navigator.of(context).push( + MaterialPageRoute( + builder: (_) => const WebViewScreen( + title: 'WebView (Hacker News)', + url: 'https://news.ycombinator.com', + ), + ), + ), + child: const Text('Open webview (Hacker News)'), + ), + TextButton( + onPressed: () async => Navigator.of(context).push( + MaterialPageRoute( + builder: (_) => const WebViewScreen( + title: 'WebView (StackOverflow)', + url: 'https://stackoverflow.com', + ), + ), + ), + child: const Text('Open webview (StackOverflow)'), + ), + TextButton( + onPressed: () async => Navigator.of(context).push( + MaterialPageRoute( + builder: (_) => const PermissionsScreen(), + ), + ), + child: const Text('Open permissions screen'), + ), + Text('EXAMPLE_KEY: ${const String.fromEnvironment('EXAMPLE_KEY')}'), + ], + ), + floatingActionButton: FloatingActionButton( + onPressed: _incrementCounter, + tooltip: 'Increment', + child: const Icon(Icons.add), + ), + ); + } +} diff --git a/packages/patrol/example/lib/notifications_screen.dart b/dev/e2e_app/lib/notifications_screen.dart similarity index 100% rename from packages/patrol/example/lib/notifications_screen.dart rename to dev/e2e_app/lib/notifications_screen.dart diff --git a/packages/patrol/example/lib/overlay_screen.dart b/dev/e2e_app/lib/overlay_screen.dart similarity index 100% rename from packages/patrol/example/lib/overlay_screen.dart rename to dev/e2e_app/lib/overlay_screen.dart diff --git a/packages/patrol/example/lib/permissions_screen.dart b/dev/e2e_app/lib/permissions_screen.dart similarity index 100% rename from packages/patrol/example/lib/permissions_screen.dart rename to dev/e2e_app/lib/permissions_screen.dart diff --git a/packages/patrol/example/lib/scrolling_screen.dart b/dev/e2e_app/lib/scrolling_screen.dart similarity index 95% rename from packages/patrol/example/lib/scrolling_screen.dart rename to dev/e2e_app/lib/scrolling_screen.dart index 9989d206e..49849d772 100644 --- a/packages/patrol/example/lib/scrolling_screen.dart +++ b/dev/e2e_app/lib/scrolling_screen.dart @@ -1,5 +1,5 @@ +import 'package:e2e_app/keys.dart'; import 'package:flutter/material.dart'; -import 'package:patrol_example/keys.dart'; class ScrollingScreen extends StatelessWidget { const ScrollingScreen({super.key}); diff --git a/packages/patrol/example/lib/webview_screen.dart b/dev/e2e_app/lib/webview_screen.dart similarity index 100% rename from packages/patrol/example/lib/webview_screen.dart rename to dev/e2e_app/lib/webview_screen.dart diff --git a/dev/e2e_app/pubspec.lock b/dev/e2e_app/pubspec.lock new file mode 100644 index 000000000..1ad8eeeb6 --- /dev/null +++ b/dev/e2e_app/pubspec.lock @@ -0,0 +1,689 @@ +# Generated by pub +# See https://dart.dev/tools/pub/glossary#lockfile +packages: + _fe_analyzer_shared: + dependency: transitive + description: + name: _fe_analyzer_shared + sha256: eb376e9acf6938204f90eb3b1f00b578640d3188b4c8a8ec054f9f479af8d051 + url: "https://pub.dev" + source: hosted + version: "64.0.0" + analyzer: + dependency: transitive + description: + name: analyzer + sha256: "69f54f967773f6c26c7dcb13e93d7ccee8b17a641689da39e878d5cf13b06893" + url: "https://pub.dev" + source: hosted + version: "6.2.0" + analyzer_plugin: + dependency: transitive + description: + name: analyzer_plugin + sha256: "9661b30b13a685efaee9f02e5d01ed9f2b423bd889d28a304d02d704aee69161" + url: "https://pub.dev" + source: hosted + version: "0.11.3" + args: + dependency: transitive + description: + name: args + sha256: eef6c46b622e0494a36c5a12d10d77fb4e855501a91c1b9ef9339326e58f0596 + url: "https://pub.dev" + source: hosted + version: "2.4.2" + 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" + checked_yaml: + dependency: transitive + description: + name: checked_yaml + sha256: feb6bed21949061731a7a75fc5d2aa727cf160b91af9a3e464c5e3a32e28b5ff + url: "https://pub.dev" + source: hosted + version: "2.0.3" + ci: + dependency: transitive + description: + name: ci + sha256: "145d095ce05cddac4d797a158bc4cf3b6016d1fe63d8c3d2fbd7212590adca13" + url: "https://pub.dev" + source: hosted + version: "0.1.0" + cli_util: + dependency: transitive + description: + name: cli_util + sha256: b8db3080e59b2503ca9e7922c3df2072cf13992354d5e944074ffa836fba43b7 + url: "https://pub.dev" + source: hosted + version: "0.4.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: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a + url: "https://pub.dev" + source: hosted + version: "1.18.0" + convert: + dependency: transitive + description: + name: convert + sha256: "0f08b14755d163f6e2134cb58222dd25ea2a2ee8a195e53983d57c075324d592" + url: "https://pub.dev" + source: hosted + version: "3.1.1" + crypto: + dependency: transitive + description: + name: crypto + sha256: ff625774173754681d66daaf4a448684fb04b78f902da9cb3d308c19cc5e8bab + url: "https://pub.dev" + source: hosted + version: "3.0.3" + cupertino_icons: + dependency: "direct main" + description: + name: cupertino_icons + sha256: d57953e10f9f8327ce64a508a355f0b1ec902193f66288e8cb5070e7c47eeb2d + url: "https://pub.dev" + source: hosted + version: "1.0.6" + custom_lint: + dependency: transitive + description: + name: custom_lint + sha256: "198ec6b8e084d22f508a76556c9afcfb71706ad3f42b083fe0ee923351a96d90" + url: "https://pub.dev" + source: hosted + version: "0.5.7" + custom_lint_builder: + dependency: transitive + description: + name: custom_lint_builder + sha256: dfcfa987d2bd9d0ba751ef4bdef0f6c1aa0062f2a67fe716fd5f3f8b709d6418 + url: "https://pub.dev" + source: hosted + version: "0.5.7" + custom_lint_core: + dependency: transitive + description: + name: custom_lint_core + sha256: f84c3fe2f27ef3b8831953e477e59d4a29c2952623f9eac450d7b40d9cdd94cc + url: "https://pub.dev" + source: hosted + version: "0.5.7" + dart_style: + dependency: transitive + description: + name: dart_style + sha256: "40ae61a5d43feea6d24bd22c0537a6629db858963b99b4bc1c3db80676f32368" + url: "https://pub.dev" + source: hosted + version: "2.3.4" + dbus: + dependency: transitive + description: + name: dbus + sha256: "365c771ac3b0e58845f39ec6deebc76e3276aa9922b0cc60840712094d9047ac" + url: "https://pub.dev" + source: hosted + version: "0.7.10" + equatable: + dependency: transitive + description: + name: equatable + sha256: c2b87cb7756efdf69892005af546c56c0b5037f54d2a88269b4f347a505e3ca2 + url: "https://pub.dev" + source: hosted + version: "2.0.5" + fake_async: + dependency: transitive + description: + name: fake_async + sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" + url: "https://pub.dev" + source: hosted + version: "1.3.1" + ffi: + dependency: transitive + description: + name: ffi + sha256: "7bf0adc28a23d395f19f3f1eb21dd7cfd1dd9f8e1c50051c069122e6853bc878" + url: "https://pub.dev" + source: hosted + version: "2.1.0" + 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_local_notifications: + dependency: "direct main" + description: + name: flutter_local_notifications + sha256: "6d11ea777496061e583623aaf31923f93a9409ef8fcaeeefdd6cd78bf4fe5bb3" + url: "https://pub.dev" + source: hosted + version: "16.1.0" + flutter_local_notifications_linux: + dependency: transitive + description: + name: flutter_local_notifications_linux + sha256: "33f741ef47b5f63cc7f78fe75eeeac7e19f171ff3c3df054d84c1e38bedb6a03" + url: "https://pub.dev" + source: hosted + version: "4.0.0+1" + flutter_local_notifications_platform_interface: + dependency: transitive + description: + name: flutter_local_notifications_platform_interface + sha256: "7cf643d6d5022f3baed0be777b0662cce5919c0a7b86e700299f22dc4ae660ef" + url: "https://pub.dev" + source: hosted + version: "7.0.0+1" + flutter_test: + dependency: "direct dev" + description: flutter + source: sdk + version: "0.0.0" + flutter_timezone: + dependency: "direct main" + description: + name: flutter_timezone + sha256: "06b35132c98fa188db3c4b654b7e1af7ccd01dfe12a004d58be423357605fb24" + url: "https://pub.dev" + source: hosted + version: "1.0.8" + flutter_web_plugins: + dependency: transitive + description: flutter + source: sdk + version: "0.0.0" + freezed_annotation: + dependency: transitive + description: + name: freezed_annotation + sha256: c3fd9336eb55a38cc1bbd79ab17573113a8deccd0ecbbf926cca3c62803b5c2d + url: "https://pub.dev" + source: hosted + version: "2.4.1" + geolocator: + dependency: "direct main" + description: + name: geolocator + sha256: e946395fc608842bb2f6c914807e9183f86f3cb787f6b8f832753e5251036f02 + url: "https://pub.dev" + source: hosted + version: "10.1.0" + geolocator_android: + dependency: transitive + description: + name: geolocator_android + sha256: "741579fa6c9e412984d2bdb2fbaa54e3c3f7587c60aeacfe6e058358a11f40f8" + url: "https://pub.dev" + source: hosted + version: "4.4.0" + geolocator_apple: + dependency: transitive + description: + name: geolocator_apple + sha256: ab90ae811c42ec2f6021e01eca71df00dee6ff1e69d2c2dafd4daeb0b793f73d + url: "https://pub.dev" + source: hosted + version: "2.3.2" + geolocator_platform_interface: + dependency: transitive + description: + name: geolocator_platform_interface + sha256: "6c8d494d6948757c56720b778af742f6973f31fca1f702a7539b8917e4a2468a" + url: "https://pub.dev" + source: hosted + version: "4.2.0" + geolocator_web: + dependency: transitive + description: + name: geolocator_web + sha256: "59083f7e0871b78299918d92bf930a14377f711d2d1156c558cd5ebae6c20d58" + url: "https://pub.dev" + source: hosted + version: "2.2.0" + geolocator_windows: + dependency: transitive + description: + name: geolocator_windows + sha256: a92fae29779d5c6dc60e8411302f5221ade464968fe80a36d330e80a71f087af + url: "https://pub.dev" + source: hosted + version: "0.2.2" + glob: + dependency: transitive + description: + name: glob + sha256: "0e7014b3b7d4dac1ca4d6114f82bf1782ee86745b9b42a92c9289c23d8a0ab63" + url: "https://pub.dev" + source: hosted + version: "2.1.2" + hotreloader: + dependency: transitive + description: + name: hotreloader + sha256: "94ee21a60ea2836500799f3af035dc3212b1562027f1e0031c14e087f0231449" + url: "https://pub.dev" + source: hosted + version: "4.1.0" + http: + dependency: transitive + description: + name: http + sha256: "759d1a329847dd0f39226c688d3e06a6b8679668e350e2891a6474f8b4bb8525" + url: "https://pub.dev" + source: hosted + version: "1.1.0" + http_parser: + dependency: transitive + description: + name: http_parser + sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b" + url: "https://pub.dev" + source: hosted + version: "4.0.2" + js: + dependency: transitive + description: + name: js + sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3 + url: "https://pub.dev" + source: hosted + version: "0.6.7" + json_annotation: + dependency: transitive + description: + name: json_annotation + sha256: b10a7b2ff83d83c777edba3c6a0f97045ddadd56c944e1a23a3fdf43a1bf4467 + url: "https://pub.dev" + source: hosted + version: "4.8.1" + leancode_lint: + dependency: "direct dev" + description: + name: leancode_lint + sha256: "1e99cba16e084a18ce966a7df270d6da6a11ab236caac716aa1fb2359eb277eb" + url: "https://pub.dev" + source: hosted + version: "7.0.0+1" + logging: + dependency: transitive + description: + name: logging + sha256: "623a88c9594aa774443aa3eb2d41807a48486b5613e67599fb4c41c0ad47c340" + url: "https://pub.dev" + source: hosted + version: "1.2.0" + matcher: + dependency: transitive + description: + name: matcher + sha256: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e" + url: "https://pub.dev" + source: hosted + version: "0.12.16" + material_color_utilities: + dependency: transitive + description: + name: material_color_utilities + sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41" + url: "https://pub.dev" + source: hosted + version: "0.5.0" + meta: + dependency: transitive + description: + name: meta + sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e + url: "https://pub.dev" + source: hosted + version: "1.10.0" + package_config: + dependency: transitive + description: + name: package_config + sha256: "1c5b77ccc91e4823a5af61ee74e6b972db1ef98c2ff5a18d3161c982a55448bd" + url: "https://pub.dev" + source: hosted + version: "2.1.0" + path: + dependency: transitive + description: + name: path + sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917" + url: "https://pub.dev" + source: hosted + version: "1.8.3" + patrol: + dependency: "direct dev" + description: + path: "../../packages/patrol" + relative: true + source: path + version: "3.0.3" + patrol_finders: + dependency: transitive + description: + name: patrol_finders + sha256: "909a5c28ba1730e5e1e06e06ec78f4ccc49f7e211f3a0919adac552841df19ee" + url: "https://pub.dev" + source: hosted + version: "2.0.1+1" + permission_handler: + dependency: "direct main" + description: + name: permission_handler + sha256: bc56bfe9d3f44c3c612d8d393bd9b174eb796d706759f9b495ac254e4294baa5 + url: "https://pub.dev" + source: hosted + version: "10.4.5" + permission_handler_android: + dependency: transitive + description: + name: permission_handler_android + sha256: "59c6322171c29df93a22d150ad95f3aa19ed86542eaec409ab2691b8f35f9a47" + url: "https://pub.dev" + source: hosted + version: "10.3.6" + permission_handler_apple: + dependency: transitive + description: + name: permission_handler_apple + sha256: "99e220bce3f8877c78e4ace901082fb29fa1b4ebde529ad0932d8d664b34f3f5" + url: "https://pub.dev" + source: hosted + version: "9.1.4" + permission_handler_platform_interface: + dependency: transitive + description: + name: permission_handler_platform_interface + sha256: "6760eb5ef34589224771010805bea6054ad28453906936f843a8cc4d3a55c4a4" + url: "https://pub.dev" + source: hosted + version: "3.12.0" + permission_handler_windows: + dependency: transitive + description: + name: permission_handler_windows + sha256: cc074aace208760f1eee6aa4fae766b45d947df85bc831cde77009cdb4720098 + url: "https://pub.dev" + source: hosted + version: "0.1.3" + petitparser: + dependency: transitive + description: + name: petitparser + sha256: eeb2d1428ee7f4170e2bd498827296a18d4e7fc462b71727d111c0ac7707cfa6 + url: "https://pub.dev" + source: hosted + version: "6.0.1" + plugin_platform_interface: + dependency: transitive + description: + name: plugin_platform_interface + sha256: f4f88d4a900933e7267e2b353594774fc0d07fb072b47eedcd5b54e1ea3269f8 + url: "https://pub.dev" + source: hosted + version: "2.1.7" + pub_semver: + dependency: transitive + description: + name: pub_semver + sha256: "40d3ab1bbd474c4c2328c91e3a7df8c6dd629b79ece4c4bd04bee496a224fb0c" + url: "https://pub.dev" + source: hosted + version: "2.1.4" + pubspec_parse: + dependency: transitive + description: + name: pubspec_parse + sha256: c63b2876e58e194e4b0828fcb080ad0e06d051cb607a6be51a9e084f47cb9367 + url: "https://pub.dev" + source: hosted + version: "1.2.3" + rxdart: + dependency: transitive + description: + name: rxdart + sha256: "0c7c0cedd93788d996e33041ffecda924cc54389199cde4e6a34b440f50044cb" + url: "https://pub.dev" + source: hosted + version: "0.27.7" + shelf: + dependency: transitive + description: + name: shelf + sha256: ad29c505aee705f41a4d8963641f91ac4cee3c8fad5947e033390a7bd8180fa4 + url: "https://pub.dev" + source: hosted + version: "1.4.1" + sky_engine: + dependency: transitive + description: flutter + source: sdk + version: "0.0.99" + source_span: + dependency: transitive + description: + name: source_span + sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" + url: "https://pub.dev" + source: hosted + version: "1.10.0" + sprintf: + dependency: transitive + description: + name: sprintf + sha256: "1fc9ffe69d4df602376b52949af107d8f5703b77cda567c4d7d86a0693120f23" + url: "https://pub.dev" + source: hosted + version: "7.0.0" + stack_trace: + dependency: transitive + description: + name: stack_trace + sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" + url: "https://pub.dev" + source: hosted + version: "1.11.1" + stream_channel: + dependency: transitive + description: + name: stream_channel + sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 + url: "https://pub.dev" + source: hosted + version: "2.1.2" + stream_transform: + dependency: transitive + description: + name: stream_transform + sha256: "14a00e794c7c11aa145a170587321aedce29769c08d7f58b1d141da75e3b1c6f" + url: "https://pub.dev" + source: hosted + version: "2.1.0" + string_scanner: + dependency: transitive + description: + name: string_scanner + sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" + url: "https://pub.dev" + source: hosted + version: "1.2.0" + term_glyph: + dependency: transitive + description: + name: term_glyph + sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 + url: "https://pub.dev" + source: hosted + version: "1.2.1" + test_api: + dependency: transitive + description: + name: test_api + sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b" + url: "https://pub.dev" + source: hosted + version: "0.6.1" + timezone: + dependency: "direct main" + description: + name: timezone + sha256: "1cfd8ddc2d1cfd836bc93e67b9be88c3adaeca6f40a00ca999104c30693cdca0" + url: "https://pub.dev" + source: hosted + version: "0.9.2" + typed_data: + dependency: transitive + description: + name: typed_data + sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c + url: "https://pub.dev" + source: hosted + version: "1.3.2" + uuid: + dependency: transitive + description: + name: uuid + sha256: df5a4d8f22ee4ccd77f8839ac7cb274ebc11ef9adcce8b92be14b797fe889921 + url: "https://pub.dev" + source: hosted + version: "4.2.1" + 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: b3d56ff4341b8f182b96aceb2fa20e3dcb336b9f867bc0eafc0de10f1048e957 + url: "https://pub.dev" + source: hosted + version: "13.0.0" + watcher: + dependency: transitive + description: + name: watcher + sha256: "3d2ad6751b3c16cf07c7fca317a1413b3f26530319181b37e3b9039b84fc01d8" + url: "https://pub.dev" + source: hosted + version: "1.1.0" + web: + dependency: transitive + description: + name: web + sha256: afe077240a270dcfd2aafe77602b4113645af95d0ad31128cc02bce5ac5d5152 + url: "https://pub.dev" + source: hosted + version: "0.3.0" + webview_flutter: + dependency: "direct main" + description: + name: webview_flutter + sha256: "42393b4492e629aa3a88618530a4a00de8bb46e50e7b3993fedbfdc5352f0dbf" + url: "https://pub.dev" + source: hosted + version: "4.4.2" + webview_flutter_android: + dependency: transitive + description: + name: webview_flutter_android + sha256: "8326ee235f87605a2bfc444a4abc897f4abc78d83f054ba7d3d1074ce82b4fbf" + url: "https://pub.dev" + source: hosted + version: "3.12.1" + webview_flutter_platform_interface: + dependency: transitive + description: + name: webview_flutter_platform_interface + sha256: adb8c03c2be231bea5a8ed0e9039e9d18dbb049603376beaefa15393ede468a5 + url: "https://pub.dev" + source: hosted + version: "2.7.0" + webview_flutter_wkwebview: + dependency: transitive + description: + name: webview_flutter_wkwebview + sha256: accdaaa49a2aca2dc3c3230907988954cdd23fed0a19525d6c9789d380f4dc76 + url: "https://pub.dev" + source: hosted + version: "3.9.4" + xdg_directories: + dependency: transitive + description: + name: xdg_directories + sha256: "589ada45ba9e39405c198fe34eb0f607cddb2108527e658136120892beac46d2" + url: "https://pub.dev" + source: hosted + version: "1.0.3" + xml: + dependency: transitive + description: + name: xml + sha256: af5e77e9b83f2f4adc5d3f0a4ece1c7f45a2467b695c2540381bac793e34e556 + url: "https://pub.dev" + source: hosted + version: "6.4.2" + yaml: + dependency: transitive + description: + name: yaml + sha256: "75769501ea3489fca56601ff33454fe45507ea3bfb014161abc3b43ae25989d5" + url: "https://pub.dev" + source: hosted + version: "3.1.2" +sdks: + dart: ">=3.2.0 <4.0.0" + flutter: ">=3.16.0" diff --git a/dev/e2e_app/pubspec.yaml b/dev/e2e_app/pubspec.yaml new file mode 100644 index 000000000..6b5ab9bb6 --- /dev/null +++ b/dev/e2e_app/pubspec.yaml @@ -0,0 +1,36 @@ +name: e2e_app +description: A new Flutter project. +publish_to: none +version: 1.0.0+1 + +environment: + sdk: '>=3.2.0 <4.0.0' + flutter: '>=3.16.0' + +dependencies: + cupertino_icons: ^1.0.6 + flutter: + sdk: flutter + flutter_local_notifications: ^16.1.0 + flutter_timezone: ^1.0.8 + geolocator: ^10.1.0 + permission_handler: ^10.4.5 + timezone: ^0.9.2 + webview_flutter: ^4.4.2 + +dev_dependencies: + flutter_test: + sdk: flutter + leancode_lint: ^7.0.0+1 + patrol: + path: ../../packages/patrol + +flutter: + uses-material-design: true + +patrol: + app_name: Patrol example + android: + package_name: pl.leancode.patrol.e2e_app + ios: + bundle_id: pl.leancode.patrol.Example diff --git a/packages/patrol/example/run_android_testlab b/dev/e2e_app/run_android_testlab similarity index 100% rename from packages/patrol/example/run_android_testlab rename to dev/e2e_app/run_android_testlab diff --git a/packages/patrol/example/run_ios_testlab b/dev/e2e_app/run_ios_testlab similarity index 100% rename from packages/patrol/example/run_ios_testlab rename to dev/e2e_app/run_ios_testlab diff --git a/dev/e2e_app/test/example_test.dart b/dev/e2e_app/test/example_test.dart new file mode 100644 index 000000000..c49295e5e --- /dev/null +++ b/dev/e2e_app/test/example_test.dart @@ -0,0 +1,7 @@ +import 'package:flutter_test/flutter_test.dart'; + +void main() { + test('my first unit test', () { + expect(true, true); + }); +} diff --git a/packages/patrol/example/.gitignore b/packages/patrol/example/.gitignore index 2c555b0b2..0c8de0d80 100644 --- a/packages/patrol/example/.gitignore +++ b/packages/patrol/example/.gitignore @@ -8,6 +8,7 @@ .buildlog/ .history .svn/ +migrate_working_dir/ # IntelliJ related *.iml @@ -31,9 +32,6 @@ .pub/ /build/ -# Web related -lib/generated_plugin_registrant.dart - # Symbolication related app.*.symbols @@ -45,9 +43,5 @@ app.*.map.json /android/app/profile /android/app/release -/screenshots -hello.txt -counter_text.txt - -# Generated by Patrol CLI -test_bundle.dart +# Patrol related +integration_test/test_bundle.dart diff --git a/packages/patrol/example/README.md b/packages/patrol/example/README.md index 2efc4aa84..784357248 100644 --- a/packages/patrol/example/README.md +++ b/packages/patrol/example/README.md @@ -1,43 +1,26 @@ -# patrol example app +# patrol_challenge -This application demonstrates most of Patrol's features. +App with the quiz for Fluttercon -## Building +### Set up -Make sure to use the compatible Patrol CLI version. The easiest way is to run: +This project is a simple quiz Flutter app. It uses flavors. -```console -$ dart pub global activate --source path packages/patrol_cli && patrol -``` - -from the repository root. - -Once you have the right Patrol CLI version, building artifacts for testing is easy. - -### Android - -Run in the example app's root: +To run tests: -```console -$ patrol build android +``` +dart run patrol test ``` -This builds 2 APKs: -- the app under test: `/build/app/outputs/apk/debug/app-debug.apk` -- the instrumentation app: `/build/app/outputs/apk/androidTest/debug/app-debug-androidTest.apk` - -### iOS device +### Google credentials -Run in the example app's root: +This app allows the user to sign in with Google. This requires some +configuration, but it's not needed if you don't plan on using this feature. -```console -$ patrol build ios --release -``` +**Android** -### iOS simulator +Place `google-services.json` in `android/app`. -Run in the example app's root: +**iOS** -``` -$ patrol build ios --debug --simulator -``` +Place `GoogleService-Info.plist` in `ios/Runner`. diff --git a/packages/patrol/example/analysis_options.yaml b/packages/patrol/example/analysis_options.yaml index 98093f93d..4af9cbc42 100644 --- a/packages/patrol/example/analysis_options.yaml +++ b/packages/patrol/example/analysis_options.yaml @@ -1,6 +1 @@ include: package:leancode_lint/analysis_options.yaml - -linter: - rules: - prefer_const_constructors: false - avoid_print: false diff --git a/packages/patrol/example/android/.gitignore b/packages/patrol/example/android/.gitignore index ea6a81579..6f568019d 100644 --- a/packages/patrol/example/android/.gitignore +++ b/packages/patrol/example/android/.gitignore @@ -11,6 +11,3 @@ GeneratedPluginRegistrant.java key.properties **/*.keystore **/*.jks - -test-reports -test-results diff --git a/packages/patrol/example/android/app/build.gradle b/packages/patrol/example/android/app/build.gradle index cb9dd3f5c..9fdde16ae 100644 --- a/packages/patrol/example/android/app/build.gradle +++ b/packages/patrol/example/android/app/build.gradle @@ -1,69 +1,72 @@ +plugins { + id "com.android.application" + id "org.jetbrains.kotlin.android" + id "dev.flutter.flutter-gradle-plugin" + id "com.google.gms.google-services" +} + def localProperties = new Properties() -def localPropertiesFile = rootProject.file("local.properties") +def localPropertiesFile = rootProject.file('local.properties') if (localPropertiesFile.exists()) { - localPropertiesFile.withReader("UTF-8") { reader -> + localPropertiesFile.withReader('UTF-8') { reader -> localProperties.load(reader) } } -def flutterRoot = localProperties.getProperty("flutter.sdk") -if (flutterRoot == null) { - throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") -} - -def flutterVersionCode = localProperties.getProperty("flutter.versionCode") +def flutterVersionCode = localProperties.getProperty('flutter.versionCode') if (flutterVersionCode == null) { - flutterVersionCode = "1" + flutterVersionCode = '1' } -def flutterVersionName = localProperties.getProperty("flutter.versionName") +def flutterVersionName = localProperties.getProperty('flutter.versionName') if (flutterVersionName == null) { - flutterVersionName = "1.0" + flutterVersionName = '1.0' } -apply plugin: "com.android.application" -apply plugin: "kotlin-android" -apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" - android { - compileSdk 33 + compileSdkVersion 33 + ndkVersion flutter.ndkVersion + namespace "pl.leancode.patrol.example" + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + kotlinOptions { - jvmTarget = "1.8" + jvmTarget = '1.8' } sourceSets { - main.java.srcDirs += "src/main/kotlin" + main.java.srcDirs += 'src/main/kotlin' } defaultConfig { applicationId "pl.leancode.patrol.example" - minSdk 21 - targetSdk 33 + minSdkVersion 21 + targetSdkVersion 33 versionCode flutterVersionCode.toInteger() versionName flutterVersionName testInstrumentationRunner "pl.leancode.patrol.PatrolJUnitRunner" testInstrumentationRunnerArguments clearPackageData: "true" } + testOptions { + execution "ANDROIDX_TEST_ORCHESTRATOR" + } + buildTypes { release { - // Signing with the debug keys for now, so `flutter run --release` works. signingConfig signingConfigs.debug } } - - testOptions { - execution "ANDROIDX_TEST_ORCHESTRATOR" - } } flutter { - source "../.." + source '../..' } dependencies { - implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" - androidTestUtil "androidx.test:orchestrator:1.4.2" + androidTestUtil 'androidx.test:orchestrator:1.4.2' } diff --git a/packages/patrol/example/android/app/google-services.json b/packages/patrol/example/android/app/google-services.json new file mode 100644 index 000000000..1401c22a5 --- /dev/null +++ b/packages/patrol/example/android/app/google-services.json @@ -0,0 +1,62 @@ +{ + "project_info": { + "project_number": "1084522097392", + "project_id": "REMOVED", + "storage_bucket": "REMOVED.appspot.com" + }, + "client": [ + { + "client_info": { + "mobilesdk_app_id": "1:1084544027393:android:a954abb91299778a2c8ff0", + "android_client_info": { + "package_name": "pl.leancode.patrol.example" + } + }, + "oauth_client": [ + { + "client_id": "1082544097392-j48pqr8dkg4almagua8er7hcl86el0df.apps.googleusercontent.com", + "client_type": 1, + "android_info": { + "package_name": "pl.leancode.patrol.example", + "certificate_hash": "04c4d550315e88f469e252e20d08aa7bf07d8657" + } + }, + { + "client_id": "1084144097393-vu46lsrqbkenn0kid9r469668m6rtd0.apps.googleusercontent.com", + "client_type": 1, + "android_info": { + "package_name": "pl.leancode.patrol.Example", + "certificate_hash": "77d5797c5c5481afe34d78ef8153d59cfd44f951" + } + }, + { + "client_id": "1084544097393-7fu46orccluulnfv0cjq3rvtv9e4op3q.apps.googleusercontent.com", + "client_type": 3 + } + ], + "api_key": [ + { + "current_key": "AIzaSyChbKtvpnU9dvaI4U69_HHEd8mjb1ehx0o" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [ + { + "client_id": "1084544097393-7fu46orccluullfv0cjq5rvtv9e8op3q.apps.googleusercontent.com", + "client_type": 3 + }, + { + "client_id": "1084544094393-1n4pqvqcni14ihhkbgl5oda9ufg9c6gf.apps.googleusercontent.com", + "client_type": 2, + "ios_info": { + "bundle_id": "pl.leancode.patrol.Example" + } + } + ] + } + } + } + ], + "configuration_version": "1" +} diff --git a/packages/patrol/example/android/app/src/androidTest/java/pl/leancode/patrol/example/MainActivityTest.java b/packages/patrol/example/android/app/src/androidTest/pl/leancode/patrol/example/MainActivityTest.java similarity index 100% rename from packages/patrol/example/android/app/src/androidTest/java/pl/leancode/patrol/example/MainActivityTest.java rename to packages/patrol/example/android/app/src/androidTest/pl/leancode/patrol/example/MainActivityTest.java diff --git a/packages/patrol/example/android/app/src/debug/AndroidManifest.xml b/packages/patrol/example/android/app/src/debug/AndroidManifest.xml new file mode 100644 index 000000000..399f6981d --- /dev/null +++ b/packages/patrol/example/android/app/src/debug/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/packages/patrol/example/android/app/src/main/AndroidManifest.xml b/packages/patrol/example/android/app/src/main/AndroidManifest.xml index b1fb866e6..c42ca1d16 100644 --- a/packages/patrol/example/android/app/src/main/AndroidManifest.xml +++ b/packages/patrol/example/android/app/src/main/AndroidManifest.xml @@ -1,20 +1,9 @@ - - - - - - - - - - - - + + + android:icon="@mipmap/launcher_icon"> + the Android process has started. This theme is visible to the user + while the Flutter UI initializes. After that, this theme continues + to determine the Window background behind the Flutter UI. --> - - - - - - - - - + This is used by the Flutter tool to generate GeneratedPluginRegistrant.java --> + android:value="2" /> diff --git a/packages/patrol/example/android/app/src/main/kotlin/pl/leancode/patrol/example/MainActivity.kt b/packages/patrol/example/android/app/src/main/kotlin/pl/leancode/patrol/example/MainActivity.kt index 6044ed3cb..0b9313215 100644 --- a/packages/patrol/example/android/app/src/main/kotlin/pl/leancode/patrol/example/MainActivity.kt +++ b/packages/patrol/example/android/app/src/main/kotlin/pl/leancode/patrol/example/MainActivity.kt @@ -2,4 +2,4 @@ package pl.leancode.patrol.example import io.flutter.embedding.android.FlutterActivity -class MainActivity : FlutterActivity() +class MainActivity: FlutterActivity() diff --git a/packages/patrol/example/android/app/src/main/res/drawable-hdpi/android12splash.png b/packages/patrol/example/android/app/src/main/res/drawable-hdpi/android12splash.png new file mode 100644 index 000000000..e10a17b88 Binary files /dev/null and b/packages/patrol/example/android/app/src/main/res/drawable-hdpi/android12splash.png differ diff --git a/packages/patrol/example/android/app/src/main/res/drawable-hdpi/splash.png b/packages/patrol/example/android/app/src/main/res/drawable-hdpi/splash.png new file mode 100644 index 000000000..e10a17b88 Binary files /dev/null and b/packages/patrol/example/android/app/src/main/res/drawable-hdpi/splash.png differ diff --git a/packages/patrol/example/android/app/src/main/res/drawable-mdpi/android12splash.png b/packages/patrol/example/android/app/src/main/res/drawable-mdpi/android12splash.png new file mode 100644 index 000000000..e94aac8ee Binary files /dev/null and b/packages/patrol/example/android/app/src/main/res/drawable-mdpi/android12splash.png differ diff --git a/packages/patrol/example/android/app/src/main/res/drawable-mdpi/splash.png b/packages/patrol/example/android/app/src/main/res/drawable-mdpi/splash.png new file mode 100644 index 000000000..e94aac8ee Binary files /dev/null and b/packages/patrol/example/android/app/src/main/res/drawable-mdpi/splash.png differ diff --git a/packages/patrol/example/android/app/src/main/res/drawable-night-hdpi/android12splash.png b/packages/patrol/example/android/app/src/main/res/drawable-night-hdpi/android12splash.png new file mode 100644 index 000000000..e10a17b88 Binary files /dev/null and b/packages/patrol/example/android/app/src/main/res/drawable-night-hdpi/android12splash.png differ diff --git a/packages/patrol/example/android/app/src/main/res/drawable-night-mdpi/android12splash.png b/packages/patrol/example/android/app/src/main/res/drawable-night-mdpi/android12splash.png new file mode 100644 index 000000000..e94aac8ee Binary files /dev/null and b/packages/patrol/example/android/app/src/main/res/drawable-night-mdpi/android12splash.png differ diff --git a/packages/patrol/example/android/app/src/main/res/drawable-night-xhdpi/android12splash.png b/packages/patrol/example/android/app/src/main/res/drawable-night-xhdpi/android12splash.png new file mode 100644 index 000000000..c80709495 Binary files /dev/null and b/packages/patrol/example/android/app/src/main/res/drawable-night-xhdpi/android12splash.png differ diff --git a/packages/patrol/example/android/app/src/main/res/drawable-night-xxhdpi/android12splash.png b/packages/patrol/example/android/app/src/main/res/drawable-night-xxhdpi/android12splash.png new file mode 100644 index 000000000..4c9ae4459 Binary files /dev/null and b/packages/patrol/example/android/app/src/main/res/drawable-night-xxhdpi/android12splash.png differ diff --git a/packages/patrol/example/android/app/src/main/res/drawable-night-xxxhdpi/android12splash.png b/packages/patrol/example/android/app/src/main/res/drawable-night-xxxhdpi/android12splash.png new file mode 100644 index 000000000..c4e59828d Binary files /dev/null and b/packages/patrol/example/android/app/src/main/res/drawable-night-xxxhdpi/android12splash.png differ diff --git a/packages/patrol/example/android/app/src/main/res/drawable-v21/background.png b/packages/patrol/example/android/app/src/main/res/drawable-v21/background.png new file mode 100644 index 000000000..89d9ab9c5 Binary files /dev/null and b/packages/patrol/example/android/app/src/main/res/drawable-v21/background.png differ diff --git a/packages/patrol/example/android/app/src/main/res/drawable-v21/launch_background.xml b/packages/patrol/example/android/app/src/main/res/drawable-v21/launch_background.xml index f74085f3f..3cc4948a1 100644 --- a/packages/patrol/example/android/app/src/main/res/drawable-v21/launch_background.xml +++ b/packages/patrol/example/android/app/src/main/res/drawable-v21/launch_background.xml @@ -1,12 +1,9 @@ - - - - - + + + + + + diff --git a/packages/patrol/example/android/app/src/main/res/drawable-xhdpi/android12splash.png b/packages/patrol/example/android/app/src/main/res/drawable-xhdpi/android12splash.png new file mode 100644 index 000000000..c80709495 Binary files /dev/null and b/packages/patrol/example/android/app/src/main/res/drawable-xhdpi/android12splash.png differ diff --git a/packages/patrol/example/android/app/src/main/res/drawable-xhdpi/splash.png b/packages/patrol/example/android/app/src/main/res/drawable-xhdpi/splash.png new file mode 100644 index 000000000..c80709495 Binary files /dev/null and b/packages/patrol/example/android/app/src/main/res/drawable-xhdpi/splash.png differ diff --git a/packages/patrol/example/android/app/src/main/res/drawable-xxhdpi/android12splash.png b/packages/patrol/example/android/app/src/main/res/drawable-xxhdpi/android12splash.png new file mode 100644 index 000000000..4c9ae4459 Binary files /dev/null and b/packages/patrol/example/android/app/src/main/res/drawable-xxhdpi/android12splash.png differ diff --git a/packages/patrol/example/android/app/src/main/res/drawable-xxhdpi/splash.png b/packages/patrol/example/android/app/src/main/res/drawable-xxhdpi/splash.png new file mode 100644 index 000000000..4c9ae4459 Binary files /dev/null and b/packages/patrol/example/android/app/src/main/res/drawable-xxhdpi/splash.png differ diff --git a/packages/patrol/example/android/app/src/main/res/drawable-xxxhdpi/android12splash.png b/packages/patrol/example/android/app/src/main/res/drawable-xxxhdpi/android12splash.png new file mode 100644 index 000000000..c4e59828d Binary files /dev/null and b/packages/patrol/example/android/app/src/main/res/drawable-xxxhdpi/android12splash.png differ diff --git a/packages/patrol/example/android/app/src/main/res/drawable-xxxhdpi/splash.png b/packages/patrol/example/android/app/src/main/res/drawable-xxxhdpi/splash.png new file mode 100644 index 000000000..c4e59828d Binary files /dev/null and b/packages/patrol/example/android/app/src/main/res/drawable-xxxhdpi/splash.png differ diff --git a/packages/patrol/example/android/app/src/main/res/drawable/app_icon.png b/packages/patrol/example/android/app/src/main/res/drawable/app_icon.png new file mode 100644 index 000000000..bb944ec7c Binary files /dev/null and b/packages/patrol/example/android/app/src/main/res/drawable/app_icon.png differ diff --git a/packages/patrol/example/android/app/src/main/res/drawable/background.png b/packages/patrol/example/android/app/src/main/res/drawable/background.png new file mode 100644 index 000000000..89d9ab9c5 Binary files /dev/null and b/packages/patrol/example/android/app/src/main/res/drawable/background.png differ diff --git a/packages/patrol/example/android/app/src/main/res/drawable/launch_background.xml b/packages/patrol/example/android/app/src/main/res/drawable/launch_background.xml index 304732f88..3cc4948a1 100644 --- a/packages/patrol/example/android/app/src/main/res/drawable/launch_background.xml +++ b/packages/patrol/example/android/app/src/main/res/drawable/launch_background.xml @@ -1,12 +1,9 @@ - - - - - + + + + + + diff --git a/packages/patrol/example/android/app/src/main/res/drawable/notification_icon.png b/packages/patrol/example/android/app/src/main/res/drawable/notification_icon.png new file mode 100644 index 000000000..169527113 Binary files /dev/null and b/packages/patrol/example/android/app/src/main/res/drawable/notification_icon.png differ diff --git a/packages/patrol/example/android/app/src/main/res/mipmap-hdpi/launcher_icon.png b/packages/patrol/example/android/app/src/main/res/mipmap-hdpi/launcher_icon.png new file mode 100644 index 000000000..7145e4227 Binary files /dev/null and b/packages/patrol/example/android/app/src/main/res/mipmap-hdpi/launcher_icon.png differ diff --git a/packages/patrol/example/android/app/src/main/res/mipmap-mdpi/launcher_icon.png b/packages/patrol/example/android/app/src/main/res/mipmap-mdpi/launcher_icon.png new file mode 100644 index 000000000..89cec41c7 Binary files /dev/null and b/packages/patrol/example/android/app/src/main/res/mipmap-mdpi/launcher_icon.png differ diff --git a/packages/patrol/example/android/app/src/main/res/mipmap-xhdpi/launcher_icon.png b/packages/patrol/example/android/app/src/main/res/mipmap-xhdpi/launcher_icon.png new file mode 100644 index 000000000..b0a7e485f Binary files /dev/null and b/packages/patrol/example/android/app/src/main/res/mipmap-xhdpi/launcher_icon.png differ diff --git a/packages/patrol/example/android/app/src/main/res/mipmap-xxhdpi/launcher_icon.png b/packages/patrol/example/android/app/src/main/res/mipmap-xxhdpi/launcher_icon.png new file mode 100644 index 000000000..02476e92e Binary files /dev/null and b/packages/patrol/example/android/app/src/main/res/mipmap-xxhdpi/launcher_icon.png differ diff --git a/packages/patrol/example/android/app/src/main/res/mipmap-xxxhdpi/launcher_icon.png b/packages/patrol/example/android/app/src/main/res/mipmap-xxxhdpi/launcher_icon.png new file mode 100644 index 000000000..24bb63b04 Binary files /dev/null and b/packages/patrol/example/android/app/src/main/res/mipmap-xxxhdpi/launcher_icon.png differ diff --git a/packages/patrol/example/android/app/src/main/res/values-night-v31/styles.xml b/packages/patrol/example/android/app/src/main/res/values-night-v31/styles.xml new file mode 100644 index 000000000..f157d8639 --- /dev/null +++ b/packages/patrol/example/android/app/src/main/res/values-night-v31/styles.xml @@ -0,0 +1,21 @@ + + + + + + + diff --git a/packages/patrol/example/android/app/src/main/res/values-night/styles.xml b/packages/patrol/example/android/app/src/main/res/values-night/styles.xml index 3db14bb53..06952be74 100644 --- a/packages/patrol/example/android/app/src/main/res/values-night/styles.xml +++ b/packages/patrol/example/android/app/src/main/res/values-night/styles.xml @@ -3,7 +3,7 @@ + + + + diff --git a/packages/patrol/example/android/app/src/main/res/values/colors.xml b/packages/patrol/example/android/app/src/main/res/values/colors.xml new file mode 100644 index 000000000..508febfcb --- /dev/null +++ b/packages/patrol/example/android/app/src/main/res/values/colors.xml @@ -0,0 +1,3 @@ + + #1F1F1F + \ No newline at end of file diff --git a/packages/patrol/example/android/app/src/main/res/values/styles.xml b/packages/patrol/example/android/app/src/main/res/values/styles.xml index d460d1e92..0d1fa8fce 100644 --- a/packages/patrol/example/android/app/src/main/res/values/styles.xml +++ b/packages/patrol/example/android/app/src/main/res/values/styles.xml @@ -3,8 +3,12 @@ + + diff --git a/packages/patrol/example/android/build.gradle b/packages/patrol/example/android/build.gradle index 2f807d1e2..da0d8da81 100644 --- a/packages/patrol/example/android/build.gradle +++ b/packages/patrol/example/android/build.gradle @@ -1,25 +1,9 @@ -buildscript { - ext.kotlin_version = "1.8.22" - repositories { - google() - mavenCentral() - } - - dependencies { - classpath "com.android.tools.build:gradle:7.4.2" - classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" - } -} - -allprojects { - repositories { - google() - mavenCentral() - } -} - rootProject.buildDir = "../build" subprojects { project.buildDir = "${rootProject.buildDir}/${project.name}" project.evaluationDependsOn(":app") } + +tasks.register("clean", Delete) { + delete rootProject.buildDir +} diff --git a/packages/patrol/example/android/gradle.properties b/packages/patrol/example/android/gradle.properties index d9cf55df7..94adc3a3f 100644 --- a/packages/patrol/example/android/gradle.properties +++ b/packages/patrol/example/android/gradle.properties @@ -1,2 +1,3 @@ org.gradle.jvmargs=-Xmx1536M android.useAndroidX=true +android.enableJetifier=true diff --git a/packages/patrol/example/android/gradle/wrapper/gradle-wrapper.properties b/packages/patrol/example/android/gradle/wrapper/gradle-wrapper.properties index cb046be63..5e6b54271 100644 --- a/packages/patrol/example/android/gradle/wrapper/gradle-wrapper.properties +++ b/packages/patrol/example/android/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,5 @@ -#Fri Jun 23 08:50:38 CEST 2017 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.2-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-all.zip diff --git a/packages/patrol/example/android/settings.gradle b/packages/patrol/example/android/settings.gradle index e791cf5c3..f08a60d92 100644 --- a/packages/patrol/example/android/settings.gradle +++ b/packages/patrol/example/android/settings.gradle @@ -1,11 +1,27 @@ -include ":app" +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 + } + settings.ext.flutterSdkPath = flutterSdkPath() + + includeBuild("${settings.ext.flutterSdkPath}/packages/flutter_tools/gradle") -def localPropertiesFile = new File(rootProject.projectDir, "local.properties") -def properties = new Properties() + repositories { + google() + mavenCentral() + gradlePluginPortal() + } +} -assert localPropertiesFile.exists() -localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } +plugins { + id "dev.flutter.flutter-plugin-loader" + id "com.android.application" version "8.1.2" apply false + id "com.google.gms.google-services" version "4.4.0" apply false + id "org.jetbrains.kotlin.android" version "1.9.20" apply false +} -def flutterSdkPath = properties.getProperty("flutter.sdk") -assert flutterSdkPath != null, "flutter.sdk not set in local.properties" -apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" +include ":app" diff --git a/packages/patrol/example/assets/fonts/Inter-Medium.ttf b/packages/patrol/example/assets/fonts/Inter-Medium.ttf new file mode 100644 index 000000000..b53fb1c4a Binary files /dev/null and b/packages/patrol/example/assets/fonts/Inter-Medium.ttf differ diff --git a/packages/patrol/example/assets/fonts/Inter-SemiBold.ttf b/packages/patrol/example/assets/fonts/Inter-SemiBold.ttf new file mode 100644 index 000000000..c6aeeb16a Binary files /dev/null and b/packages/patrol/example/assets/fonts/Inter-SemiBold.ttf differ diff --git a/packages/patrol/example/assets/icon/app_icon.png b/packages/patrol/example/assets/icon/app_icon.png new file mode 100644 index 000000000..bb944ec7c Binary files /dev/null and b/packages/patrol/example/assets/icon/app_icon.png differ diff --git a/packages/patrol/example/assets/icon/circle_x.svg b/packages/patrol/example/assets/icon/circle_x.svg new file mode 100644 index 000000000..6f59a047a --- /dev/null +++ b/packages/patrol/example/assets/icon/circle_x.svg @@ -0,0 +1,3 @@ + + + diff --git a/packages/patrol/example/assets/icon/notification_icon.png b/packages/patrol/example/assets/icon/notification_icon.png new file mode 100644 index 000000000..169527113 Binary files /dev/null and b/packages/patrol/example/assets/icon/notification_icon.png differ diff --git a/packages/patrol/example/assets/icon/splash_icon.png b/packages/patrol/example/assets/icon/splash_icon.png new file mode 100644 index 000000000..73db17034 Binary files /dev/null and b/packages/patrol/example/assets/icon/splash_icon.png differ diff --git a/packages/patrol/example/assets/image/confetti.svg b/packages/patrol/example/assets/image/confetti.svg new file mode 100644 index 000000000..fe41e6c5e --- /dev/null +++ b/packages/patrol/example/assets/image/confetti.svg @@ -0,0 +1,134 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/patrol/example/assets/image/fluttercon_logo.svg b/packages/patrol/example/assets/image/fluttercon_logo.svg new file mode 100644 index 000000000..27b730c74 --- /dev/null +++ b/packages/patrol/example/assets/image/fluttercon_logo.svg @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/packages/patrol/example/assets/image/leancode_logo.svg b/packages/patrol/example/assets/image/leancode_logo.svg new file mode 100644 index 000000000..17973bd9d --- /dev/null +++ b/packages/patrol/example/assets/image/leancode_logo.svg @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/packages/patrol/example/assets/image/patrol_logo.svg b/packages/patrol/example/assets/image/patrol_logo.svg new file mode 100644 index 000000000..5da6793c5 --- /dev/null +++ b/packages/patrol/example/assets/image/patrol_logo.svg @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/patrol/example/dart_test.yaml b/packages/patrol/example/dart_test.yaml deleted file mode 100644 index c3374e1cc..000000000 --- a/packages/patrol/example/dart_test.yaml +++ /dev/null @@ -1,3 +0,0 @@ -tags: - android: - ios: diff --git a/packages/patrol/example/devtools_options.yaml b/packages/patrol/example/devtools_options.yaml deleted file mode 100644 index 7e9b8c7c0..000000000 --- a/packages/patrol/example/devtools_options.yaml +++ /dev/null @@ -1,2 +0,0 @@ -extensions: - - patrol: true \ No newline at end of file diff --git a/packages/patrol/example/integration_test/empty_test.dart b/packages/patrol/example/integration_test/empty_test.dart new file mode 100644 index 000000000..94dbdb405 --- /dev/null +++ b/packages/patrol/example/integration_test/empty_test.dart @@ -0,0 +1,19 @@ +import 'package:example/main.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:patrol/patrol.dart'; + +void main() { + patrolTest( + 'test', + ($) async { + await initApp(); + await $.pumpWidgetAndSettle(const MyApp()); + + // write your code here + + await $.pumpAndSettle(); + + expect($('Congratulations!'), findsOneWidget); + }, + ); +} diff --git a/packages/patrol/example/integration_test/main_test.dart b/packages/patrol/example/integration_test/main_test.dart new file mode 100644 index 000000000..035b5e6c1 --- /dev/null +++ b/packages/patrol/example/integration_test/main_test.dart @@ -0,0 +1,65 @@ +import 'package:example/main.dart'; +import 'package:example/pages/quiz/form_page.dart'; +import 'package:example/ui/components/button/elevated_button.dart'; +import 'package:example/ui/style/colors.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:patrol/patrol.dart'; + +void main() { + patrolTest('main flow', ($) async { + await $.pumpWidgetAndSettle(const MyApp()); + + await $('Go to the quiz').tap(); + + await $('Start').tap(); + + await $(TextField).enterText('text'); + + final colors = [PTColors.lcYellow, PTColors.lcBlack, PTColors.lcWhite]; + + for (final color in colors) { + await $(SelectableBox) + .which((box) => box.color == color) + .scrollTo() + .tap(); + } + + await $('Ready!').tap(); + + // Why doesn't it work? + // await $(ElevatedButton).$(Center).$('Fluttercon').tap(); + + await $(PTElevatedButton) + .which((widget) => widget.caption == 'Fluttercon') + .tap(); + + await $(ListTile).containing($(Icons.flutter_dash)).$('click').tap(); + + await $(ElevatedButton) + .which( + (widget) => widget.enabled, + ) + .at(2) + .scrollTo() + .tap(); + + if (await $.native.isPermissionDialogVisible()) { + await $.native.grantPermissionWhenInUse(); + } + + await $.native.pressHome(); + await $.native.openNotifications(); + + // wait for notification to show up + await Future.delayed(const Duration(seconds: 5)); + + await $.native.openNotifications(); + + await $.native.tapOnNotificationByIndex(0); + + await $.pumpAndSettle(); + + expect($('Congratulations!'), findsOneWidget); + }); +} diff --git a/packages/patrol/example/ios/.gitignore b/packages/patrol/example/ios/.gitignore index 3cbd03717..7a7f9873a 100644 --- a/packages/patrol/example/ios/.gitignore +++ b/packages/patrol/example/ios/.gitignore @@ -32,8 +32,3 @@ Runner/GeneratedPluginRegistrant.* !default.mode2v3 !default.pbxuser !default.perspectivev3 - -# Files for XCTestHTMLReport -TestResults -TestResults.xcresult -index.html diff --git a/packages/patrol/example/ios/Podfile b/packages/patrol/example/ios/Podfile index 30eedc704..7fcb5e2a7 100644 --- a/packages/patrol/example/ios/Podfile +++ b/packages/patrol/example/ios/Podfile @@ -1,6 +1,4 @@ -# Uncomment this line to define a global platform for your project -ios_deployment_target = '11.0' -platform :ios, ios_deployment_target +platform :ios, '11.0' # CocoaPods analytics sends network stats synchronously affecting flutter build latency. ENV['COCOAPODS_DISABLE_STATS'] = 'true' @@ -42,54 +40,14 @@ end post_install do |installer| installer.pods_project.targets.each do |target| flutter_additional_ios_build_settings(target) + # Start of the permission_handler configuration + target.build_configurations.each do |config| - target.build_configurations.each do |config| - config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = ios_deployment_target - config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [ - '$(inherited)', + config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [ + '$(inherited)', - ## dart: PermissionGroup.calendar - # 'PERMISSION_EVENTS=1', - - ## dart: PermissionGroup.reminders - # 'PERMISSION_REMINDERS=1', - - ## dart: PermissionGroup.contacts - 'PERMISSION_CONTACTS=1', - - ## dart: PermissionGroup.camera - 'PERMISSION_CAMERA=1', - - ## dart: PermissionGroup.microphone - 'PERMISSION_MICROPHONE=1', - - ## dart: PermissionGroup.speech - # 'PERMISSION_SPEECH_RECOGNIZER=1', - - ## dart: PermissionGroup.photos - # 'PERMISSION_PHOTOS=1', - - ## dart: [PermissionGroup.location, PermissionGroup.locationAlways, PermissionGroup.locationWhenInUse] - 'PERMISSION_LOCATION=1', - - ## dart: PermissionGroup.notification - # 'PERMISSION_NOTIFICATIONS=1', - - ## dart: PermissionGroup.mediaLibrary - # 'PERMISSION_MEDIA_LIBRARY=1', - - ## dart: PermissionGroup.sensors - # 'PERMISSION_SENSORS=1', - - ## dart: PermissionGroup.bluetooth - # 'PERMISSION_BLUETOOTH=1', - - ## dart: PermissionGroup.appTrackingTransparency - # 'PERMISSION_APP_TRACKING_TRANSPARENCY=1', - - ## dart: PermissionGroup.criticalAlerts - # 'PERMISSION_CRITICAL_ALERTS=1' - ] - end + 'PERMISSION_NOTIFICATIONS=1', + ] + end end end diff --git a/packages/patrol/example/ios/Podfile.lock b/packages/patrol/example/ios/Podfile.lock index d7cd4bbf6..87398a90b 100644 --- a/packages/patrol/example/ios/Podfile.lock +++ b/packages/patrol/example/ios/Podfile.lock @@ -1,67 +1,207 @@ PODS: + - AppAuth (1.6.2): + - AppAuth/Core (= 1.6.2) + - AppAuth/ExternalUserAgent (= 1.6.2) + - AppAuth/Core (1.6.2) + - AppAuth/ExternalUserAgent (1.6.2): + - AppAuth/Core - CocoaAsyncSocket (7.6.5) + - Firebase/Auth (10.18.0): + - Firebase/CoreOnly + - FirebaseAuth (~> 10.18.0) + - Firebase/CoreOnly (10.18.0): + - FirebaseCore (= 10.18.0) + - Firebase/Messaging (10.18.0): + - Firebase/CoreOnly + - FirebaseMessaging (~> 10.18.0) + - firebase_auth (4.14.1): + - Firebase/Auth (= 10.18.0) + - firebase_core + - Flutter + - firebase_core (2.23.0): + - Firebase/CoreOnly (= 10.18.0) + - Flutter + - firebase_messaging (14.7.5): + - Firebase/Messaging (= 10.18.0) + - firebase_core + - Flutter + - FirebaseAppCheckInterop (10.18.0) + - FirebaseAuth (10.18.0): + - FirebaseAppCheckInterop (~> 10.17) + - FirebaseCore (~> 10.0) + - GoogleUtilities/AppDelegateSwizzler (~> 7.8) + - GoogleUtilities/Environment (~> 7.8) + - GTMSessionFetcher/Core (< 4.0, >= 2.1) + - RecaptchaInterop (~> 100.0) + - FirebaseCore (10.18.0): + - FirebaseCoreInternal (~> 10.0) + - GoogleUtilities/Environment (~> 7.12) + - GoogleUtilities/Logger (~> 7.12) + - FirebaseCoreInternal (10.18.0): + - "GoogleUtilities/NSData+zlib (~> 7.8)" + - FirebaseInstallations (10.18.0): + - FirebaseCore (~> 10.0) + - GoogleUtilities/Environment (~> 7.8) + - GoogleUtilities/UserDefaults (~> 7.8) + - PromisesObjC (~> 2.1) + - FirebaseMessaging (10.18.0): + - FirebaseCore (~> 10.0) + - FirebaseInstallations (~> 10.0) + - GoogleDataTransport (~> 9.2) + - GoogleUtilities/AppDelegateSwizzler (~> 7.8) + - GoogleUtilities/Environment (~> 7.8) + - GoogleUtilities/Reachability (~> 7.8) + - GoogleUtilities/UserDefaults (~> 7.8) + - nanopb (< 2.30910.0, >= 2.30908.0) - Flutter (1.0.0) - flutter_local_notifications (0.0.1): - Flutter - - flutter_timezone (0.0.1): + - flutter_native_splash (0.0.1): + - Flutter + - geocoding_ios (1.0.5): - Flutter - geolocator_apple (1.2.0): - Flutter + - google_sign_in_ios (0.0.1): + - Flutter + - GoogleSignIn (~> 6.2) + - GoogleDataTransport (9.2.5): + - GoogleUtilities/Environment (~> 7.7) + - nanopb (< 2.30910.0, >= 2.30908.0) + - PromisesObjC (< 3.0, >= 1.2) + - GoogleSignIn (6.2.4): + - AppAuth (~> 1.5) + - GTMAppAuth (~> 1.3) + - GTMSessionFetcher/Core (< 3.0, >= 1.1) + - GoogleUtilities/AppDelegateSwizzler (7.12.0): + - GoogleUtilities/Environment + - GoogleUtilities/Logger + - GoogleUtilities/Network + - GoogleUtilities/Environment (7.12.0): + - PromisesObjC (< 3.0, >= 1.2) + - GoogleUtilities/Logger (7.12.0): + - GoogleUtilities/Environment + - GoogleUtilities/Network (7.12.0): + - GoogleUtilities/Logger + - "GoogleUtilities/NSData+zlib" + - GoogleUtilities/Reachability + - "GoogleUtilities/NSData+zlib (7.12.0)" + - GoogleUtilities/Reachability (7.12.0): + - GoogleUtilities/Logger + - GoogleUtilities/UserDefaults (7.12.0): + - GoogleUtilities/Logger + - GTMAppAuth (1.3.1): + - AppAuth/Core (~> 1.6) + - GTMSessionFetcher/Core (< 3.0, >= 1.5) + - GTMSessionFetcher/Core (2.3.0) - HTTPParserC (2.9.4) + - nanopb (2.30909.1): + - nanopb/decode (= 2.30909.1) + - nanopb/encode (= 2.30909.1) + - nanopb/decode (2.30909.1) + - nanopb/encode (2.30909.1) - patrol (0.0.1): - Flutter - Telegraph (~> 0.30.0) - permission_handler_apple (9.1.1): - Flutter + - PromisesObjC (2.3.1) + - RecaptchaInterop (100.0.0) - Telegraph (0.30.0): - CocoaAsyncSocket (~> 7.6) - HTTPParserC (~> 2.9) - - webview_flutter_wkwebview (0.0.1): - - Flutter DEPENDENCIES: + - firebase_auth (from `.symlinks/plugins/firebase_auth/ios`) + - firebase_core (from `.symlinks/plugins/firebase_core/ios`) + - firebase_messaging (from `.symlinks/plugins/firebase_messaging/ios`) - Flutter (from `Flutter`) - flutter_local_notifications (from `.symlinks/plugins/flutter_local_notifications/ios`) - - flutter_timezone (from `.symlinks/plugins/flutter_timezone/ios`) + - flutter_native_splash (from `.symlinks/plugins/flutter_native_splash/ios`) + - geocoding_ios (from `.symlinks/plugins/geocoding_ios/ios`) - geolocator_apple (from `.symlinks/plugins/geolocator_apple/ios`) + - google_sign_in_ios (from `.symlinks/plugins/google_sign_in_ios/ios`) - patrol (from `.symlinks/plugins/patrol/ios`) - permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/ios`) - - webview_flutter_wkwebview (from `.symlinks/plugins/webview_flutter_wkwebview/ios`) SPEC REPOS: trunk: + - AppAuth - CocoaAsyncSocket + - Firebase + - FirebaseAppCheckInterop + - FirebaseAuth + - FirebaseCore + - FirebaseCoreInternal + - FirebaseInstallations + - FirebaseMessaging + - GoogleDataTransport + - GoogleSignIn + - GoogleUtilities + - GTMAppAuth + - GTMSessionFetcher - HTTPParserC + - nanopb + - PromisesObjC + - RecaptchaInterop - Telegraph EXTERNAL SOURCES: + firebase_auth: + :path: ".symlinks/plugins/firebase_auth/ios" + firebase_core: + :path: ".symlinks/plugins/firebase_core/ios" + firebase_messaging: + :path: ".symlinks/plugins/firebase_messaging/ios" Flutter: :path: Flutter flutter_local_notifications: :path: ".symlinks/plugins/flutter_local_notifications/ios" - flutter_timezone: - :path: ".symlinks/plugins/flutter_timezone/ios" + flutter_native_splash: + :path: ".symlinks/plugins/flutter_native_splash/ios" + geocoding_ios: + :path: ".symlinks/plugins/geocoding_ios/ios" geolocator_apple: :path: ".symlinks/plugins/geolocator_apple/ios" + google_sign_in_ios: + :path: ".symlinks/plugins/google_sign_in_ios/ios" patrol: :path: ".symlinks/plugins/patrol/ios" permission_handler_apple: :path: ".symlinks/plugins/permission_handler_apple/ios" - webview_flutter_wkwebview: - :path: ".symlinks/plugins/webview_flutter_wkwebview/ios" SPEC CHECKSUMS: + AppAuth: 3bb1d1cd9340bd09f5ed189fb00b1cc28e1e8570 CocoaAsyncSocket: 065fd1e645c7abab64f7a6a2007a48038fdc6a99 + Firebase: 414ad272f8d02dfbf12662a9d43f4bba9bec2a06 + firebase_auth: 88053a759923970e580789d167a43b6031568ef5 + firebase_core: 29d66baf806970cda37c93621b27cd369b27db1b + firebase_messaging: 0a39f2514e1f27b0274b0d2fa99048f57856ee7c + FirebaseAppCheckInterop: 3cd914842ba46f4304050874cd284de82f154ffd + FirebaseAuth: 12314b438fa76048540c8fb86d6cfc9e08595176 + FirebaseCore: 2322423314d92f946219c8791674d2f3345b598f + FirebaseCoreInternal: 8eb002e564b533bdcf1ba011f33f2b5c10e2ed4a + FirebaseInstallations: e842042ec6ac1fd2e37d7706363ebe7f662afea4 + FirebaseMessaging: 9bc34a98d2e0237e1b121915120d4d48ddcf301e Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854 flutter_local_notifications: 0c0b1ae97e741e1521e4c1629a459d04b9aec743 - flutter_timezone: ffb07bdad3c6276af8dada0f11978d8a1f8a20bb + flutter_native_splash: 52501b97d1c0a5f898d687f1646226c1f93c56ef + geocoding_ios: a389ea40f6f548de6e63006a2e31bf66ff80769a geolocator_apple: cc556e6844d508c95df1e87e3ea6fa4e58c50401 + google_sign_in_ios: 1256ff9d941db546373826966720b0c24804bcdd + GoogleDataTransport: 54dee9d48d14580407f8f5fbf2f496e92437a2f2 + GoogleSignIn: 5651ce3a61e56ca864160e79b484cd9ed3f49b7a + GoogleUtilities: 0759d1a57ebb953965c2dfe0ba4c82e95ccc2e34 + GTMAppAuth: 0ff230db599948a9ad7470ca667337803b3fc4dd + GTMSessionFetcher: 3a63d75eecd6aa32c2fc79f578064e1214dfdec2 HTTPParserC: aea14c3d2d4ac5beb3988781daa36dfa62e0d9ef + nanopb: d4d75c12cd1316f4a64e3c6963f879ecd4b5e0d5 patrol: 792c0bb6cc4d552fc8b37f49266341c39e659b4d permission_handler_apple: e76247795d700c14ea09e3a2d8855d41ee80a2e6 + PromisesObjC: c50d2056b5253dadbd6c2bea79b0674bd5a52fa4 + RecaptchaInterop: 7d1a4a01a6b2cb1610a47ef3f85f0c411434cb21 Telegraph: 12576b119324138e4929792af9e5a1085c2ecbc1 - webview_flutter_wkwebview: 2e2d318f21a5e036e2c3f26171342e95908bd60a -PODFILE CHECKSUM: b2bb71756d032256bcb4043384dd40772d5e6a93 +PODFILE CHECKSUM: a2f999e8fe2642046eaa22133617aca7cd25a681 COCOAPODS: 1.14.2 diff --git a/packages/patrol/example/ios/Runner.xcodeproj/project.pbxproj b/packages/patrol/example/ios/Runner.xcodeproj/project.pbxproj index de113a8ae..cdfeb877f 100644 --- a/packages/patrol/example/ios/Runner.xcodeproj/project.pbxproj +++ b/packages/patrol/example/ios/Runner.xcodeproj/project.pbxproj @@ -8,26 +8,19 @@ /* Begin PBXBuildFile section */ 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; + 1E78C839FE2BE0BF82D354A0 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 5A4E6FEAE8203E3593674CFC /* GoogleService-Info.plist */; }; 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; - 6090F033F64EF2E6EC73E939 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B67A70BD9498C1A200C5D078 /* Pods_Runner.framework */; }; + 6A40764D89464B1109ECAF08 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D978CC248F4B0FE33F0F963 /* Pods_Runner.framework */; }; 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 */; }; - 983964DC2978A956007EB76F /* RunnerUITests.m in Sources */ = {isa = PBXBuildFile; fileRef = 983964DB2978A956007EB76F /* RunnerUITests.m */; }; - 9862560529F9A72100B267FA /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9862560429F9A72100B267FA /* RunnerTests.swift */; }; - FA27315210C24EEDF8E3A8C2 /* Pods_Runner_RunnerUITests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 93E89E9CC733F51B93EF71E1 /* Pods_Runner_RunnerUITests.framework */; }; + 9835C3BA2AEBE2B200AD4576 /* RunnerUITests.m in Sources */ = {isa = PBXBuildFile; fileRef = 9835C3B92AEBE2B200AD4576 /* RunnerUITests.m */; }; + C4CD80A2806BBA53CC4676D4 /* Pods_Runner_RunnerUITests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 77B0713DC63135B5488A774E /* Pods_Runner_RunnerUITests.framework */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ - 983964DF2978A956007EB76F /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 97C146E61CF9000F007C117D /* Project object */; - proxyType = 1; - remoteGlobalIDString = 97C146ED1CF9000F007C117D; - remoteInfo = Runner; - }; - 9862560629F9A72100B267FA /* PBXContainerItemProxy */ = { + 9835C3BD2AEBE2B200AD4576 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 97C146E61CF9000F007C117D /* Project object */; proxyType = 1; @@ -50,18 +43,27 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ - 039FF0702EF7414DA773B859 /* Pods-Runner-RunnerUITests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner-RunnerUITests.profile.xcconfig"; path = "Target Support Files/Pods-Runner-RunnerUITests/Pods-Runner-RunnerUITests.profile.xcconfig"; sourceTree = ""; }; - 0CD8ADEABA35D9D53F0DF923 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; + 0A5055EBC979578B00780A25 /* Pods-Runner-RunnerUITests.release-dev.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner-RunnerUITests.release-dev.xcconfig"; path = "Target Support Files/Pods-Runner-RunnerUITests/Pods-Runner-RunnerUITests.release-dev.xcconfig"; sourceTree = ""; }; 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 = ""; }; - 2F26359F19FF5877E6D9BB4A /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; + 157D5E1918F928220379E184 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; + 1B77ED38F3CFB577B226C787 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; + 1FF748E00695D5F39485C84C /* Pods-Runner.profile-prod.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile-prod.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile-prod.xcconfig"; sourceTree = ""; }; + 2F50FCC5E7FFD7D98D9E37C0 /* Pods-Runner.debug-dev.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug-dev.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug-dev.xcconfig"; sourceTree = ""; }; + 35B0BC3EA00F65C7F5C2A2DC /* Pods-Runner.release-prod.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release-prod.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release-prod.xcconfig"; sourceTree = ""; }; 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; - 6AD63AC0BB42D464CC8ABFC5 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; - 714A2CF42B7519C44AFD56B9 /* Pods-Runner-RunnerUITests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner-RunnerUITests.debug.xcconfig"; path = "Target Support Files/Pods-Runner-RunnerUITests/Pods-Runner-RunnerUITests.debug.xcconfig"; sourceTree = ""; }; + 47449248CF084D77624EF27B /* Pods-Runner-RunnerUITests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner-RunnerUITests.release.xcconfig"; path = "Target Support Files/Pods-Runner-RunnerUITests/Pods-Runner-RunnerUITests.release.xcconfig"; sourceTree = ""; }; + 5A4E6FEAE8203E3593674CFC /* GoogleService-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; name = "GoogleService-Info.plist"; path = "Runner/GoogleService-Info.plist"; sourceTree = ""; }; + 5E424AFEDD5F54FB9C5FE6A0 /* Pods-Runner-RunnerUITests.debug-dev.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner-RunnerUITests.debug-dev.xcconfig"; path = "Target Support Files/Pods-Runner-RunnerUITests/Pods-Runner-RunnerUITests.debug-dev.xcconfig"; sourceTree = ""; }; + 68BCEFDE4A146CA3EAEBE287 /* Pods-Runner.debug-prod.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug-prod.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug-prod.xcconfig"; sourceTree = ""; }; + 6D978CC248F4B0FE33F0F963 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 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 = ""; }; + 77B0713DC63135B5488A774E /* Pods_Runner_RunnerUITests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner_RunnerUITests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 78A9D202DA29B01CE316DDD8 /* Pods-Runner-RunnerUITests.debug-prod.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner-RunnerUITests.debug-prod.xcconfig"; path = "Target Support Files/Pods-Runner-RunnerUITests/Pods-Runner-RunnerUITests.debug-prod.xcconfig"; sourceTree = ""; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; - 93E89E9CC733F51B93EF71E1 /* Pods_Runner_RunnerUITests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner_RunnerUITests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 8320DBCBECD26EFBD206E3F7 /* Pods-Runner.release-dev.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release-dev.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release-dev.xcconfig"; sourceTree = ""; }; + 89F42EDB7AA949A94DDF3483 /* Pods-Runner-RunnerUITests.release-prod.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner-RunnerUITests.release-prod.xcconfig"; path = "Target Support Files/Pods-Runner-RunnerUITests/Pods-Runner-RunnerUITests.release-prod.xcconfig"; 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; }; @@ -69,13 +71,15 @@ 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 = ""; }; - 983964D92978A956007EB76F /* RunnerUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - 983964DB2978A956007EB76F /* RunnerUITests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RunnerUITests.m; sourceTree = ""; }; - 98575F2E29FA960A00AF8421 /* RunnerTests-Bridging-Header.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "RunnerTests-Bridging-Header.h"; sourceTree = ""; }; - 9862560229F9A72100B267FA /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - 9862560429F9A72100B267FA /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = ""; }; - B447E7B3C41089DE3953018D /* Pods-Runner-RunnerUITests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner-RunnerUITests.release.xcconfig"; path = "Target Support Files/Pods-Runner-RunnerUITests/Pods-Runner-RunnerUITests.release.xcconfig"; sourceTree = ""; }; - B67A70BD9498C1A200C5D078 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 9835C3B72AEBE2B200AD4576 /* RunnerUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 9835C3B92AEBE2B200AD4576 /* RunnerUITests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RunnerUITests.m; sourceTree = ""; }; + AA67FAE78E5508E1099965A5 /* Pods-Runner.profile-dev.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile-dev.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile-dev.xcconfig"; sourceTree = ""; }; + B25051AE2A914DEB002AB245 /* Runner.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Runner.entitlements; sourceTree = ""; }; + B49FBE2F1B8BD809F01F6970 /* Pods-Runner-RunnerUITests.profile-prod.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner-RunnerUITests.profile-prod.xcconfig"; path = "Target Support Files/Pods-Runner-RunnerUITests/Pods-Runner-RunnerUITests.profile-prod.xcconfig"; sourceTree = ""; }; + CFBBF813CD43D6EB929AB2B6 /* Pods-Runner-RunnerUITests.profile-dev.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner-RunnerUITests.profile-dev.xcconfig"; path = "Target Support Files/Pods-Runner-RunnerUITests/Pods-Runner-RunnerUITests.profile-dev.xcconfig"; sourceTree = ""; }; + E740F02DB75B59873B10F97B /* Pods-Runner-RunnerUITests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner-RunnerUITests.debug.xcconfig"; path = "Target Support Files/Pods-Runner-RunnerUITests/Pods-Runner-RunnerUITests.debug.xcconfig"; sourceTree = ""; }; + EDCD1D890C833F4AC9A7EB0C /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; + FD73CFB3D4A1A089A124EDA8 /* Pods-Runner-RunnerUITests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner-RunnerUITests.profile.xcconfig"; path = "Target Support Files/Pods-Runner-RunnerUITests/Pods-Runner-RunnerUITests.profile.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -83,37 +87,42 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 6090F033F64EF2E6EC73E939 /* Pods_Runner.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 983964D62978A956007EB76F /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - FA27315210C24EEDF8E3A8C2 /* Pods_Runner_RunnerUITests.framework in Frameworks */, + 6A40764D89464B1109ECAF08 /* Pods_Runner.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; - 986255FF29F9A72100B267FA /* Frameworks */ = { + 9835C3B42AEBE2B200AD4576 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + C4CD80A2806BBA53CC4676D4 /* Pods_Runner_RunnerUITests.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ - 71514460146D120DA8711EC5 /* Pods */ = { + 4BFB9CE428BED72E658E9FCC /* Pods */ = { isa = PBXGroup; children = ( - 6AD63AC0BB42D464CC8ABFC5 /* Pods-Runner.debug.xcconfig */, - 0CD8ADEABA35D9D53F0DF923 /* Pods-Runner.release.xcconfig */, - 2F26359F19FF5877E6D9BB4A /* Pods-Runner.profile.xcconfig */, - 714A2CF42B7519C44AFD56B9 /* Pods-Runner-RunnerUITests.debug.xcconfig */, - B447E7B3C41089DE3953018D /* Pods-Runner-RunnerUITests.release.xcconfig */, - 039FF0702EF7414DA773B859 /* Pods-Runner-RunnerUITests.profile.xcconfig */, + EDCD1D890C833F4AC9A7EB0C /* Pods-Runner.debug.xcconfig */, + 1B77ED38F3CFB577B226C787 /* Pods-Runner.release.xcconfig */, + 157D5E1918F928220379E184 /* Pods-Runner.profile.xcconfig */, + 68BCEFDE4A146CA3EAEBE287 /* Pods-Runner.debug-prod.xcconfig */, + 2F50FCC5E7FFD7D98D9E37C0 /* Pods-Runner.debug-dev.xcconfig */, + 35B0BC3EA00F65C7F5C2A2DC /* Pods-Runner.release-prod.xcconfig */, + 8320DBCBECD26EFBD206E3F7 /* Pods-Runner.release-dev.xcconfig */, + 1FF748E00695D5F39485C84C /* Pods-Runner.profile-prod.xcconfig */, + AA67FAE78E5508E1099965A5 /* Pods-Runner.profile-dev.xcconfig */, + 78A9D202DA29B01CE316DDD8 /* Pods-Runner-RunnerUITests.debug-prod.xcconfig */, + 5E424AFEDD5F54FB9C5FE6A0 /* Pods-Runner-RunnerUITests.debug-dev.xcconfig */, + 89F42EDB7AA949A94DDF3483 /* Pods-Runner-RunnerUITests.release-prod.xcconfig */, + 0A5055EBC979578B00780A25 /* Pods-Runner-RunnerUITests.release-dev.xcconfig */, + B49FBE2F1B8BD809F01F6970 /* Pods-Runner-RunnerUITests.profile-prod.xcconfig */, + CFBBF813CD43D6EB929AB2B6 /* Pods-Runner-RunnerUITests.profile-dev.xcconfig */, + E740F02DB75B59873B10F97B /* Pods-Runner-RunnerUITests.debug.xcconfig */, + 47449248CF084D77624EF27B /* Pods-Runner-RunnerUITests.release.xcconfig */, + FD73CFB3D4A1A089A124EDA8 /* Pods-Runner-RunnerUITests.profile.xcconfig */, ); path = Pods; sourceTree = ""; @@ -134,11 +143,11 @@ children = ( 9740EEB11CF90186004384FC /* Flutter */, 97C146F01CF9000F007C117D /* Runner */, - 983964DA2978A956007EB76F /* RunnerUITests */, - 9862560329F9A72100B267FA /* RunnerTests */, + 9835C3B82AEBE2B200AD4576 /* RunnerUITests */, 97C146EF1CF9000F007C117D /* Products */, - 71514460146D120DA8711EC5 /* Pods */, - E54C552FCC7A91D75B1E4F09 /* Frameworks */, + 4BFB9CE428BED72E658E9FCC /* Pods */, + DC071F6FA63E917403D662C6 /* Frameworks */, + 5A4E6FEAE8203E3593674CFC /* GoogleService-Info.plist */, ); sourceTree = ""; }; @@ -146,8 +155,7 @@ isa = PBXGroup; children = ( 97C146EE1CF9000F007C117D /* Runner.app */, - 983964D92978A956007EB76F /* RunnerUITests.xctest */, - 9862560229F9A72100B267FA /* RunnerTests.xctest */, + 9835C3B72AEBE2B200AD4576 /* RunnerUITests.xctest */, ); name = Products; sourceTree = ""; @@ -155,6 +163,7 @@ 97C146F01CF9000F007C117D /* Runner */ = { isa = PBXGroup; children = ( + B25051AE2A914DEB002AB245 /* Runner.entitlements */, 97C146FA1CF9000F007C117D /* Main.storyboard */, 97C146FD1CF9000F007C117D /* Assets.xcassets */, 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, @@ -167,28 +176,19 @@ path = Runner; sourceTree = ""; }; - 983964DA2978A956007EB76F /* RunnerUITests */ = { + 9835C3B82AEBE2B200AD4576 /* RunnerUITests */ = { isa = PBXGroup; children = ( - 983964DB2978A956007EB76F /* RunnerUITests.m */, + 9835C3B92AEBE2B200AD4576 /* RunnerUITests.m */, ); path = RunnerUITests; sourceTree = ""; }; - 9862560329F9A72100B267FA /* RunnerTests */ = { + DC071F6FA63E917403D662C6 /* Frameworks */ = { isa = PBXGroup; children = ( - 98575F2E29FA960A00AF8421 /* RunnerTests-Bridging-Header.h */, - 9862560429F9A72100B267FA /* RunnerTests.swift */, - ); - path = RunnerTests; - sourceTree = ""; - }; - E54C552FCC7A91D75B1E4F09 /* Frameworks */ = { - isa = PBXGroup; - children = ( - B67A70BD9498C1A200C5D078 /* Pods_Runner.framework */, - 93E89E9CC733F51B93EF71E1 /* Pods_Runner_RunnerUITests.framework */, + 6D978CC248F4B0FE33F0F963 /* Pods_Runner.framework */, + 77B0713DC63135B5488A774E /* Pods_Runner_RunnerUITests.framework */, ); name = Frameworks; sourceTree = ""; @@ -200,14 +200,14 @@ isa = PBXNativeTarget; buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; buildPhases = ( - 01FBF9092C877C4910CAC196 /* [CP] Check Pods Manifest.lock */, - 9740EEB61CF901F6004384FC /* xcode_backend build */, + 3AF1BFB546C851787D470561 /* [CP] Check Pods Manifest.lock */, + 9740EEB61CF901F6004384FC /* Run Script */, 97C146EA1CF9000F007C117D /* Sources */, 97C146EB1CF9000F007C117D /* Frameworks */, 97C146EC1CF9000F007C117D /* Resources */, 9705A1C41CF9048500538489 /* Embed Frameworks */, - 3B06AD1E1E4923F5004D2608 /* xcode_backend embed_and_thin */, - E621EC4C03882F1FC407353C /* [CP] Embed Pods Frameworks */, + 3B06AD1E1E4923F5004D2608 /* Thin Binary */, + 2FC8CE8F8BE785A6FA42F3C6 /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); @@ -218,53 +218,32 @@ productReference = 97C146EE1CF9000F007C117D /* Runner.app */; productType = "com.apple.product-type.application"; }; - 983964D82978A956007EB76F /* RunnerUITests */ = { + 9835C3B62AEBE2B200AD4576 /* RunnerUITests */ = { isa = PBXNativeTarget; - buildConfigurationList = 983964E12978A956007EB76F /* Build configuration list for PBXNativeTarget "RunnerUITests" */; + buildConfigurationList = 9835C3C52AEBE2B200AD4576 /* Build configuration list for PBXNativeTarget "RunnerUITests" */; buildPhases = ( - CCBA4E2120CD0A4549A78A05 /* [CP] Check Pods Manifest.lock */, - 983964E62978A9F4007EB76F /* xcode_backend build */, - 983964D52978A956007EB76F /* Sources */, - 983964D62978A956007EB76F /* Frameworks */, - 983964D72978A956007EB76F /* Resources */, - 983964E52978A9D4007EB76F /* xcode_backend embed_and_thin */, - FB0F1ED3C61A5044791AC712 /* [CP] Embed Pods Frameworks */, + 6DD48773736CF13259607197 /* [CP] Check Pods Manifest.lock */, + 9835C3B32AEBE2B200AD4576 /* Sources */, + 9835C3B42AEBE2B200AD4576 /* Frameworks */, + 9835C3B52AEBE2B200AD4576 /* Resources */, + FFE213DE21216A1B3F16BFE9 /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); dependencies = ( - 983964E02978A956007EB76F /* PBXTargetDependency */, + 9835C3BE2AEBE2B200AD4576 /* PBXTargetDependency */, ); name = RunnerUITests; productName = RunnerUITests; - productReference = 983964D92978A956007EB76F /* RunnerUITests.xctest */; + productReference = 9835C3B72AEBE2B200AD4576 /* RunnerUITests.xctest */; productType = "com.apple.product-type.bundle.ui-testing"; }; - 9862560129F9A72100B267FA /* RunnerTests */ = { - isa = PBXNativeTarget; - buildConfigurationList = 9862560B29F9A72100B267FA /* Build configuration list for PBXNativeTarget "RunnerTests" */; - buildPhases = ( - 986255FE29F9A72100B267FA /* Sources */, - 986255FF29F9A72100B267FA /* Frameworks */, - 9862560029F9A72100B267FA /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - 9862560729F9A72100B267FA /* PBXTargetDependency */, - ); - name = RunnerTests; - productName = RunnerTests; - productReference = 9862560229F9A72100B267FA /* RunnerTests.xctest */; - productType = "com.apple.product-type.bundle.unit-test"; - }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ 97C146E61CF9000F007C117D /* Project object */ = { isa = PBXProject; attributes = { - LastSwiftUpdateCheck = 1430; LastUpgradeCheck = 1430; ORGANIZATIONNAME = ""; TargetAttributes = { @@ -272,15 +251,10 @@ CreatedOnToolsVersion = 7.3.1; LastSwiftMigration = 1100; }; - 983964D82978A956007EB76F = { + 9835C3B62AEBE2B200AD4576 = { CreatedOnToolsVersion = 14.2; TestTargetID = 97C146ED1CF9000F007C117D; }; - 9862560129F9A72100B267FA = { - CreatedOnToolsVersion = 14.3; - LastSwiftMigration = 1430; - TestTargetID = 97C146ED1CF9000F007C117D; - }; }; }; buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; @@ -297,8 +271,7 @@ projectRoot = ""; targets = ( 97C146ED1CF9000F007C117D /* Runner */, - 983964D82978A956007EB76F /* RunnerUITests */, - 9862560129F9A72100B267FA /* RunnerTests */, + 9835C3B62AEBE2B200AD4576 /* RunnerUITests */, ); }; /* End PBXProject section */ @@ -312,17 +285,11 @@ 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, + 1E78C839FE2BE0BF82D354A0 /* GoogleService-Info.plist in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 983964D72978A956007EB76F /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 9862560029F9A72100B267FA /* Resources */ = { + 9835C3B52AEBE2B200AD4576 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( @@ -332,57 +299,24 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ - 01FBF9092C877C4910CAC196 /* [CP] Check Pods Manifest.lock */ = { + 2FC8CE8F8BE785A6FA42F3C6 /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; + name = "[CP] Embed Pods Frameworks"; outputFileListPaths = ( - ); - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; - 3B06AD1E1E4923F5004D2608 /* xcode_backend embed_and_thin */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "xcode_backend embed_and_thin"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "echo \"Runner xcode_backend embed_and_thin\"\n/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin\n"; - }; - 9740EEB61CF901F6004384FC /* xcode_backend build */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "xcode_backend build"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "echo \"Runner xcode_backend build\"\n/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build\n"; - }; - 983964E52978A9D4007EB76F /* xcode_backend embed_and_thin */ = { + 3AF1BFB546C851787D470561 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -390,35 +324,37 @@ inputFileListPaths = ( ); inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", ); - name = "xcode_backend embed_and_thin"; + name = "[CP] Check Pods Manifest.lock"; outputFileListPaths = ( ); outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "echo \"RunnerUITests xcode_backend embed_and_thin\"\n/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin\n"; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; }; - 983964E62978A9F4007EB76F /* xcode_backend build */ = { + 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; buildActionMask = 2147483647; files = ( ); - inputFileListPaths = ( - ); inputPaths = ( + "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}", ); - name = "xcode_backend build"; - outputFileListPaths = ( - ); + name = "Thin Binary"; outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "echo \"RunnerUITests xcode_backend build\"\n/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build\n"; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin\n"; }; - CCBA4E2120CD0A4549A78A05 /* [CP] Check Pods Manifest.lock */ = { + 6DD48773736CF13259607197 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -440,24 +376,22 @@ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; - E621EC4C03882F1FC407353C /* [CP] Embed Pods Frameworks */ = { + 9740EEB61CF901F6004384FC /* Run Script */ = { isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; buildActionMask = 2147483647; files = ( ); - inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", + inputPaths = ( ); - name = "[CP] Embed Pods Frameworks"; - outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", + name = "Run Script"; + outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; - showEnvVarsInLog = 0; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build\n"; }; - FB0F1ED3C61A5044791AC712 /* [CP] Embed Pods Frameworks */ = { + FFE213DE21216A1B3F16BFE9 /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -486,34 +420,21 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 983964D52978A956007EB76F /* Sources */ = { + 9835C3B32AEBE2B200AD4576 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 983964DC2978A956007EB76F /* RunnerUITests.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 986255FE29F9A72100B267FA /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 9862560529F9A72100B267FA /* RunnerTests.swift in Sources */, + 9835C3BA2AEBE2B200AD4576 /* RunnerUITests.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ - 983964E02978A956007EB76F /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 97C146ED1CF9000F007C117D /* Runner */; - targetProxy = 983964DF2978A956007EB76F /* PBXContainerItemProxy */; - }; - 9862560729F9A72100B267FA /* PBXTargetDependency */ = { + 9835C3BE2AEBE2B200AD4576 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 97C146ED1CF9000F007C117D /* Runner */; - targetProxy = 9862560629F9A72100B267FA /* PBXContainerItemProxy */; + targetProxy = 9835C3BD2AEBE2B200AD4576 /* PBXContainerItemProxy */; }; /* End PBXTargetDependency section */ @@ -537,21 +458,25 @@ /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ - 249021D3217E4FDB00AE95B9 /* Profile */ = { + 9835C3C02AEBE2B200AD4576 /* Debug */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = 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_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; @@ -560,17 +485,90 @@ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + DEVELOPMENT_TEAM = U3EG6EALX7; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + 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; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + PRODUCT_BUNDLE_IDENTIFIER = pl.leancode.patrol.Example.RunnerUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = iphoneos; + SWIFT_EMIT_LOC_STRINGS = NO; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = Runner; + }; + name = Debug; + }; + 9835C3C22AEBE2B200AD4576 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = 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_DOCUMENTATION_COMMENTS = YES; + 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_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_STYLE = Automatic; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEVELOPMENT_TEAM = U3EG6EALX7; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_C_LANGUAGE_STANDARD = gnu11; GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; @@ -578,38 +576,84 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 11.0; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = pl.leancode.patrol.Example.RunnerUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = iphoneos; - SUPPORTED_PLATFORMS = iphoneos; + SWIFT_EMIT_LOC_STRINGS = NO; TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = Runner; VALIDATE_PRODUCT = YES; }; - name = Profile; + name = Release; }; - 249021D4217E4FDB00AE95B9 /* Profile */ = { + 9835C3C42AEBE2B200AD4576 /* Profile */ = { isa = XCBuildConfiguration; baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; CLANG_ENABLE_MODULES = YES; - CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = 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_DOCUMENTATION_COMMENTS = YES; + 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_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_STYLE = Automatic; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = U3EG6EALX7; - ENABLE_BITCODE = NO; - INFOPLIST_FILE = Runner/Info.plist; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - ); - PRODUCT_BUNDLE_IDENTIFIER = pl.leancode.patrol.Example; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + 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; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = pl.leancode.patrol.Example.RunnerUITests; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; - SWIFT_VERSION = 5.0; - VERSIONING_SYSTEM = "apple-generic"; + SDKROOT = iphoneos; + SWIFT_EMIT_LOC_STRINGS = NO; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = Runner; + VALIDATE_PRODUCT = YES; }; name = Profile; }; - 97C147031CF9000F007C117D /* Debug */ = { + B2F268802A8E5F2200D757B3 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; @@ -664,7 +708,34 @@ }; name = Debug; }; - 97C147041CF9000F007C117D /* Release */ = { + B2F268812A8E5F2200D757B3 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + APP_DISPLAY_NAME = "DEV Challenge"; + 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 = U3EG6EALX7; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = pl.leancode.patrol.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; + }; + B2F268822A8E5F2A00D757B3 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; @@ -716,15 +787,18 @@ }; name = Release; }; - 97C147061CF9000F007C117D /* Debug */ = { + B2F268832A8E5F2A00D757B3 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; buildSettings = { + APP_DISPLAY_NAME = "DEV Challenge"; 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 = U3EG6EALX7; - ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", @@ -732,22 +806,75 @@ ); PRODUCT_BUNDLE_IDENTIFIER = pl.leancode.patrol.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; + name = Release; + }; + B2F268842A8E5F3000D757B3 /* Profile */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + 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; + 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 = 11.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SUPPORTED_PLATFORMS = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Profile; }; - 97C147071CF9000F007C117D /* Release */ = { + B2F268852A8E5F3000D757B3 /* Profile */ = { isa = XCBuildConfiguration; baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; buildSettings = { + APP_DISPLAY_NAME = "DEV Challenge"; 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 = U3EG6EALX7; - ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", @@ -755,176 +882,11 @@ ); PRODUCT_BUNDLE_IDENTIFIER = pl.leancode.patrol.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; - }; - 983964E22978A956007EB76F /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; - buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_TEAM = U3EG6EALX7; - GCC_C_LANGUAGE_STANDARD = gnu11; - GENERATE_INFOPLIST_FILE = YES; - MARKETING_VERSION = 1.0; - MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; - MTL_FAST_MATH = YES; - PRODUCT_BUNDLE_IDENTIFIER = pl.leancode.patrol.Example.RunnerUITests; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_EMIT_LOC_STRINGS = NO; - TARGETED_DEVICE_FAMILY = "1,2"; - TEST_TARGET_NAME = Runner; - }; - name = Debug; - }; - 983964E32978A956007EB76F /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; - buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_TEAM = U3EG6EALX7; - GCC_C_LANGUAGE_STANDARD = gnu11; - GENERATE_INFOPLIST_FILE = YES; - MARKETING_VERSION = 1.0; - MTL_FAST_MATH = YES; - PRODUCT_BUNDLE_IDENTIFIER = pl.leancode.patrol.Example.RunnerUITests; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_EMIT_LOC_STRINGS = NO; - TARGETED_DEVICE_FAMILY = "1,2"; - TEST_TARGET_NAME = Runner; - }; - name = Release; - }; - 983964E42978A956007EB76F /* Profile */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; - buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_TEAM = U3EG6EALX7; - GCC_C_LANGUAGE_STANDARD = gnu11; - GENERATE_INFOPLIST_FILE = YES; - MARKETING_VERSION = 1.0; - MTL_FAST_MATH = YES; - PRODUCT_BUNDLE_IDENTIFIER = pl.leancode.patrol.Example.RunnerUITests; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_EMIT_LOC_STRINGS = NO; - TARGETED_DEVICE_FAMILY = "1,2"; - TEST_TARGET_NAME = Runner; - }; - name = Profile; - }; - 9862560829F9A72100B267FA /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; - buildSettings = { - BUNDLE_LOADER = "$(TEST_HOST)"; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_TEAM = U3EG6EALX7; - GCC_C_LANGUAGE_STANDARD = gnu11; - GENERATE_INFOPLIST_FILE = YES; - MARKETING_VERSION = 1.0; - MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; - MTL_FAST_MATH = YES; - PRODUCT_BUNDLE_IDENTIFIER = pl.leancode.patrol.Example.RunnerTests; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; - SWIFT_EMIT_LOC_STRINGS = NO; - SWIFT_OBJC_BRIDGING_HEADER = "RunnerTests/RunnerTests-Bridging-Header.h"; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 5.0; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; - }; - name = Debug; - }; - 9862560929F9A72100B267FA /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; - buildSettings = { - BUNDLE_LOADER = "$(TEST_HOST)"; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_TEAM = U3EG6EALX7; - GCC_C_LANGUAGE_STANDARD = gnu11; - GENERATE_INFOPLIST_FILE = YES; - MARKETING_VERSION = 1.0; - MTL_FAST_MATH = YES; - PRODUCT_BUNDLE_IDENTIFIER = pl.leancode.patrol.Example.RunnerTests; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_EMIT_LOC_STRINGS = NO; - SWIFT_OBJC_BRIDGING_HEADER = "RunnerTests/RunnerTests-Bridging-Header.h"; - SWIFT_VERSION = 5.0; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; - }; - name = Release; - }; - 9862560A29F9A72100B267FA /* Profile */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; - buildSettings = { - BUNDLE_LOADER = "$(TEST_HOST)"; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_TEAM = U3EG6EALX7; - GCC_C_LANGUAGE_STANDARD = gnu11; - GENERATE_INFOPLIST_FILE = YES; - MARKETING_VERSION = 1.0; - MTL_FAST_MATH = YES; - PRODUCT_BUNDLE_IDENTIFIER = pl.leancode.patrol.Example.RunnerTests; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_EMIT_LOC_STRINGS = NO; - SWIFT_OBJC_BRIDGING_HEADER = "RunnerTests/RunnerTests-Bridging-Header.h"; - SWIFT_VERSION = 5.0; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; - }; name = Profile; }; /* End XCBuildConfiguration section */ @@ -933,9 +895,9 @@ 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { isa = XCConfigurationList; buildConfigurations = ( - 97C147031CF9000F007C117D /* Debug */, - 97C147041CF9000F007C117D /* Release */, - 249021D3217E4FDB00AE95B9 /* Profile */, + B2F268802A8E5F2200D757B3 /* Debug */, + B2F268822A8E5F2A00D757B3 /* Release */, + B2F268842A8E5F3000D757B3 /* Profile */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Debug; @@ -943,29 +905,19 @@ 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { isa = XCConfigurationList; buildConfigurations = ( - 97C147061CF9000F007C117D /* Debug */, - 97C147071CF9000F007C117D /* Release */, - 249021D4217E4FDB00AE95B9 /* Profile */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Debug; - }; - 983964E12978A956007EB76F /* Build configuration list for PBXNativeTarget "RunnerUITests" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 983964E22978A956007EB76F /* Debug */, - 983964E32978A956007EB76F /* Release */, - 983964E42978A956007EB76F /* Profile */, + B2F268812A8E5F2200D757B3 /* Debug */, + B2F268832A8E5F2A00D757B3 /* Release */, + B2F268852A8E5F3000D757B3 /* Profile */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Debug; }; - 9862560B29F9A72100B267FA /* Build configuration list for PBXNativeTarget "RunnerTests" */ = { + 9835C3C52AEBE2B200AD4576 /* Build configuration list for PBXNativeTarget "RunnerUITests" */ = { isa = XCConfigurationList; buildConfigurations = ( - 9862560829F9A72100B267FA /* Debug */, - 9862560929F9A72100B267FA /* Release */, - 9862560A29F9A72100B267FA /* Profile */, + 9835C3C02AEBE2B200AD4576 /* Debug */, + 9835C3C22AEBE2B200AD4576 /* Release */, + 9835C3C42AEBE2B200AD4576 /* Profile */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Debug; diff --git a/packages/patrol/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/packages/patrol/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index 05552f28c..97a416ad2 100644 --- a/packages/patrol/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/packages/patrol/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -1,7 +1,7 @@ + version = "1.7"> @@ -27,37 +27,12 @@ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" shouldUseLaunchSchemeArgsEnv = "YES"> - - - - - - - - - - - - - - + + + + + + diff --git a/packages/patrol/example/ios/Runner/AppDelegate.swift b/packages/patrol/example/ios/Runner/AppDelegate.swift index f778914dd..ff10bc94a 100644 --- a/packages/patrol/example/ios/Runner/AppDelegate.swift +++ b/packages/patrol/example/ios/Runner/AppDelegate.swift @@ -1,5 +1,5 @@ -import Flutter import UIKit +import Flutter @UIApplicationMain @objc class AppDelegate: FlutterAppDelegate { @@ -7,8 +7,8 @@ import UIKit _ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? ) -> Bool { - GeneratedPluginRegistrant.register(with: self) UNUserNotificationCenter.current().delegate = self as UNUserNotificationCenterDelegate + GeneratedPluginRegistrant.register(with: self) return super.application(application, didFinishLaunchingWithOptions: launchOptions) } } diff --git a/packages/patrol/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/packages/patrol/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png index dc9ada472..abb75b5ea 100644 Binary files a/packages/patrol/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png and b/packages/patrol/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png differ diff --git a/packages/patrol/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/packages/patrol/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png index 28c6bf030..c0021d1ae 100644 Binary files a/packages/patrol/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png and b/packages/patrol/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png differ diff --git a/packages/patrol/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/packages/patrol/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png index 2ccbfd967..10b40b4ac 100644 Binary files a/packages/patrol/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png and b/packages/patrol/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png differ diff --git a/packages/patrol/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/packages/patrol/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png index f091b6b0b..fcad9eebe 100644 Binary files a/packages/patrol/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png and b/packages/patrol/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png differ diff --git a/packages/patrol/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/packages/patrol/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png index 4cde12118..190242266 100644 Binary files a/packages/patrol/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png and b/packages/patrol/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png differ diff --git a/packages/patrol/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/packages/patrol/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png index d0ef06e7e..179c2c304 100644 Binary files a/packages/patrol/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png and b/packages/patrol/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png differ diff --git a/packages/patrol/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/packages/patrol/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png index dcdc2306c..e68d0017a 100644 Binary files a/packages/patrol/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png and b/packages/patrol/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png differ diff --git a/packages/patrol/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/packages/patrol/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png index 2ccbfd967..10b40b4ac 100644 Binary files a/packages/patrol/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png and b/packages/patrol/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png differ diff --git a/packages/patrol/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/packages/patrol/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png index c8f9ed8f5..062fb835e 100644 Binary files a/packages/patrol/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png and b/packages/patrol/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png differ diff --git a/packages/patrol/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/packages/patrol/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png index a6d6b8609..e19339fb2 100644 Binary files a/packages/patrol/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png and b/packages/patrol/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png differ diff --git a/packages/patrol/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@1x.png b/packages/patrol/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@1x.png new file mode 100644 index 000000000..eebd1727a Binary files /dev/null and b/packages/patrol/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@1x.png differ diff --git a/packages/patrol/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@2x.png b/packages/patrol/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@2x.png new file mode 100644 index 000000000..66737f2b4 Binary files /dev/null and b/packages/patrol/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@2x.png differ diff --git a/packages/patrol/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@1x.png b/packages/patrol/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@1x.png new file mode 100644 index 000000000..200972561 Binary files /dev/null and b/packages/patrol/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@1x.png differ diff --git a/packages/patrol/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@2x.png b/packages/patrol/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@2x.png new file mode 100644 index 000000000..c254ef308 Binary files /dev/null and b/packages/patrol/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@2x.png differ diff --git a/packages/patrol/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/packages/patrol/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png index a6d6b8609..e19339fb2 100644 Binary files a/packages/patrol/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png and b/packages/patrol/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png differ diff --git a/packages/patrol/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/packages/patrol/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png index 75b2d164a..dfe2fd092 100644 Binary files a/packages/patrol/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png and b/packages/patrol/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png differ diff --git a/packages/patrol/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@1x.png b/packages/patrol/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@1x.png new file mode 100644 index 000000000..7145e4227 Binary files /dev/null and b/packages/patrol/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@1x.png differ diff --git a/packages/patrol/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@2x.png b/packages/patrol/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@2x.png new file mode 100644 index 000000000..02476e92e Binary files /dev/null and b/packages/patrol/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@2x.png differ diff --git a/packages/patrol/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/packages/patrol/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png index c4df70d39..8c8ceac68 100644 Binary files a/packages/patrol/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png and b/packages/patrol/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png differ diff --git a/packages/patrol/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/packages/patrol/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png index 6a84f41e1..287728aaa 100644 Binary files a/packages/patrol/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png and b/packages/patrol/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png differ diff --git a/packages/patrol/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/packages/patrol/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png index d0e1f5853..43edd0f4b 100644 Binary files a/packages/patrol/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png and b/packages/patrol/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png differ diff --git a/packages/patrol/example/ios/Runner/Assets.xcassets/LaunchBackground.imageset/Contents.json b/packages/patrol/example/ios/Runner/Assets.xcassets/LaunchBackground.imageset/Contents.json new file mode 100644 index 000000000..9f447e1b3 --- /dev/null +++ b/packages/patrol/example/ios/Runner/Assets.xcassets/LaunchBackground.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "background.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/packages/patrol/example/ios/Runner/Assets.xcassets/LaunchBackground.imageset/background.png b/packages/patrol/example/ios/Runner/Assets.xcassets/LaunchBackground.imageset/background.png new file mode 100644 index 000000000..89d9ab9c5 Binary files /dev/null and b/packages/patrol/example/ios/Runner/Assets.xcassets/LaunchBackground.imageset/background.png differ diff --git a/packages/patrol/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json b/packages/patrol/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json index 0bedcf2fd..00cabce83 100644 --- a/packages/patrol/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json +++ b/packages/patrol/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json @@ -1,23 +1,23 @@ { "images" : [ { - "idiom" : "universal", "filename" : "LaunchImage.png", + "idiom" : "universal", "scale" : "1x" }, { - "idiom" : "universal", "filename" : "LaunchImage@2x.png", + "idiom" : "universal", "scale" : "2x" }, { - "idiom" : "universal", "filename" : "LaunchImage@3x.png", + "idiom" : "universal", "scale" : "3x" } ], "info" : { - "version" : 1, - "author" : "xcode" + "author" : "xcode", + "version" : 1 } } diff --git a/packages/patrol/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png b/packages/patrol/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png index 9da19eaca..e94aac8ee 100644 Binary files a/packages/patrol/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png and b/packages/patrol/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png differ diff --git a/packages/patrol/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/packages/patrol/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png index 9da19eaca..c80709495 100644 Binary files a/packages/patrol/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png and b/packages/patrol/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png differ diff --git a/packages/patrol/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/packages/patrol/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png index 9da19eaca..4c9ae4459 100644 Binary files a/packages/patrol/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png and b/packages/patrol/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png differ diff --git a/packages/patrol/example/ios/Runner/Base.lproj/LaunchScreen.storyboard b/packages/patrol/example/ios/Runner/Base.lproj/LaunchScreen.storyboard index f2e259c7c..c85151dfd 100644 --- a/packages/patrol/example/ios/Runner/Base.lproj/LaunchScreen.storyboard +++ b/packages/patrol/example/ios/Runner/Base.lproj/LaunchScreen.storyboard @@ -16,13 +16,19 @@ - - + + - - + + + + + + + + @@ -32,6 +38,7 @@ - + + diff --git a/packages/patrol/example/ios/Runner/GoogleService-Info.plist b/packages/patrol/example/ios/Runner/GoogleService-Info.plist new file mode 100644 index 000000000..8828b76ce --- /dev/null +++ b/packages/patrol/example/ios/Runner/GoogleService-Info.plist @@ -0,0 +1,36 @@ + + + + + CLIENT_ID + REMOVED.apps.googleusercontent.com + REVERSED_CLIENT_ID + com.googleusercontent.apps.REMOVED + ANDROID_CLIENT_ID + REMOVED.apps.googleusercontent.com + API_KEY + AIzaSyChw7aDlxxJBfLRDxb1qIoBXqxrJ-8_fw1 + GCM_SENDER_ID + 1814244492393 + PLIST_VERSION + 1 + BUNDLE_ID + pl.leancode.patrol.Example + PROJECT_ID + REMOVED + STORAGE_BUCKET + REMOVED.appspot.com + IS_ADS_ENABLED + + IS_ANALYTICS_ENABLED + + IS_APPINVITE_ENABLED + + IS_GCM_ENABLED + + IS_SIGNIN_ENABLED + + GOOGLE_APP_ID + 1:1984545047423:ios:ad10dafb0621e0382c8ff5 + + diff --git a/packages/patrol/example/ios/Runner/Info.plist b/packages/patrol/example/ios/Runner/Info.plist index 24a67c646..2c94a6ea1 100644 --- a/packages/patrol/example/ios/Runner/Info.plist +++ b/packages/patrol/example/ios/Runner/Info.plist @@ -2,16 +2,12 @@ - NSBonjourServices - - _dartobservatory._tcp - CADisableMinimumFrameDurationOnPhone CFBundleDevelopmentRegion $(DEVELOPMENT_LANGUAGE) CFBundleDisplayName - Example + $(APP_DISPLAY_NAME) CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier @@ -19,37 +15,43 @@ CFBundleInfoDictionaryVersion 6.0 CFBundleName - example + patrol_challenge CFBundlePackageType APPL CFBundleShortVersionString $(FLUTTER_BUILD_NAME) CFBundleSignature ???? + CFBundleURLTypes + + + CFBundleTypeRole + Editor + CFBundleURLSchemes + + com.googleusercontent.apps.161899692976-ksb464fv3r9eq3r58n35gficunijd7kv + + + CFBundleVersion $(FLUTTER_BUILD_NUMBER) + LSApplicationCategoryType + LSRequiresIPhoneOS - NSCameraUsageDescription - camera - NSContactsUsageDescription - contacts - NSLocationAlwaysAndWhenInUseUsageDescription - Always and when in use! - NSLocationAlwaysUsageDescription - Can I have location always? - NSLocationUsageDescription - Older devices need location. - NSLocationWhenInUseUsageDescription - Need location when in use - NSMicrophoneUsageDescription - microphone UIApplicationSupportsIndirectInputEvents + UIBackgroundModes + + processing + remote-notification + UILaunchStoryboardName LaunchScreen UIMainStoryboardFile Main + UIStatusBarHidden + UISupportedInterfaceOrientations UIInterfaceOrientationPortrait diff --git a/packages/patrol/example/ios/Runner/Runner.entitlements b/packages/patrol/example/ios/Runner/Runner.entitlements new file mode 100644 index 000000000..903def2af --- /dev/null +++ b/packages/patrol/example/ios/Runner/Runner.entitlements @@ -0,0 +1,8 @@ + + + + + aps-environment + development + + diff --git a/packages/patrol/example/ios/TestPlan.xctestplan b/packages/patrol/example/ios/TestPlan.xctestplan new file mode 100644 index 000000000..f7b74699a --- /dev/null +++ b/packages/patrol/example/ios/TestPlan.xctestplan @@ -0,0 +1,29 @@ +{ + "configurations" : [ + { + "id" : "939A83E4-5059-4987-9414-28779DA07207", + "name" : "Test Scheme Action", + "options" : { + + } + } + ], + "defaultOptions" : { + "codeCoverage" : false, + "targetForVariableExpansion" : { + "containerPath" : "container:Runner.xcodeproj", + "identifier" : "97C146ED1CF9000F007C117D", + "name" : "Runner" + } + }, + "testTargets" : [ + { + "target" : { + "containerPath" : "container:Runner.xcodeproj", + "identifier" : "9835C3B62AEBE2B200AD4576", + "name" : "RunnerUITests" + } + } + ], + "version" : 1 +} diff --git a/packages/patrol/example/lib/cubit/auth_cubit.dart b/packages/patrol/example/lib/cubit/auth_cubit.dart new file mode 100644 index 000000000..2123c0ae1 --- /dev/null +++ b/packages/patrol/example/lib/cubit/auth_cubit.dart @@ -0,0 +1,90 @@ +import 'dart:async'; + +import 'package:firebase_auth/firebase_auth.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:google_sign_in/google_sign_in.dart'; + +class AuthCubit extends Cubit { + AuthCubit(this._firebaseAuth, this._googleSignIn) : super(AuthStateLoading()); + + final FirebaseAuth? _firebaseAuth; + final GoogleSignIn? _googleSignIn; + late final StreamSubscription _authStateChangesSubscription; + + void init() { + if (_firebaseAuth == null || _googleSignIn == null) { + emit(AuthStateUnauthenticated()); + return; + } + + final user = _firebaseAuth.currentUser; + _emitAuthState(user); + + _authStateChangesSubscription = + _firebaseAuth.authStateChanges().listen(_emitAuthState); + } + + void _emitAuthState(User? user) { + if (user == null) { + emit(AuthStateUnauthenticated()); + } else { + emit(AuthStateAuthenticated(user)); + } + } + + Future signInWithGoogle() async { + if (_firebaseAuth == null || _googleSignIn == null) { + return; + } + + emit(AuthStateLoading()); + try { + final googleUser = await _googleSignIn.signIn(); + + final googleAuth = await googleUser?.authentication; + + final credential = GoogleAuthProvider.credential( + accessToken: googleAuth?.accessToken, + idToken: googleAuth?.idToken, + ); + + await _firebaseAuth.signInWithCredential(credential); + } catch (err) { + emit(AuthStateUnauthenticated(showError: true)); + emit(AuthStateUnauthenticated()); + } + } + + Future signOut() async { + if (_firebaseAuth == null || _googleSignIn == null) { + return; + } + + await _googleSignIn.signOut(); + await _firebaseAuth.signOut(); + } + + @override + Future close() { + _authStateChangesSubscription.cancel(); + return super.close(); + } +} + +@immutable +sealed class AuthState {} + +final class AuthStateLoading extends AuthState {} + +final class AuthStateAuthenticated extends AuthState { + AuthStateAuthenticated(this.user); + + final User user; +} + +final class AuthStateUnauthenticated extends AuthState { + AuthStateUnauthenticated({this.showError = false}); + + final bool showError; +} diff --git a/packages/patrol/example/lib/firebase_options.dart b/packages/patrol/example/lib/firebase_options.dart new file mode 100644 index 000000000..e47f3467b --- /dev/null +++ b/packages/patrol/example/lib/firebase_options.dart @@ -0,0 +1,70 @@ +// File generated by FlutterFire CLI. ignore_for_file: +// lines_longer_than_80_chars, avoid_classes_with_only_static_members +import 'package:firebase_core/firebase_core.dart' show FirebaseOptions; +import 'package:flutter/foundation.dart' + show TargetPlatform, defaultTargetPlatform, kIsWeb; + +/// Default [FirebaseOptions] for use with your Firebase apps. +/// +/// Example: +/// ```dart +/// import 'firebase_options.dart'; +/// // ... +/// await Firebase.initializeApp( +/// options: DefaultFirebaseOptions.currentPlatform, +/// ); +/// ``` +class DefaultFirebaseOptions { + static FirebaseOptions get currentPlatform { + if (kIsWeb) { + throw UnsupportedError( + 'DefaultFirebaseOptions have not been configured for web - ' + 'you can reconfigure this by running the FlutterFire CLI again.', + ); + } + switch (defaultTargetPlatform) { + case TargetPlatform.android: + return android; + case TargetPlatform.iOS: + return ios; + case TargetPlatform.macOS: + throw UnsupportedError( + 'DefaultFirebaseOptions have not been configured for macos - ' + 'you can reconfigure this by running the FlutterFire CLI again.', + ); + case TargetPlatform.windows: + throw UnsupportedError( + 'DefaultFirebaseOptions have not been configured for windows - ' + 'you can reconfigure this by running the FlutterFire CLI again.', + ); + case TargetPlatform.linux: + throw UnsupportedError( + 'DefaultFirebaseOptions have not been configured for linux - ' + 'you can reconfigure this by running the FlutterFire CLI again.', + ); + default: + throw UnsupportedError( + 'DefaultFirebaseOptions are not supported for this platform.', + ); + } + } + + static const FirebaseOptions android = FirebaseOptions( + apiKey: '', + appId: '', + messagingSenderId: '', + projectId: 'patrol-poc', + storageBucket: '', + ); + + static const FirebaseOptions ios = FirebaseOptions( + apiKey: '', + appId: '', + messagingSenderId: '', + projectId: 'patrol-poc', + storageBucket: '', + androidClientId: '', + iosClientId: '', + iosBundleId: 'com.example.patrolConf', + ); +} diff --git a/packages/patrol/example/lib/handlers/notification_handler.dart b/packages/patrol/example/lib/handlers/notification_handler.dart new file mode 100644 index 000000000..af976f9ca --- /dev/null +++ b/packages/patrol/example/lib/handlers/notification_handler.dart @@ -0,0 +1,124 @@ +import 'dart:async'; +import 'dart:convert'; + +import 'package:example/handlers/permission_handler.dart'; +import 'package:example/ui/style/colors.dart'; +import 'package:firebase_messaging/firebase_messaging.dart'; +import 'package:flutter/foundation.dart'; +import 'package:flutter_local_notifications/flutter_local_notifications.dart'; +import 'package:http/http.dart' as http; +import 'package:permission_handler/permission_handler.dart'; + +class NotificationHandler { + NotificationHandler( + this._flutterLocalNotificationsPlugin, + this._firebaseMessaging, + ); + + final FlutterLocalNotificationsPlugin _flutterLocalNotificationsPlugin; + final FirebaseMessaging? _firebaseMessaging; + + Future init(VoidCallback onNotificationTap) async { + await _init(onNotificationTap); + final token = await _firebaseMessaging?.getToken(); + debugPrint('Device FCM token: $token'); + _listenForPushNotifications(); + } + + Future _init(VoidCallback onNotificationTap) async { + await _flutterLocalNotificationsPlugin.initialize( + const InitializationSettings( + android: AndroidInitializationSettings('notification_icon'), + iOS: DarwinInitializationSettings( + requestAlertPermission: false, + requestBadgePermission: false, + requestSoundPermission: false, + ), + ), + onDidReceiveNotificationResponse: (_) => onNotificationTap(), + ); + await _firebaseMessaging?.setForegroundNotificationPresentationOptions( + alert: true, + badge: true, + sound: true, + ); + } + + Future _requestPermission() async { + final permissionStatus = await PermissionHandler.requestPermissions(); + return switch (permissionStatus) { + PermissionStatus.granted => true, + _ => false, + }; + } + + Future triggerLocalNotification({ + required VoidCallback onPressed, + required VoidCallback onError, + }) async { + final hasPermission = await _requestPermission(); + if (!hasPermission) { + onError(); + return; + } + await _init(onPressed); + await _showNotification(title: 'Tap me to finish the quiz!'); + } + + Future triggerPushNotification({ + required VoidCallback onPressed, + }) async { + final hasPermission = await _requestPermission(); + if (!hasPermission) { + return; + } + await _init(onPressed); + final fcmToken = await _firebaseMessaging?.getToken(); + await http.post( + Uri.parse( + 'https://us-central1-patrol-poc.cloudfunctions.net/sendNotification', + ), + headers: {'Content-Type': 'application/json'}, + body: jsonEncode({'token': fcmToken}), + ); + } + + void _listenForPushNotifications() { + if (_firebaseMessaging == null) { + return; + } + + FirebaseMessaging.onMessage.listen((message) { + if (message.notification != null) { + final notification = message.notification; + _showNotification( + title: notification?.title ?? '', + body: notification?.body, + ); + } + }); + } + + Future _showNotification({ + required String title, + String? body, + }) async { + const details = NotificationDetails( + android: AndroidNotificationDetails( + 'patrolChallengeChannelId', + 'patrolChallengeChannel', + importance: Importance.max, + priority: Priority.high, + color: PTColors.lcBlack, + ), + iOS: DarwinNotificationDetails( + presentAlert: true, + presentBadge: true, + presentSound: true, + interruptionLevel: InterruptionLevel.active, + ), + ); + + return _flutterLocalNotificationsPlugin.show(0, title, body, details); + } +} diff --git a/packages/patrol/example/lib/handlers/permission_handler.dart b/packages/patrol/example/lib/handlers/permission_handler.dart new file mode 100644 index 000000000..24f6122c3 --- /dev/null +++ b/packages/patrol/example/lib/handlers/permission_handler.dart @@ -0,0 +1,13 @@ +import 'package:permission_handler/permission_handler.dart'; + +class PermissionHandler { + static Future requestPermissions() async { + var status = await Permission.notification.status; + + if (status != PermissionStatus.granted) { + status = await Permission.notification.request(); + } + + return status; + } +} diff --git a/packages/patrol/example/lib/main.dart b/packages/patrol/example/lib/main.dart index 1c378b738..69769eabe 100644 --- a/packages/patrol/example/lib/main.dart +++ b/packages/patrol/example/lib/main.dart @@ -1,249 +1,96 @@ +import 'package:animations/animations.dart'; +import 'package:example/cubit/auth_cubit.dart'; +import 'package:example/firebase_options.dart'; +import 'package:example/handlers/notification_handler.dart'; +import 'package:example/pages/home_page.dart'; +import 'package:example/pages/push_notification/notification_success_page.dart'; +import 'package:example/ui/style/colors.dart'; +import 'package:firebase_auth/firebase_auth.dart'; +import 'package:firebase_core/firebase_core.dart'; +import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:flutter/material.dart'; -import 'package:flutter_timezone/flutter_timezone.dart'; -import 'package:patrol_example/loading_screen.dart'; -import 'package:patrol_example/location_screen.dart'; -import 'package:patrol_example/notifications_screen.dart'; -import 'package:patrol_example/overlay_screen.dart'; -import 'package:patrol_example/permissions_screen.dart'; -import 'package:patrol_example/scrolling_screen.dart'; -import 'package:patrol_example/webview_screen.dart'; -import 'package:timezone/data/latest.dart' as tz_data; -import 'package:timezone/timezone.dart' as tz; +import 'package:flutter/services.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_local_notifications/flutter_local_notifications.dart'; +import 'package:geolocator/geolocator.dart'; +import 'package:google_sign_in/google_sign_in.dart'; +import 'package:provider/provider.dart'; -Future main() async { - WidgetsFlutterBinding.ensureInitialized(); - await setUpTimezone(); +const firebaseEnabled = String.fromEnvironment('FIREBASE_ENABLED') == 'true'; - runApp(const ExampleApp()); -} +void main() async { + WidgetsFlutterBinding.ensureInitialized(); + await initApp(); + debugPrint('!Google sign in will not work when dev flavor used!'); -Future setUpTimezone() async { - tz_data.initializeTimeZones(); - final timezone = await FlutterTimezone.getLocalTimezone(); - final location = tz.getLocation(timezone); - tz.setLocalLocation(location); + runApp(const MyApp()); } -class ExampleApp extends StatelessWidget { - const ExampleApp({super.key}); +Future initApp() async { + _setUpTheme(); - @override - Widget build(BuildContext context) { - return MaterialApp( - title: 'Flutter Demo', - darkTheme: ThemeData( - primarySwatch: Colors.blue, - brightness: Brightness.dark, - ), - theme: ThemeData( - primarySwatch: Colors.blue, - brightness: Brightness.light, - ), - home: const ExampleHomePage(title: 'Flutter Demo Home Page'), - ); + if (firebaseEnabled) { + await _initFirebase(); } + await _askForLocationPermission(); } -class ExampleHomePage extends StatefulWidget { - const ExampleHomePage({super.key, required this.title}); - - final String title; +void _setUpTheme() { + final mySystemTheme = SystemUiOverlayStyle.light + .copyWith(systemNavigationBarColor: PTColors.lcBlack); - @override - State createState() => _ExampleHomePageState(); + SystemChrome.setSystemUIOverlayStyle(mySystemTheme); } -class _ExampleHomePageState extends State { - var _counter = 0; +Future _initFirebase() async { + await Firebase.initializeApp( + options: DefaultFirebaseOptions.currentPlatform, + ); +} - void _incrementCounter([int value = 1]) { - final newValue = _counter + value; - setState(() { - _counter = newValue; - }); - } +Future _askForLocationPermission() => Geolocator.requestPermission(); - void _decrementCounter([int value = 1]) { - final newValue = _counter - value; - setState(() { - _counter = newValue; - }); - } +class MyApp extends StatelessWidget { + const MyApp({super.key}); @override Widget build(BuildContext context) { - return Scaffold( - key: const Key('scaffold'), - appBar: AppBar( - title: Text(widget.title), - ), - body: ListView( - padding: EdgeInsets.all(8), - key: const Key('listViewKey'), - children: [ - const Text( - 'You have pushed the button this many times:', - ), - Text( - '$_counter', - key: const Key('counterText'), - style: Theme.of(context).textTheme.headlineMedium, - ), - const TextField( - key: Key('textField'), - decoration: InputDecoration( - border: OutlineInputBorder(), - hintText: 'You have entered this text', - ), - ), - SizedBox(height: 8), - Container( - key: const Key('box1'), - color: Theme.of(context).colorScheme.background, - padding: const EdgeInsets.all(8), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const Text('box 1'), - ListTile( - onTap: () => _incrementCounter(10), - key: const Key('tile1'), - title: const Text('Add'), - trailing: IconButton( - icon: const Icon(Icons.add, key: Key('icon1')), - onPressed: _incrementCounter, - ), + return BlocProvider( + create: (context) => AuthCubit( + firebaseEnabled ? FirebaseAuth.instance : null, + firebaseEnabled ? GoogleSignIn() : null, + )..init(), + child: Provider( + lazy: false, + create: (_) => NotificationHandler( + FlutterLocalNotificationsPlugin(), + firebaseEnabled ? FirebaseMessaging.instance : null, + )..init(() => Navigator.push(context, notificationRoute)), + child: MaterialApp( + theme: ThemeData.dark().copyWith( + pageTransitionsTheme: const PageTransitionsTheme( + builders: { + TargetPlatform.android: SharedAxisPageTransitionsBuilder( + transitionType: SharedAxisTransitionType.horizontal, ), - ListTile( - onTap: () => _decrementCounter(10), - key: const Key('tile2'), - title: const Text('Subtract'), - trailing: IconButton( - icon: const Icon(Icons.remove, key: Key('icon2')), - onPressed: _decrementCounter, - ), + TargetPlatform.iOS: SharedAxisPageTransitionsBuilder( + transitionType: SharedAxisTransitionType.horizontal, ), - ], + }, ), - ), - const SizedBox(height: 16), - Container( - key: const Key('box2'), - color: Theme.of(context).colorScheme.background, - padding: const EdgeInsets.all(8), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const Text('box 2'), - ListTile( - onTap: () => _incrementCounter(10), - key: const Key('tile1'), - title: const Text('Add'), - trailing: IconButton( - icon: const Icon(Icons.add, key: Key('icon1')), - onPressed: _incrementCounter, - ), - ), - ListTile( - onTap: () => _decrementCounter(10), - key: const Key('tile2'), - title: const Text('Subtract'), - trailing: IconButton( - icon: const Icon(Icons.remove, key: Key('icon2')), - onPressed: _decrementCounter, - ), - ), - ], + colorScheme: ColorScheme.fromSwatch(primarySwatch: Colors.grey), + primaryColor: PTColors.lcBlack, + canvasColor: PTColors.textDark, + textSelectionTheme: TextSelectionThemeData( + selectionColor: PTColors.lcYellow.withOpacity(0.5), + cursorColor: PTColors.textWhite, + selectionHandleColor: PTColors.lcYellow, ), ), - TextButton( - onPressed: () async => Navigator.of(context).push( - MaterialPageRoute( - builder: (_) => const LoadingScreen(), - ), - ), - child: const Text('Open loading screen'), - ), - TextButton( - onPressed: () async => Navigator.of(context).push( - MaterialPageRoute( - builder: (_) => const LocationScreen(), - ), - ), - child: const Text('Open location screen'), - ), - TextButton( - onPressed: () async => Navigator.of(context).push( - MaterialPageRoute( - builder: (_) => const NotificationsScreen(), - ), - ), - child: const Text('Open notifications screen'), - ), - TextButton( - onPressed: () async => Navigator.of(context).push( - MaterialPageRoute( - builder: (_) => const OverlayScreen(), - ), - ), - child: const Text('Open overlay screen'), - ), - TextButton( - onPressed: () async => Navigator.of(context).push( - MaterialPageRoute( - builder: (_) => const ScrollingScreen(), - ), - ), - child: const Text('Open scrolling screen'), - ), - TextButton( - onPressed: () async => Navigator.of(context).push( - MaterialPageRoute( - builder: (_) => const WebViewScreen( - title: 'WebView (LeanCode)', - url: 'https://leancode.co', - ), - ), - ), - child: const Text('Open webview (LeanCode)'), - ), - TextButton( - onPressed: () async => Navigator.of(context).push( - MaterialPageRoute( - builder: (_) => const WebViewScreen( - title: 'WebView (Hacker News)', - url: 'https://news.ycombinator.com', - ), - ), - ), - child: const Text('Open webview (Hacker News)'), - ), - TextButton( - onPressed: () async => Navigator.of(context).push( - MaterialPageRoute( - builder: (_) => const WebViewScreen( - title: 'WebView (StackOverflow)', - url: 'https://stackoverflow.com', - ), - ), - ), - child: const Text('Open webview (StackOverflow)'), - ), - TextButton( - onPressed: () async => Navigator.of(context).push( - MaterialPageRoute( - builder: (_) => const PermissionsScreen(), - ), - ), - child: const Text('Open permissions screen'), - ), - Text('EXAMPLE_KEY: ${const String.fromEnvironment('EXAMPLE_KEY')}'), - ], - ), - floatingActionButton: FloatingActionButton( - onPressed: _incrementCounter, - tooltip: 'Increment', - child: const Icon(Icons.add), + debugShowCheckedModeBanner: false, + title: 'Patrol Challenge', + home: const HomePage(), + ), ), ); } diff --git a/packages/patrol/example/lib/pages/google_sign_in/profile_page.dart b/packages/patrol/example/lib/pages/google_sign_in/profile_page.dart new file mode 100644 index 000000000..2eb167d82 --- /dev/null +++ b/packages/patrol/example/lib/pages/google_sign_in/profile_page.dart @@ -0,0 +1,82 @@ +import 'package:example/cubit/auth_cubit.dart'; +import 'package:example/handlers/notification_handler.dart'; +import 'package:example/pages/push_notification/notification_success_page.dart'; +import 'package:example/ui/components/scaffold.dart'; +import 'package:example/ui/style/colors.dart'; +import 'package:example/ui/style/test_style.dart'; +import 'package:firebase_auth/firebase_auth.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; + +Route get profileRoute => + MaterialPageRoute(builder: (_) => const _ProfilePage()); + +class _ProfilePage extends StatelessWidget { + const _ProfilePage(); + + @override + Widget build(BuildContext context) { + return BlocConsumer( + listener: (context, state) { + if (state case AuthStateUnauthenticated()) { + Navigator.pop(context); + } + }, + builder: (context, state) { + return SafeArea( + child: switch (state) { + AuthStateAuthenticated(:final user) => _ProfilePageBody(user: user), + _ => const SizedBox(), + }, + ); + }, + ); + } +} + +class _ProfilePageBody extends StatelessWidget { + const _ProfilePageBody({required this.user}); + + final User user; + + @override + Widget build(BuildContext context) { + return PTScaffold( + top: Align( + alignment: Alignment.centerRight, + child: Padding( + padding: const EdgeInsets.all(16), + child: IconButton( + color: PTColors.lcYellow, + icon: const Icon( + Icons.power_settings_new, + color: PTColors.lcYellow, + ), + onPressed: context.read().signOut, + ), + ), + ), + body: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + 'Welcome ${user.displayName}!', + textAlign: TextAlign.center, + style: PTTextStyles.bodyBold, + ), + const SizedBox(height: 16), + ElevatedButton( + onPressed: () => context + .read() + .triggerPushNotification( + onPressed: () => Navigator.push(context, notificationRoute), + ), + child: const Text('Notify me!'), + ), + ], + ), + ), + ); + } +} diff --git a/packages/patrol/example/lib/pages/home_page.dart b/packages/patrol/example/lib/pages/home_page.dart new file mode 100644 index 000000000..ce83a0071 --- /dev/null +++ b/packages/patrol/example/lib/pages/home_page.dart @@ -0,0 +1,87 @@ +import 'package:example/cubit/auth_cubit.dart'; +import 'package:example/handlers/notification_handler.dart'; +import 'package:example/pages/google_sign_in/profile_page.dart'; +import 'package:example/pages/push_notification/notification_success_page.dart'; +import 'package:example/pages/quiz/welcome_page.dart'; +import 'package:example/ui/components/button/elevated_button.dart'; +import 'package:example/ui/components/scaffold.dart'; +import 'package:example/ui/style/test_style.dart'; +import 'package:example/ui/widgets/utils.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; + +class HomePage extends StatelessWidget { + const HomePage({super.key}); + + @override + Widget build(BuildContext context) { + return PTScaffold( + body: BlocConsumer( + listener: (context, state) async { + if (state case AuthStateAuthenticated()) { + await Navigator.push(context, profileRoute); + } else if (state case AuthStateUnauthenticated()) { + if (state.showError) { + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar(content: Text('Login failed')), + ); + } + } + }, + builder: (context, state) { + return switch (state) { + AuthStateLoading() => const Center( + child: CircularProgressIndicator(), + ), + _ => const _HomePageBody(), + }; + }, + ), + ); + } +} + +class _HomePageBody extends StatelessWidget { + const _HomePageBody(); + + @override + Widget build(BuildContext context) { + return Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + PTElevatedButton( + caption: 'Sign In with Google', + onPressed: context.read().signInWithGoogle, + ), + const _TextSeparator(), + PTElevatedButton( + caption: 'Go to the quiz', + onPressed: () => Navigator.push(context, quizWelcomeRoute), + ), + const _TextSeparator(), + PTElevatedButton( + caption: 'Send notification', + onPressed: () => + context.read().triggerPushNotification( + onPressed: () => Navigator.push(context, notificationRoute), + ), + ), + ], + ).horizontallyPadded24; + } +} + +class _TextSeparator extends StatelessWidget { + const _TextSeparator(); + + @override + Widget build(BuildContext context) { + return Padding( + padding: const EdgeInsets.symmetric(vertical: 45), + child: Text( + 'or', + style: PTTextStyles.h4, + ), + ); + } +} diff --git a/packages/patrol/example/lib/pages/push_notification/notification_success_page.dart b/packages/patrol/example/lib/pages/push_notification/notification_success_page.dart new file mode 100644 index 000000000..1efc63eab --- /dev/null +++ b/packages/patrol/example/lib/pages/push_notification/notification_success_page.dart @@ -0,0 +1,87 @@ +import 'dart:async'; + +import 'package:confetti/confetti.dart'; +import 'package:example/ui/components/scaffold.dart'; +import 'package:example/ui/style/colors.dart'; +import 'package:flutter/material.dart'; +import 'package:geocoding/geocoding.dart'; +import 'package:geolocator/geolocator.dart'; + +Route get notificationRoute => + MaterialPageRoute(builder: (_) => const _NotificationSuccessPage()); + +class _NotificationSuccessPage extends StatefulWidget { + const _NotificationSuccessPage(); + + @override + State<_NotificationSuccessPage> createState() => + _NotificationSuccessPageState(); +} + +class _NotificationSuccessPageState extends State<_NotificationSuccessPage> { + late ConfettiController _confettiController; + late final StreamSubscription _locationStream; + String _location = ''; + + @override + void initState() { + super.initState(); + _confettiController = ConfettiController( + duration: const Duration(seconds: 10), + ); + _locationStream = Geolocator.getPositionStream().listen(_onPositionUpdated); + } + + @override + Widget build(BuildContext context) { + return PTScaffold( + top: AppBar( + backgroundColor: PTColors.textDark, + elevation: 0, + leading: IconButton( + icon: const Icon(Icons.arrow_back, color: PTColors.lcWhite), + onPressed: () => Navigator.of(context).popUntil( + (route) => route.isFirst, + ), + ), + ), + body: Column( + children: [ + const Spacer(), + Text(_location), + Center( + child: ConfettiWidget( + confettiController: _confettiController..play(), + blastDirectionality: BlastDirectionality.explosive, + gravity: 0.05, + shouldLoop: true, + colors: const [ + Colors.green, + Colors.blue, + Colors.pink, + Colors.orange, + Colors.purple, + ], + ), + ), + const Spacer(flex: 3), + ], + ), + ); + } + + @override + void dispose() { + _confettiController.dispose(); + _locationStream.cancel(); + super.dispose(); + } + + Future _onPositionUpdated(Position pos) async { + final placemarks = + await placemarkFromCoordinates(pos.latitude, pos.longitude); + setState(() { + _location = 'Your location: ${placemarks.firstOrNull?.street ?? ''}'; + }); + } +} diff --git a/packages/patrol/example/lib/pages/quiz/error_page.dart b/packages/patrol/example/lib/pages/quiz/error_page.dart new file mode 100644 index 000000000..19c3f6540 --- /dev/null +++ b/packages/patrol/example/lib/pages/quiz/error_page.dart @@ -0,0 +1,33 @@ +import 'package:example/ui/components/scaffold.dart'; +import 'package:example/ui/icons.dart'; +import 'package:example/ui/style/test_style.dart'; +import 'package:flutter/material.dart'; + +Route get errorRoute => + MaterialPageRoute(builder: (_) => const _ErrorPage()); + +class _ErrorPage extends StatelessWidget { + const _ErrorPage(); + + @override + Widget build(BuildContext context) { + return PTScaffold( + body: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + PTIcons.circleX, + const SizedBox(height: 16), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 48), + child: Text( + 'Unfortunately you have selected wrong answer. ' + 'Restart the app and try again.', + textAlign: TextAlign.center, + style: PTTextStyles.bodyBold, + ), + ), + ], + ), + ); + } +} diff --git a/packages/patrol/example/lib/pages/quiz/form_page.dart b/packages/patrol/example/lib/pages/quiz/form_page.dart new file mode 100644 index 000000000..83bc35ace --- /dev/null +++ b/packages/patrol/example/lib/pages/quiz/form_page.dart @@ -0,0 +1,390 @@ +import 'dart:math'; + +import 'package:example/pages/quiz/question_page.dart'; +import 'package:example/ui/components/button/elevated_button.dart'; +import 'package:example/ui/components/scaffold.dart'; +import 'package:example/ui/components/text_field.dart'; +import 'package:example/ui/style/colors.dart'; +import 'package:example/ui/style/test_style.dart'; +import 'package:example/ui/widgets/top_bar.dart'; +import 'package:example/ui/widgets/utils.dart'; +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; + +Route get formRoute => + MaterialPageRoute(builder: (_) => const _FormPage()); + +class _FormPage extends StatefulWidget { + const _FormPage(); + + static final _leanCodeColors = { + PTColors.lcBlack, + PTColors.lcYellow, + PTColors.lcWhite, + }; + static final _otherColors = { + const Color(0xFF3AE35F), + const Color(0xFF7521FF), + const Color(0xFF215FFF), + const Color(0xFFABFFB3), + const Color(0xFF8DD6FF), + const Color(0xFF739F51), + }; + + @override + State<_FormPage> createState() => _FormPageState(); +} + +class _FormPageState extends State<_FormPage> { + var _submitted = false; + + @override + Widget build(BuildContext context) { + return GestureDetector( + onTap: FocusScope.of(context).unfocus, + child: PTScaffold( + bodyKey: ValueKey(_submitted), + top: const TopBar(), + body: + _submitted ? const _CountdownTimer() : _Form(onSubmit: _showTimer), + ), + ); + } + + void _showTimer(bool valid) { + if (valid) { + setState(() => _submitted = true); + } + } +} + +class _Form extends StatefulWidget { + const _Form({required this.onSubmit}); + + final ValueChanged onSubmit; + + @override + State<_Form> createState() => _FormState(); +} + +class _FormState extends State<_Form> { + final _colorsToDisplay = [ + ..._FormPage._leanCodeColors, + ..._FormPage._otherColors, + ]..shuffle(); + final _textController = TextEditingController(); + final _selectedColors = {}; + var _showErrors = false; + + @override + void initState() { + super.initState(); + _textController.addListener(() => setState(() {})); + } + + @override + void dispose() { + _textController.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return SingleChildScrollView( + keyboardDismissBehavior: ScrollViewKeyboardDismissBehavior.onDrag, + padding: const EdgeInsets.only(bottom: 24), + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + const SizedBox(height: 24), + Text( + 'Choose a nickname to sign up', + style: PTTextStyles.h4, + ), + const SizedBox(height: 32), + PTTextField( + controller: _textController, + label: 'Your nickname', + errorText: + _showErrors && !_nickValid ? 'Nick must not be empty' : null, + ), + const SizedBox(height: 32), + _ColorPicker( + selectedColors: _selectedColors, + colorsToDisplay: _colorsToDisplay, + onSelected: _onColorSelected, + errorText: + _showErrors && !_colorsValid ? 'Colors must be picked' : null, + ), + const SizedBox(height: 24), + PTElevatedButton( + caption: 'Ready!', + onPressed: _onSubmit, + ), + ], + ).horizontallyPadded24, + ); + } + + void _onColorSelected(Color color) { + setState(() { + if (_selectedColors.contains(color)) { + _selectedColors.remove(color); + } else if (_selectedColors.length < 3) { + _selectedColors.add(color); + } + }); + } + + bool get _nickValid => _textController.text.isNotEmpty; + + bool get _colorsValid => + setEquals(_FormPage._leanCodeColors, _selectedColors); + + bool get _allValid => _nickValid && _colorsValid; + + void _onSubmit() { + if (_allValid) { + widget.onSubmit(true); + } else if (!_showErrors) { + setState(() { + _showErrors = true; + }); + } + } +} + +class _CountdownTimer extends StatefulWidget { + const _CountdownTimer(); + + @override + State<_CountdownTimer> createState() => _CountdownTimerState(); +} + +class _CountdownTimerState extends State<_CountdownTimer> { + @override + Widget build(BuildContext context) { + return Stack( + alignment: Alignment.center, + fit: StackFit.expand, + children: [ + Positioned( + top: 128, + height: 120, + width: 262, + child: Text( + 'The quiz will start in', + style: PTTextStyles.h1, + textAlign: TextAlign.center, + ), + ), + const _AnimatedTimer(), + ], + ); + } +} + +class _AnimatedTimer extends StatefulWidget { + const _AnimatedTimer(); + + @override + State<_AnimatedTimer> createState() => _AnimatedTimerState(); +} + +class _AnimatedTimerState extends State<_AnimatedTimer> + with SingleTickerProviderStateMixin { + late final AnimationController _animationController; + + @override + void initState() { + super.initState(); + _animationController = + AnimationController(vsync: this, duration: const Duration(seconds: 3)) + ..addStatusListener( + (status) { + if (status == AnimationStatus.completed) { + Navigator.of(context).push(questionRoute); + } + }, + ); + + Future.delayed(const Duration(milliseconds: 200), () { + _animationController.animateTo(1); + }); + } + + @override + Widget build(BuildContext context) { + return AnimatedBuilder( + key: const Key('ticker'), + animation: _animationController, + builder: (context, child) { + final valueToDisplay = 3 - _animationController.value * 3; + + return Stack( + alignment: Alignment.center, + children: [ + _CustomPaint(painter: _Painter(2 * pi, PTColors.lcYellow)), + _CustomPaint( + painter: _Painter( + _animationController.value * 2 * pi, + const Color(0xFFFDFED5), + ), + ), + Text( + valueToDisplay.ceil().toString(), + style: PTTextStyles.h2.copyWith(color: PTColors.textDark), + ), + ], + ); + }, + ); + } +} + +class _CustomPaint extends StatelessWidget { + const _CustomPaint({required this.painter}); + + final _Painter painter; + + @override + Widget build(BuildContext context) { + return CustomPaint( + willChange: true, + painter: painter, + size: const Size(145, 145), + ); + } +} + +class _Painter extends CustomPainter { + _Painter(this.angle, this.color); + + final double angle; + final Color color; + + @override + void paint(Canvas canvas, Size size) { + final paint = Paint()..color = color; + canvas.drawArc( + Rect.fromCenter( + center: Offset(size.height / 2, size.width / 2), + height: size.height, + width: size.width, + ), + -pi / 2, + angle, + true, + paint, + ); + } + + @override + bool shouldRepaint(CustomPainter oldDelegate) => true; +} + +class _ColorPicker extends StatelessWidget { + const _ColorPicker({ + required this.selectedColors, + required this.colorsToDisplay, + required this.onSelected, + this.errorText, + }); + + final Set selectedColors; + final List colorsToDisplay; + final void Function(Color) onSelected; + final String? errorText; + + @override + Widget build(BuildContext context) { + final errorText = this.errorText; + + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + "To confirm you're not a robot, pick LeanCode's colors", + style: PTTextStyles.h4, + ), + const SizedBox(height: 16), + Text( + '${selectedColors.length}/3 selected', + style: PTTextStyles.label, + ), + const SizedBox(height: 8), + Wrap( + runSpacing: 8, + spacing: 8, + children: List.generate( + 9, + (index) => Builder( + builder: (context) { + final color = colorsToDisplay[index]; + + return GestureDetector( + onTap: () { + FocusScope.of(context).unfocus(); + onSelected(color); + }, + child: SelectableBox( + color: color, + selected: selectedColors.contains(color), + ), + ); + }, + ), + ), + ), + if (errorText != null) + Padding( + padding: const EdgeInsets.only(top: 8), + child: Text( + errorText, + style: PTTextStyles.label.copyWith(color: PTColors.error), + ), + ), + ], + ); + } +} + +class SelectableBox extends StatelessWidget { + const SelectableBox({ + super.key, + required this.color, + required this.selected, + }); + + final Color color; + final bool selected; + + @override + Widget build(BuildContext context) { + return Stack( + children: [ + Container( + width: 108, + height: 96, + decoration: BoxDecoration( + color: color, + borderRadius: const BorderRadius.all(Radius.circular(8)), + border: Border.all(color: PTColors.borderGrey), + ), + ), + if (selected) + Positioned( + top: 9, + right: 9, + child: Icon( + Icons.check_circle, + size: 22, + color: color == PTColors.lcBlack + ? PTColors.lcWhite + : PTColors.lcBlack, + ), + ), + ], + ); + } +} diff --git a/packages/patrol/example/lib/pages/quiz/question_page.dart b/packages/patrol/example/lib/pages/quiz/question_page.dart new file mode 100644 index 000000000..7af178045 --- /dev/null +++ b/packages/patrol/example/lib/pages/quiz/question_page.dart @@ -0,0 +1,279 @@ +import 'package:example/handlers/notification_handler.dart'; +import 'package:example/pages/quiz/error_page.dart'; +import 'package:example/pages/quiz/success_page.dart'; +import 'package:example/ui/components/button/elevated_button.dart'; +import 'package:example/ui/components/button/text_button.dart'; +import 'package:example/ui/components/scaffold.dart'; +import 'package:example/ui/style/colors.dart'; +import 'package:example/ui/style/test_style.dart'; +import 'package:example/ui/widgets/top_bar.dart'; +import 'package:example/ui/widgets/utils.dart'; +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; + +Route get questionRoute => + MaterialPageRoute(builder: (_) => _QuestionsPage()); + +class _QuestionsPage extends StatefulWidget { + @override + State<_QuestionsPage> createState() => _QuestionsPageState(); +} + +class _QuestionsPageState extends State<_QuestionsPage> { + var _taskIndex = 0; + late final List _answers; + final List _tasks = [ + "Click on elevated button with centered 'Fluttercon' text", + 'Click on an elevated button, which is placed in a list tile with a dash icon', + 'Click on the third button that is enabled', + ]; + + @override + void initState() { + super.initState(); + + _answers = [ + _Answers(answers: firstTaskAnswers), + _Answers(answers: secondTaskAnswers), + _Answers(answers: thirdTaskTaskAnswers), + ]; + } + + @override + Widget build(BuildContext context) { + return PTScaffold( + bodyKey: ValueKey(_taskIndex), + top: const TopBar(), + body: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + const SizedBox(height: 32), + Text( + 'Question ${_taskIndex + 1}/3', + style: PTTextStyles.h3, + ).horizontallyPadded24, + const SizedBox(height: 32), + Text(_tasks[_taskIndex]).horizontallyPadded24, + const SizedBox(height: 32), + Flexible(child: _answers[_taskIndex]), + const SizedBox(height: 24), + ], + ), + ); + } + + void _showError() => Navigator.of(context).push(errorRoute); + + void _showNextQuestion() => setState(() => _taskIndex++); + + Future _showNotification() async { + final notificationHandler = context.read(); + await notificationHandler.triggerLocalNotification( + onPressed: () => Navigator.of(context).push(successRoute), + onError: _showError, + ); + } + + List get firstTaskAnswers { + return [ + PTTextButton( + onPressed: _showError, + text: 'Fluttercon', + ), + PTElevatedButton( + onPressed: _showError, + caption: '', + trailing: const Text('Fluttercon'), + ), + PTElevatedButton( + onPressed: _showNextQuestion, + caption: 'Fluttercon', + ), + ]..shuffle(); + } + + List get secondTaskAnswers { + return [ + _Tile( + leading: _EnabledButton(onPressed: _showNextQuestion), + trailing: const _Dash(color: PTColors.lcWhite), + ), + _Tile(leading: _EnabledButton(onPressed: _showError)), + Center( + child: SizedBox( + width: 128, + child: _EnabledButton( + onPressed: _showError, + showTrailing: true, + ), + ), + ), + ]..shuffle(); + } + + List get thirdTaskTaskAnswers { + final firstPart = List.generate( + 10, + (index) => index % 6 == 0 + ? _EnabledButton(onPressed: _showError) + : const _DisabledButton(), + )..shuffle(); + final secondPart = List.generate( + 5, + (index) => index == 0 + ? _EnabledButton(onPressed: _showNotification) + : const _DisabledButton(), + )..shuffle(); + final thirdPart = List.generate( + 5, + (index) => index == 0 + ? _EnabledButton(onPressed: _showError) + : const _DisabledButton(), + )..shuffle(); + + return [...firstPart, ...secondPart, ...thirdPart]; + } +} + +class _Answers extends StatelessWidget { + const _Answers({ + required this.answers, + }); + + final List answers; + + @override + Widget build(BuildContext context) { + return SingleChildScrollView( + child: Padding( + padding: const EdgeInsets.only(left: 24, right: 16), + child: Column( + children: List.generate( + answers.length, + (index) => Padding( + padding: const EdgeInsets.symmetric(vertical: 16), + child: _Answer( + letter: _getAlphabetLetter(index), + answer: answers[index], + ), + ), + ), + ), + ), + ); + } + + String _getAlphabetLetter(int index) => String.fromCharCode(index + 65); +} + +class _Answer extends StatelessWidget { + const _Answer({ + required this.letter, + required this.answer, + }); + + final String letter; + final Widget answer; + + @override + Widget build(BuildContext context) { + return Row( + children: [ + SizedBox( + width: 14, + height: 19, + child: Text( + letter, + style: PTTextStyles.bodyBold, + ), + ), + const SizedBox(width: 16), + Expanded(child: answer), + ], + ); + } +} + +class _EnabledButton extends StatelessWidget { + const _EnabledButton({ + required this.onPressed, + this.showTrailing = false, + }); + + final VoidCallback onPressed; + final bool showTrailing; + + @override + Widget build(BuildContext context) { + return PTElevatedButton( + caption: 'click', + trailing: showTrailing ? const _Dash(color: PTColors.lcBlack) : null, + onPressed: onPressed, + ); + } +} + +class _DisabledButton extends StatelessWidget { + const _DisabledButton(); + + @override + Widget build(BuildContext context) { + return const PTElevatedButton( + caption: 'click', + onPressed: null, + ); + } +} + +class _Dash extends StatelessWidget { + const _Dash({ + required this.color, + }); + + final Color color; + + @override + Widget build(BuildContext context) { + return Icon( + Icons.flutter_dash, + color: color, + size: 24, + ); + } +} + +class _Tile extends StatelessWidget { + const _Tile({ + required this.leading, + this.trailing, + }); + + final Widget leading; + final Widget? trailing; + + @override + Widget build(BuildContext context) { + return DecoratedBox( + decoration: BoxDecoration( + border: Border.all(color: PTColors.borderGrey), + borderRadius: const BorderRadius.all(Radius.circular(12)), + color: PTColors.backgroundGrey, + ), + child: ListTile( + contentPadding: const EdgeInsets.symmetric( + horizontal: 8, + vertical: 6, + ), + leading: SizedBox( + width: 128, + child: leading, + ), + trailing: Padding( + padding: const EdgeInsets.only(right: 8), + child: trailing, + ), + tileColor: PTColors.backgroundGrey, + ), + ); + } +} diff --git a/packages/patrol/example/lib/pages/quiz/success_page.dart b/packages/patrol/example/lib/pages/quiz/success_page.dart new file mode 100644 index 000000000..550d64f4a --- /dev/null +++ b/packages/patrol/example/lib/pages/quiz/success_page.dart @@ -0,0 +1,48 @@ +import 'package:example/ui/components/button/elevated_button.dart'; +import 'package:example/ui/components/scaffold.dart'; +import 'package:example/ui/images.dart'; +import 'package:example/ui/style/colors.dart'; +import 'package:example/ui/style/test_style.dart'; +import 'package:flutter/material.dart'; + +Route get successRoute => + MaterialPageRoute(builder: (_) => const _SuccessPage()); + +class _SuccessPage extends StatelessWidget { + const _SuccessPage(); + + @override + Widget build(BuildContext context) { + return PTScaffold( + body: Stack( + fit: StackFit.expand, + children: [ + Positioned(child: PTImages.confetti), + Center( + child: Container( + width: double.infinity, + height: 76, + alignment: Alignment.center, + color: PTColors.lcBlack.withOpacity(0.9), + child: Text( + 'Congratulations!', + style: PTTextStyles.h2, + ), + ), + ), + Positioned( + left: 24, + right: 24, + bottom: 24, + child: PTElevatedButton( + onPressed: () => Navigator.of(context).popUntil( + (route) => route.isFirst, + ), + caption: 'Start again', + ), + ), + ], + ), + ); + } +} diff --git a/packages/patrol/example/lib/pages/quiz/welcome_page.dart b/packages/patrol/example/lib/pages/quiz/welcome_page.dart new file mode 100644 index 000000000..711f08c28 --- /dev/null +++ b/packages/patrol/example/lib/pages/quiz/welcome_page.dart @@ -0,0 +1,50 @@ +import 'package:example/pages/quiz/form_page.dart'; +import 'package:example/ui/components/button/elevated_button.dart'; +import 'package:example/ui/components/scaffold.dart'; +import 'package:example/ui/images.dart'; +import 'package:example/ui/style/colors.dart'; +import 'package:example/ui/style/test_style.dart'; +import 'package:example/ui/widgets/logos_hero.dart'; +import 'package:example/ui/widgets/utils.dart'; +import 'package:flutter/material.dart'; + +Route get quizWelcomeRoute => + MaterialPageRoute(builder: (_) => const _WelcomePage()); + +class _WelcomePage extends StatelessWidget { + const _WelcomePage(); + + @override + Widget build(BuildContext context) { + return PTScaffold( + body: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + const SizedBox(height: 76), + const LogoHero(), + const Spacer(), + Text.rich( + TextSpan( + style: PTTextStyles.h2.copyWith(color: PTColors.textWhite), + children: [ + const TextSpan(text: 'Welcome to Patrol Testing Quiz for'), + WidgetSpan( + child: Padding( + padding: const EdgeInsets.fromLTRB(5, 10, 10, 5), + child: PTImages.flutterconLogo, + ), + ), + ], + ), + ), + const SizedBox(height: 32), + PTElevatedButton( + caption: 'Start', + onPressed: () => Navigator.push(context, formRoute), + ), + const SizedBox(height: 40), + ], + ).horizontallyPadded24, + ); + } +} diff --git a/packages/patrol/example/lib/ui/components/button/elevated_button.dart b/packages/patrol/example/lib/ui/components/button/elevated_button.dart new file mode 100644 index 000000000..ce75ac591 --- /dev/null +++ b/packages/patrol/example/lib/ui/components/button/elevated_button.dart @@ -0,0 +1,84 @@ +import 'package:example/ui/style/colors.dart'; +import 'package:example/ui/style/test_style.dart'; +import 'package:example/ui/widgets/utils.dart'; +import 'package:flutter/material.dart'; + +class PTElevatedButton extends StatelessWidget { + const PTElevatedButton({ + super.key, + this.caption, + this.trailing, + required this.onPressed, + }); + + final String? caption; + final Widget? trailing; + final VoidCallback? onPressed; + + @override + Widget build(BuildContext context) { + final caption = this.caption; + final trailing = this.trailing; + + return SizedBox( + height: 48, + child: ElevatedButton( + style: ButtonStyle( + textStyle: _textStyle, + backgroundColor: _backgroundColor, + padding: _padding, + shape: _shape, + ), + onPressed: onPressed, + child: Row( + mainAxisAlignment: trailing != null + ? MainAxisAlignment.spaceBetween + : MainAxisAlignment.center, + children: [ + if (caption != null) Text(caption), + if (trailing != null) trailing, + ], + ).horizontallyPadded24, + ), + ); + } + + MaterialStateProperty? get _padding => + const MaterialStatePropertyAll(EdgeInsets.symmetric(vertical: 12)); + + MaterialStateProperty? get _shape => + const MaterialStatePropertyAll( + RoundedRectangleBorder( + borderRadius: BorderRadius.all(Radius.circular(8)), + ), + ); + + MaterialStateProperty? get _backgroundColor => + MaterialStateProperty.resolveWith( + (states) { + if (states.contains(MaterialState.pressed)) { + return PTColors.lcYellowPressed; + } else if (states.contains(MaterialState.disabled)) { + return PTColors.backgroundDisabled; + } + + return PTColors.lcYellow; + }, + ); + + MaterialStateProperty? get _textStyle => + MaterialStateProperty.resolveWith( + (states) { + if (states.contains(MaterialState.pressed)) { + return PTTextStyles.bodyMedium + .copyWith(foreground: Paint()..color = PTColors.textDark); + } else if (states.contains(MaterialState.disabled)) { + return PTTextStyles.bodyMedium + .copyWith(foreground: Paint()..color = PTColors.textDisabled); + } + + return PTTextStyles.bodyBold + .copyWith(foreground: Paint()..color = PTColors.textDark); + }, + ); +} diff --git a/packages/patrol/example/lib/ui/components/button/text_button.dart b/packages/patrol/example/lib/ui/components/button/text_button.dart new file mode 100644 index 000000000..6174501d6 --- /dev/null +++ b/packages/patrol/example/lib/ui/components/button/text_button.dart @@ -0,0 +1,34 @@ +import 'package:example/ui/style/colors.dart'; +import 'package:example/ui/style/test_style.dart'; +import 'package:flutter/material.dart'; + +class PTTextButton extends StatelessWidget { + const PTTextButton({ + super.key, + required this.text, + required this.onPressed, + }); + + final String text; + final VoidCallback onPressed; + + @override + Widget build(BuildContext context) { + return TextButton( + style: ButtonStyle( + overlayColor: MaterialStatePropertyAll( + PTColors.lcYellow.withOpacity(0.2), + ), + ), + onPressed: onPressed, + child: Center( + child: Text( + text, + style: PTTextStyles.bodyBold.copyWith( + color: PTColors.lcYellow, + ), + ), + ), + ); + } +} diff --git a/packages/patrol/example/lib/ui/components/scaffold.dart b/packages/patrol/example/lib/ui/components/scaffold.dart new file mode 100644 index 000000000..e6f7c20a8 --- /dev/null +++ b/packages/patrol/example/lib/ui/components/scaffold.dart @@ -0,0 +1,54 @@ +import 'package:animations/animations.dart'; +import 'package:example/ui/style/colors.dart'; +import 'package:example/ui/style/test_style.dart'; +import 'package:flutter/material.dart'; + +class PTScaffold extends StatelessWidget { + const PTScaffold({ + super.key, + this.top, + required this.body, + this.bodyKey, + }); + + final Widget? top; + final Widget body; + final Key? bodyKey; + + @override + Widget build(BuildContext context) { + final top = this.top; + + return PopScope( + onPopInvoked: (didPop) => Future.value(false), + child: Scaffold( + backgroundColor: PTColors.textDark, + body: DefaultTextStyle( + style: PTTextStyles.bodyMedium.copyWith(color: PTColors.textWhite), + child: SafeArea( + top: top == null, + child: PageTransitionSwitcher( + duration: const Duration(milliseconds: 1000), + transitionBuilder: (child, primaryAnimation, secondaryAnimation) { + return SharedAxisTransition( + animation: primaryAnimation, + secondaryAnimation: secondaryAnimation, + transitionType: SharedAxisTransitionType.horizontal, + fillColor: PTColors.lcBlack, + child: child, + ); + }, + child: Column( + key: bodyKey, + children: [ + if (top != null) top, + Expanded(child: body), + ], + ), + ), + ), + ), + ), + ); + } +} diff --git a/packages/patrol/example/lib/ui/components/text_field.dart b/packages/patrol/example/lib/ui/components/text_field.dart new file mode 100644 index 000000000..2f5609eb4 --- /dev/null +++ b/packages/patrol/example/lib/ui/components/text_field.dart @@ -0,0 +1,81 @@ +import 'package:example/ui/style/colors.dart'; +import 'package:example/ui/style/test_style.dart'; +import 'package:flutter/material.dart'; + +class PTTextField extends StatelessWidget { + const PTTextField({ + super.key, + required this.controller, + required this.label, + this.errorText, + }); + + final TextEditingController controller; + final String label; + final String? errorText; + + @override + Widget build(BuildContext context) { + final errorText = this.errorText; + + return Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + SizedBox( + height: 48, + child: _TextField( + controller: controller, + label: label, + ), + ), + if (errorText != null) ...[ + const SizedBox(height: 4), + Text( + errorText, + style: PTTextStyles.label.copyWith(color: PTColors.error), + ), + ], + ], + ); + } +} + +class _TextField extends StatelessWidget { + const _TextField({ + required this.controller, + required this.label, + }); + + final String label; + final TextEditingController controller; + + static const _borderColor = Color(0xFF777777); + static const _fillColor = Color(0xFF2F2F2F); + + @override + Widget build(BuildContext context) { + return TextField( + controller: controller, + style: PTTextStyles.bodyMedium.copyWith(color: PTColors.textWhite), + cursorColor: PTColors.textWhite, + decoration: InputDecoration( + labelText: label, + labelStyle: PTTextStyles.bodyMedium.copyWith(color: PTColors.textWhite), + fillColor: _fillColor, + contentPadding: const EdgeInsets.symmetric( + horizontal: 10, + vertical: 12, + ), + filled: true, + focusedBorder: _getBorder(PTColors.lcYellow), + border: _getBorder(_borderColor), + enabledBorder: _getBorder(_borderColor), + ), + ); + } + + OutlineInputBorder _getBorder(Color color) => OutlineInputBorder( + borderRadius: const BorderRadius.all(Radius.circular(6)), + borderSide: BorderSide(color: color), + ); +} diff --git a/packages/patrol/example/lib/ui/icons.dart b/packages/patrol/example/lib/ui/icons.dart new file mode 100644 index 000000000..d75447609 --- /dev/null +++ b/packages/patrol/example/lib/ui/icons.dart @@ -0,0 +1,6 @@ +import 'package:flutter_svg/flutter_svg.dart'; + +abstract class PTIcons { + static final appIcon = SvgPicture.asset('assets/icon/app_icon.png'); + static final circleX = SvgPicture.asset('assets/icon/circle_x.svg'); +} diff --git a/packages/patrol/example/lib/ui/images.dart b/packages/patrol/example/lib/ui/images.dart new file mode 100644 index 000000000..8ae4886c6 --- /dev/null +++ b/packages/patrol/example/lib/ui/images.dart @@ -0,0 +1,17 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; + +abstract class PTImages { + static final patrolLogo = SvgPicture.asset('assets/image/patrol_logo.svg'); + static final flutterconLogo = SvgPicture.asset( + 'assets/image/fluttercon_logo.svg', + placeholderBuilder: (_) => const SizedBox(height: 26, width: 166), + ); + static final leancodeLogo = SvgPicture.asset( + 'assets/image/leancode_logo.svg', + ); + static final confetti = SvgPicture.asset( + 'assets/image/confetti.svg', + fit: BoxFit.cover, + ); +} diff --git a/packages/patrol/example/lib/ui/style/colors.dart b/packages/patrol/example/lib/ui/style/colors.dart new file mode 100644 index 000000000..ffa1ea7ee --- /dev/null +++ b/packages/patrol/example/lib/ui/style/colors.dart @@ -0,0 +1,15 @@ +import 'dart:ui'; + +abstract class PTColors { + static const textDark = Color(0xFF1F1F1F); + static const lcYellow = Color(0xFFF0FF00); + static const lcBlack = Color(0xFF1F1F1F); + static const lcWhite = Color(0xFFFFFFFF); + static const lcYellowPressed = Color(0xFFEBFA01); + static const textWhite = Color(0xFFFAFAFA); + static const error = Color(0xFFFF1F1F); + static const textDisabled = Color(0xFFBCC1CC); + static const backgroundDisabled = Color(0xFFE8EAED); + static const backgroundGrey = Color(0xFF2F2F2F); + static const borderGrey = Color(0xFF717171); +} diff --git a/packages/patrol/example/lib/ui/style/test_style.dart b/packages/patrol/example/lib/ui/style/test_style.dart new file mode 100644 index 000000000..061e41379 --- /dev/null +++ b/packages/patrol/example/lib/ui/style/test_style.dart @@ -0,0 +1,46 @@ +import 'package:example/ui/style/colors.dart'; +import 'package:flutter/cupertino.dart'; + +abstract class PTTextStyles { + static const _baseStyle = TextStyle( + color: PTColors.textWhite, + fontFamily: 'Inter', + fontStyle: FontStyle.normal, + ); + + static final h1 = _baseStyle.copyWith( + fontSize: 42, + height: 1.43, + fontWeight: FontWeight.w600, + ); + static final h2 = _baseStyle.copyWith( + fontSize: 36, + height: 1.44, + fontWeight: FontWeight.w600, + ); + static final h3 = _baseStyle.copyWith( + fontSize: 24, + height: 1.50, + fontWeight: FontWeight.w600, + ); + static final h4 = _baseStyle.copyWith( + fontSize: 20, + height: 1.40, + fontWeight: FontWeight.w600, + ); + static final bodyBold = _baseStyle.copyWith( + fontSize: 16, + height: 1.3, + fontWeight: FontWeight.w600, + ); + static final bodyMedium = _baseStyle.copyWith( + fontSize: 16, + height: 1.3, + fontWeight: FontWeight.w500, + ); + static final label = _baseStyle.copyWith( + fontSize: 12, + height: 1.33, + fontWeight: FontWeight.w500, + ); +} diff --git a/packages/patrol/example/lib/ui/widgets/logos_hero.dart b/packages/patrol/example/lib/ui/widgets/logos_hero.dart new file mode 100644 index 000000000..6df9b1f26 --- /dev/null +++ b/packages/patrol/example/lib/ui/widgets/logos_hero.dart @@ -0,0 +1,20 @@ +import 'package:example/ui/images.dart'; +import 'package:flutter/widgets.dart'; + +class LogoHero extends StatelessWidget { + const LogoHero({super.key}); + + @override + Widget build(BuildContext context) { + return Hero( + tag: 'logoHero', + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + PTImages.patrolLogo, + PTImages.leancodeLogo, + ], + ), + ); + } +} diff --git a/packages/patrol/example/lib/ui/widgets/top_bar.dart b/packages/patrol/example/lib/ui/widgets/top_bar.dart new file mode 100644 index 000000000..9a42597bb --- /dev/null +++ b/packages/patrol/example/lib/ui/widgets/top_bar.dart @@ -0,0 +1,26 @@ +import 'package:example/ui/style/colors.dart'; +import 'package:example/ui/widgets/logos_hero.dart'; +import 'package:flutter/widgets.dart'; + +class TopBar extends StatelessWidget { + const TopBar({super.key}); + + @override + Widget build(BuildContext context) { + return Container( + color: PTColors.backgroundGrey, + child: Column( + children: [ + SizedBox(height: MediaQuery.of(context).viewPadding.top), + const SizedBox( + height: 56, + child: Padding( + padding: EdgeInsets.symmetric(vertical: 16), + child: LogoHero(), + ), + ), + ], + ), + ); + } +} diff --git a/packages/patrol/example/lib/ui/widgets/utils.dart b/packages/patrol/example/lib/ui/widgets/utils.dart new file mode 100644 index 000000000..e993dc0e0 --- /dev/null +++ b/packages/patrol/example/lib/ui/widgets/utils.dart @@ -0,0 +1,8 @@ +import 'package:flutter/cupertino.dart'; + +extension ColumnPadded on Widget { + Widget get horizontallyPadded24 => Padding( + padding: const EdgeInsets.symmetric(horizontal: 24), + child: this, + ); +} diff --git a/packages/patrol/example/pubspec.yaml b/packages/patrol/example/pubspec.yaml index 47b5ef4bc..285293f7f 100644 --- a/packages/patrol/example/pubspec.yaml +++ b/packages/patrol/example/pubspec.yaml @@ -1,5 +1,5 @@ -name: patrol_example -description: A new Flutter project. +name: example +description: Patrol example app. publish_to: none version: 1.0.0+1 @@ -8,28 +8,59 @@ environment: flutter: '>=3.16.0' dependencies: - cupertino_icons: ^1.0.6 + animations: ^2.0.8 + confetti: ^0.7.0 + dispose_scope: ^2.1.0 + firebase_auth: ^4.14.1 + firebase_core: ^2.23.0 + firebase_messaging: ^14.7.5 flutter: sdk: flutter + flutter_bloc: ^8.1.3 + flutter_holo_date_picker: ^1.1.3 flutter_local_notifications: ^16.1.0 - flutter_timezone: ^1.0.8 + flutter_svg: ^2.0.9 + geocoding: ^2.1.1 geolocator: ^10.1.0 - permission_handler: ^10.4.5 - timezone: ^0.9.2 - webview_flutter: ^4.4.2 - + google_sign_in: ^6.1.6 + http: ^1.1.0 + permission_handler: ^11.1.0 + provider: ^6.1.1 dev_dependencies: + flutter_launcher_icons: ^0.13.1 + flutter_native_splash: ^2.3.6 flutter_test: sdk: flutter leancode_lint: ^7.0.0+1 patrol: - path: ../ + path: .. + +flutter_launcher_icons: + android: 'launcher_icon' + ios: true + image_path: 'assets/icon/app_icon.png' + +flutter_native_splash: + color: '#1F1F1F' + image: 'assets/icon/splash_icon.png' + android_12: + image: 'assets/icon/splash_icon.png' + color: '#1F1F1F' flutter: uses-material-design: true + assets: + - assets/icon/ + - assets/image/ + fonts: + - family: Inter + fonts: + - asset: assets/fonts/Inter-Medium.ttf + weight: 500 + - asset: assets/fonts/Inter-SemiBold.ttf + weight: 600 patrol: - app_name: Patrol example android: package_name: pl.leancode.patrol.example ios: diff --git a/packages/patrol/example/test/widget_test.dart b/packages/patrol/example/test/widget_test.dart new file mode 100644 index 000000000..d5cfa06f1 --- /dev/null +++ b/packages/patrol/example/test/widget_test.dart @@ -0,0 +1,29 @@ +// This is a basic Flutter widget test. +// +// To perform an interaction with a widget in your test, use the WidgetTester +// utility in the flutter_test package. For example, you can send tap and scroll +// gestures. You can also use WidgetTester to find child widgets in the widget +// tree, read text, and verify that the values of widget properties are correct. + +import 'package:example/main.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; + +void main() { + testWidgets('Counter increments smoke test', (tester) async { + // Build our app and trigger a frame. + await tester.pumpWidget(const MyApp()); + + // Verify that our counter starts at 0. + expect(find.text('0'), findsOneWidget); + expect(find.text('1'), findsNothing); + + // Tap the '+' icon and trigger a frame. + await tester.tap(find.byIcon(Icons.add)); + await tester.pump(); + + // Verify that our counter has incremented. + expect(find.text('0'), findsNothing); + expect(find.text('1'), findsOneWidget); + }); +} diff --git a/packages/patrol/pubspec.yaml b/packages/patrol/pubspec.yaml index a60ccb653..51574906b 100644 --- a/packages/patrol/pubspec.yaml +++ b/packages/patrol/pubspec.yaml @@ -43,3 +43,8 @@ flutter: pluginClass: PatrolPlugin ios: pluginClass: PatrolPlugin + +# These files don't contain real credentials. They exist only for build to pass. +false_secrets: + - /example/android/app/google-services.json + - /example/ios/Runner/GoogleService-Info.plist diff --git a/packages/patrol_devtools_extension/pubspec.lock b/packages/patrol_devtools_extension/pubspec.lock index 902b482f0..0094da241 100644 --- a/packages/patrol_devtools_extension/pubspec.lock +++ b/packages/patrol_devtools_extension/pubspec.lock @@ -122,29 +122,29 @@ packages: source: hosted version: "1.0.6" custom_lint: - dependency: transitive + dependency: "direct dev" description: name: custom_lint - sha256: f9a828b696930cf8307f9a3617b2b65c9b370e484dc845d69100cadb77506778 + sha256: "198ec6b8e084d22f508a76556c9afcfb71706ad3f42b083fe0ee923351a96d90" url: "https://pub.dev" source: hosted - version: "0.5.6" + version: "0.5.7" custom_lint_builder: dependency: transitive description: name: custom_lint_builder - sha256: c6f656a4d83385fc0656ae60410ed06bb382898c45627bfb8bbaa323aea97883 + sha256: dfcfa987d2bd9d0ba751ef4bdef0f6c1aa0062f2a67fe716fd5f3f8b709d6418 url: "https://pub.dev" source: hosted - version: "0.5.6" + version: "0.5.7" custom_lint_core: dependency: transitive description: name: custom_lint_core - sha256: e20a67737adcf0cf2465e734dd624af535add11f9edd1f2d444909b5b0749650 + sha256: f84c3fe2f27ef3b8831953e477e59d4a29c2952623f9eac450d7b40d9cdd94cc url: "https://pub.dev" source: hosted - version: "0.5.6" + version: "0.5.7" dart_style: dependency: transitive description: diff --git a/packages/patrol_finders/example/android/app/src/main/AndroidManifest.xml b/packages/patrol_finders/example/android/app/src/main/AndroidManifest.xml index bb0b8b58a..2198855b2 100644 --- a/packages/patrol_finders/example/android/app/src/main/AndroidManifest.xml +++ b/packages/patrol_finders/example/android/app/src/main/AndroidManifest.xml @@ -1,8 +1,5 @@ - - + -