diff --git a/.github/workflows/onPush.yaml b/.github/workflows/onPush.yaml index c8a67b3..5abee78 100644 --- a/.github/workflows/onPush.yaml +++ b/.github/workflows/onPush.yaml @@ -15,7 +15,7 @@ jobs: uses: subosito/flutter-action@v2 with: architecture: x64 - flutter-version: 3.22.2 + flutter-version: 3.24.5 - name: Install dependencies run: flutter pub get diff --git a/.gitignore b/.gitignore index ac5aa98..7835ae7 100644 --- a/.gitignore +++ b/.gitignore @@ -27,3 +27,4 @@ migrate_working_dir/ **/doc/api/ .dart_tool/ build/ +example/.patrol.env diff --git a/example/.patrol.env.example b/example/.patrol.env.example new file mode 100644 index 0000000..c866aba --- /dev/null +++ b/example/.patrol.env.example @@ -0,0 +1,25 @@ +# Email + password user credentials +LOGIN_EMAIL= +LOGIN_PASSWORD= + +# Email + password user wrong credentials +LOGIN_WRONG_EMAIL= +LOGIN_WRONG_PASSWORD= + +# Sign up user credentials +SIGN_UP_TEMPLATE=some.email+{uuid}@mail.com +SIGN_UP_NAME=Test +SIGN_UP_ORGANIZATION=Flutter Integration Testing + +# Google login email +GOOGLE_EMAIL= + +# Google login credentials +APPLE_EMAIL= +APPLE_PASSWORD= + +# Tenants +TENANT_ID_1=1148ad6b-e8d1-447c-910b-b270ed5deb22 +TENANT_ID_2=9cbbbea9-18c8-4c18-a43a-fd6f1623d422 +TENANT_NAME_1=Account 1 +TENANT_NAME_2=Account 2 \ No newline at end of file diff --git a/example/android/app/build.gradle b/example/android/app/build.gradle index 12c17d4..3bcf343 100644 --- a/example/android/app/build.gradle +++ b/example/android/app/build.gradle @@ -22,13 +22,15 @@ if (flutterVersionName == null) { flutterVersionName = '1.0' } -def fronteggDomain = "autheu.davidantoon.me" -def fronteggClientId = "b6adfe4c-d695-4c04-b95f-3ec9fd0c6cca" +def fronteggDomain = "app-axsx38m96enh.frontegg.com" +def fronteggClientId = "392b348b-a37c-471f-8f1b-2c35d23aa7e6" android { namespace "com.frontegg.demo" compileSdk 34 ndkVersion flutter.ndkVersion + ndkVersion = "26.1.10909125" + compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 @@ -61,6 +63,23 @@ android { buildConfigField "String", 'FRONTEGG_CLIENT_ID', "\"$fronteggClientId\"" buildConfigField "Boolean", 'FRONTEGG_USE_ASSETS_LINKS', "true" buildConfigField "Boolean", 'FRONTEGG_USE_CHROME_CUSTOM_TABS', "true" + + testInstrumentationRunner "pl.leancode.patrol.PatrolJUnitRunner" + testInstrumentationRunnerArguments clearPackageData: "true" + } + + testOptions { + execution "ANDROIDX_TEST_ORCHESTRATOR" + } + + signingConfigs { + debug { + storeFile file("./../../../.github/test-jks/debug.keystore") + } + + release { + storeFile file("./../../../.github/test-jks/release.keystore") + } } signingConfigs { @@ -81,6 +100,11 @@ android { shrinkResources true proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } + + debug { + minifyEnabled false + shrinkResources false + } } buildFeatures { @@ -94,4 +118,6 @@ flutter { source '../..' } -dependencies {} +dependencies { + androidTestUtil "androidx.test:orchestrator:1.5.1" +} diff --git a/example/android/app/proguard-rules.pro b/example/android/app/proguard-rules.pro index 74777f4..80eb8c9 100644 --- a/example/android/app/proguard-rules.pro +++ b/example/android/app/proguard-rules.pro @@ -9,3 +9,15 @@ # Frontegg SDK -keepclasseswithmembers class com.frontegg.** {*;} + +-dontwarn com.google.android.play.core.splitcompat.SplitCompatApplication +-dontwarn com.google.android.play.core.splitinstall.SplitInstallException +-dontwarn com.google.android.play.core.splitinstall.SplitInstallManager +-dontwarn com.google.android.play.core.splitinstall.SplitInstallManagerFactory +-dontwarn com.google.android.play.core.splitinstall.SplitInstallRequest$Builder +-dontwarn com.google.android.play.core.splitinstall.SplitInstallRequest +-dontwarn com.google.android.play.core.splitinstall.SplitInstallSessionState +-dontwarn com.google.android.play.core.splitinstall.SplitInstallStateUpdatedListener +-dontwarn com.google.android.play.core.tasks.OnFailureListener +-dontwarn com.google.android.play.core.tasks.OnSuccessListener +-dontwarn com.google.android.play.core.tasks.Task diff --git a/example/android/app/src/androidTest/java/com/frontegg/demo/MainActivityTest.java b/example/android/app/src/androidTest/java/com/frontegg/demo/MainActivityTest.java new file mode 100644 index 0000000..4c6f34a --- /dev/null +++ b/example/android/app/src/androidTest/java/com/frontegg/demo/MainActivityTest.java @@ -0,0 +1,36 @@ +package com.frontegg.demo; + +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(); + // replace "MainActivity.class" with "io.flutter.embedding.android.FlutterActivity.class" + // if in AndroidManifest.xml in manifest/application/activity you have + // android:name="io.flutter.embedding.android.FlutterActivity" + 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/example/android/app/src/main/AndroidManifest.xml b/example/android/app/src/main/AndroidManifest.xml index b35e85b..44ef0f4 100644 --- a/example/android/app/src/main/AndroidManifest.xml +++ b/example/android/app/src/main/AndroidManifest.xml @@ -1,7 +1,7 @@ - - + + diff --git a/example/android/gradle/wrapper/gradle-wrapper.properties b/example/android/gradle/wrapper/gradle-wrapper.properties index 15de902..17655d0 100644 --- a/example/android/gradle/wrapper/gradle-wrapper.properties +++ b/example/android/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/example/android/settings.gradle b/example/android/settings.gradle index b5ac4b9..d4e9f4d 100644 --- a/example/android/settings.gradle +++ b/example/android/settings.gradle @@ -19,7 +19,7 @@ pluginManagement { plugins { id "dev.flutter.flutter-plugin-loader" version "1.0.0" - id "com.android.application" version "7.4.2" apply false + id "com.android.application" version "8.4.0" apply false id "org.jetbrains.kotlin.android" version "1.9.10" apply false } diff --git a/example/integration_test/src/login_via_apple_test.dart b/example/integration_test/src/login_via_apple_test.dart new file mode 100644 index 0000000..53e35ff --- /dev/null +++ b/example/integration_test/src/login_via_apple_test.dart @@ -0,0 +1,100 @@ +import 'dart:io'; + +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:frontegg_flutter_example/main.dart'; +import 'package:patrol/patrol.dart'; + +void main() { + const appleButtonLabel = "continue with apple"; + + late final String email; + late final String password; + + patrolSetUp(() { + email = const String.fromEnvironment('APPLE_EMAIL'); + password = const String.fromEnvironment('APPLE_PASSWORD'); + + assert(email.isNotEmpty && password.isNotEmpty); + }); + + patrolTest( + 'Success Login via Apple Provider', + ($) async { + await $.pumpWidget(const MyApp()); + await $.pumpAndSettle(); + + await $.tap(find.byKey(const ValueKey("LoginButton"))); + + await $.native.tap( + Selector(text: appleButtonLabel), + timeout: const Duration(seconds: 10), + ); + await Future.delayed(const Duration(seconds: 3)); + if (Platform.isIOS) { + await $.native.tap(Selector(text: "Continue")); + await Future.delayed(const Duration(seconds: 7)); + } + + await $.native2.enterText( + NativeSelector( + ios: IOSSelector( + label: "Email or Phone Number", + ), + android: AndroidSelector( + resourceName: "account_name_text_field", + ), + ), + text: email, + keyboardBehavior: + Platform.isIOS ? KeyboardBehavior.showAndDismiss : KeyboardBehavior.alternative, + ); + if (Platform.isAndroid) { + await $.native.tap(Selector(resourceId: "sign-in")); + } + await Future.delayed(const Duration(seconds: 3)); + + await $.native2.enterText( + NativeSelector( + ios: IOSSelector( + label: "password", + ), + android: AndroidSelector( + resourceName: "password_text_field", + ), + ), + text: password, + keyboardBehavior: + Platform.isIOS ? KeyboardBehavior.showAndDismiss : KeyboardBehavior.alternative, + ); + if (Platform.isAndroid) { + await $.native.tap(Selector(resourceId: "sign-in")); + } + + await $.native.waitUntilVisible(Selector(textStartsWith: "Do you want to continue using")); + await Future.delayed(const Duration(seconds: 2)); + await $.native2.tap( + NativeSelector( + ios: IOSSelector( + label: "Continue", + instance: 1, + ), + android: AndroidSelector( + textContains: "Continue", + isClickable: true, + ), + ), + ); + + await $.pumpAndSettle(); + await $.waitUntilVisible( + find.text("Logout"), + timeout: const Duration(seconds: 15), + ); + + await $.tap(find.byKey(const ValueKey("LogoutButton"))); + await $.pumpAndSettle(); + await $.waitUntilVisible(find.text("Not Authenticated")); + }, + ); +} diff --git a/example/integration_test/src/login_via_email_and_password_test.dart b/example/integration_test/src/login_via_email_and_password_test.dart new file mode 100644 index 0000000..0553213 --- /dev/null +++ b/example/integration_test/src/login_via_email_and_password_test.dart @@ -0,0 +1,110 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:frontegg_flutter_example/main.dart'; +import 'package:patrol/patrol.dart'; + +void main() { + late final String email; + late final String wrongEmail; + + late final String password; + late final String wrongPassword; + + patrolSetUp(() { + email = const String.fromEnvironment('LOGIN_EMAIL'); + password = const String.fromEnvironment('LOGIN_PASSWORD'); + + wrongEmail = const String.fromEnvironment('LOGIN_WRONG_EMAIL'); + wrongPassword = const String.fromEnvironment('LOGIN_WRONG_PASSWORD'); + }); + + patrolTest( + 'Success Login via email and password', + ($) async { + await $.pumpWidget(const MyApp()); + await $.pumpAndSettle(); + + await $.tap(find.byKey(const ValueKey("LoginButton"))); + await Future.delayed(const Duration(seconds: 5)); + + await $.native.enterTextByIndex( + email, + index: 0, + keyboardBehavior: KeyboardBehavior.alternative, + ); + + await $.native.tap(Selector(text: "Continue")); + + await $.native.enterTextByIndex( + password, + index: 1, + keyboardBehavior: KeyboardBehavior.alternative, + ); + + await $.native.tap(Selector(text: "Sign in")); + + await $.waitUntilVisible(find.text("Logout"), timeout: const Duration(seconds: 15),); + + await $.tap(find.byKey(const ValueKey("LogoutButton"))); + await $.pumpAndSettle(); + }, + ); + + patrolTest( + 'Failure Login via wrong email and password', + ($) async { + await $.pumpWidget(const MyApp()); + await $.pumpAndSettle(); + + await $.tap(find.byKey(const ValueKey("LoginButton"))); + await Future.delayed(const Duration(seconds: 5)); + + await $.native.enterTextByIndex( + wrongEmail, + index: 0, + keyboardBehavior: KeyboardBehavior.alternative, + ); + + await $.native.tap(Selector(text: "Continue")); + + await $.native.enterTextByIndex( + password, + index: 1, + keyboardBehavior: KeyboardBehavior.alternative, + ); + + await $.native.tap(Selector(text: "Sign in")); + + await $.native.waitUntilVisible(Selector(text: "Incorrect email or password")); + }, + ); + + patrolTest( + 'Failure Login via email and wrong password', + ($) async { + await $.pumpWidget(const MyApp()); + await $.pumpAndSettle(); + + await $.tap(find.byKey(const ValueKey("LoginButton"))); + await Future.delayed(const Duration(seconds: 5)); + + await $.native.enterTextByIndex( + email, + index: 0, + keyboardBehavior: KeyboardBehavior.alternative, + ); + + await $.native.tap(Selector(text: "Continue")); + + await $.native.enterTextByIndex( + wrongPassword, + index: 1, + keyboardBehavior: KeyboardBehavior.alternative, + ); + + await $.native.tap(Selector(text: "Sign in")); + + await $.native.waitUntilVisible(Selector(text: "Incorrect email or password")); + }, + ); +} diff --git a/example/integration_test/src/login_via_google_test.dart b/example/integration_test/src/login_via_google_test.dart new file mode 100644 index 0000000..cc08648 --- /dev/null +++ b/example/integration_test/src/login_via_google_test.dart @@ -0,0 +1,41 @@ +import 'dart:io'; + +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:frontegg_flutter_example/main.dart'; +import 'package:patrol/patrol.dart'; + +void main() { + const googleButtonLabel = "continue with google"; + late final String email; + patrolSetUp(() { + email = const String.fromEnvironment('GOOGLE_EMAIL'); + + assert(email.isNotEmpty); + }); + + patrolTest( + 'Success Login via Google Provider', + ($) async { + await $.pumpWidget(const MyApp()); + await $.pumpAndSettle(); + + await $.tap(find.byKey(const ValueKey("LoginButton"))); + await Future.delayed(const Duration(seconds: 5)); + + await $.native.tap(Selector(text: googleButtonLabel)); + await Future.delayed(const Duration(seconds: 5)); + if (Platform.isIOS) { + await $.native.tap(Selector(text: "Continue")); + await Future.delayed(const Duration(seconds: 7)); + } + await $.native.tap(Selector(text: email)); + + await $.waitUntilVisible(find.text("Logout"), timeout: const Duration(seconds: 15),); + + await $.tap(find.byKey(const ValueKey("LogoutButton"))); + await $.pumpAndSettle(); + await $.waitUntilVisible(find.text("Not Authenticated")); + }, + ); +} diff --git a/example/integration_test/src/logout_test.dart b/example/integration_test/src/logout_test.dart new file mode 100644 index 0000000..2298fbc --- /dev/null +++ b/example/integration_test/src/logout_test.dart @@ -0,0 +1,50 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:frontegg_flutter_example/main.dart'; +import 'package:patrol/patrol.dart'; + +void main() { + late final String email; + late final String password; + + patrolSetUp(() { + email = const String.fromEnvironment('LOGIN_EMAIL'); + password = const String.fromEnvironment('LOGIN_PASSWORD'); + }); + + patrolTest( + 'Success Logout', + ($) async { + await $.pumpWidget(const MyApp()); + await $.pumpAndSettle(); + + await $.tap(find.byKey(const ValueKey("LoginButton"))); + await Future.delayed(const Duration(seconds: 5)); + + await $.native.enterTextByIndex( + email, + index: 0, + keyboardBehavior: KeyboardBehavior.alternative, + ); + + await $.native.tap(Selector(text: "Continue")); + + await $.native.enterTextByIndex( + password, + index: 1, + keyboardBehavior: KeyboardBehavior.alternative, + ); + + await $.native.tap(Selector(text: "Sign in")); + + await $.waitUntilVisible( + find.text("Logout"), + timeout: const Duration(seconds: 15), + ); + + await $.tap(find.byKey(const ValueKey("LogoutButton"))); + await $.pumpAndSettle(); + await $.waitUntilVisible(find.text("Not Authenticated")); + }, + ); +} diff --git a/example/integration_test/src/sign_up_via_email_and_password_test.dart b/example/integration_test/src/sign_up_via_email_and_password_test.dart new file mode 100644 index 0000000..4231da3 --- /dev/null +++ b/example/integration_test/src/sign_up_via_email_and_password_test.dart @@ -0,0 +1,287 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:frontegg_flutter_example/main.dart'; +import 'package:patrol/patrol.dart'; +import 'package:uuid/uuid.dart'; + +void main() { + late final String email; + late final String existsEmail; + + late final String password; + late final String name; + late final String organization; + + patrolSetUp(() { + password = const String.fromEnvironment('LOGIN_PASSWORD'); + email = const String.fromEnvironment('SIGN_UP_TEMPLATE').replaceFirst( + "{uuid}", + const Uuid().v4(), + ); + + name = const String.fromEnvironment('SIGN_UP_NAME'); + organization = const String.fromEnvironment('SIGN_UP_ORGANIZATION'); + existsEmail = const String.fromEnvironment('LOGIN_EMAIL'); + }); + + patrolTest( + "Success Sign up via email and password", + ($) async { + await $.pumpWidget(const MyApp()); + await $.pumpAndSettle(); + + await $.tap(find.byKey(const ValueKey("LoginButton"))); + await Future.delayed(const Duration(seconds: 5)); + + await $.native.tap(Selector(text: "Sign up")); + await $.native.waitUntilVisible(Selector(text: "Account sign-up")); + + await $.native.enterTextByIndex( + email, + index: 0, + keyboardBehavior: KeyboardBehavior.alternative, + ); + await $.native.enterTextByIndex( + name, + index: 1, + keyboardBehavior: KeyboardBehavior.alternative, + ); + await $.native.enterTextByIndex( + password, + index: 2, + keyboardBehavior: KeyboardBehavior.alternative, + ); + await $.native.enterTextByIndex( + organization, + index: 3, + keyboardBehavior: KeyboardBehavior.alternative, + ); + + // Hide Keyboard + await $.native.tap(Selector(text: "Account sign-up")); + await Future.delayed(const Duration(seconds: 1)); + + await $.native.tap(Selector(text: "Sign up")); + + await $.waitUntilVisible(find.text("Logout"), timeout: const Duration(seconds: 15),); + + await $.tap(find.byKey(const ValueKey("LogoutButton"))); + await $.pumpAndSettle(); + }, + ); + + patrolTest( + 'Failure Sign up with existing user', + ($) async { + await $.pumpWidget(const MyApp()); + await $.pumpAndSettle(); + + await $.tap(find.byKey(const ValueKey("LoginButton"))); + await Future.delayed(const Duration(seconds: 5)); + + await $.native.tap(Selector(text: "Sign up")); + await $.native.waitUntilVisible(Selector(text: "Account sign-up")); + + await $.native.enterTextByIndex( + existsEmail, + index: 0, + keyboardBehavior: KeyboardBehavior.alternative, + ); + await $.native.enterTextByIndex( + name, + index: 1, + keyboardBehavior: KeyboardBehavior.alternative, + ); + await $.native.enterTextByIndex( + password, + index: 2, + keyboardBehavior: KeyboardBehavior.alternative, + ); + await $.native.enterTextByIndex( + organization, + index: 3, + keyboardBehavior: KeyboardBehavior.alternative, + ); + + // Hide Keyboard + await $.native.tap(Selector(text: "Account sign-up")); + await Future.delayed(const Duration(seconds: 1)); + + await $.native.tap(Selector(text: "Sign up")); + + await $.native.waitUntilVisible(Selector(text: "User already exists")); + }, + ); + + patrolTest( + 'Failure Sign up with invalid Email field', + ($) async { + await $.pumpWidget(const MyApp()); + await $.pumpAndSettle(); + + await $.tap(find.byKey(const ValueKey("LoginButton"))); + await Future.delayed(const Duration(seconds: 5)); + + await $.native.tap(Selector(text: "Sign up")); + await $.native.waitUntilVisible(Selector(text: "Account sign-up")); + + await $.native.enterTextByIndex( + "s", + index: 0, + keyboardBehavior: KeyboardBehavior.alternative, + ); + await $.native.enterTextByIndex( + name, + index: 1, + keyboardBehavior: KeyboardBehavior.alternative, + ); + await $.native.enterTextByIndex( + password, + index: 2, + keyboardBehavior: KeyboardBehavior.alternative, + ); + await $.native.enterTextByIndex( + organization, + index: 3, + keyboardBehavior: KeyboardBehavior.alternative, + ); + + // Hide Keyboard + await $.native.tap(Selector(text: "Account sign-up")); + await Future.delayed(const Duration(seconds: 1)); + + await $.native.tap(Selector(text: "Sign up")); + + await $.native.waitUntilVisible(Selector(text: "Must be a valid email")); + }, + ); + + patrolTest( + 'Failure Sign up with empty Name field', + ($) async { + await $.pumpWidget(const MyApp()); + await $.pumpAndSettle(); + + await $.tap(find.byKey(const ValueKey("LoginButton"))); + await Future.delayed(const Duration(seconds: 5)); + + await $.native.tap(Selector(text: "Sign up")); + await $.native.waitUntilVisible(Selector(text: "Account sign-up")); + + await $.native.enterTextByIndex( + email, + index: 0, + keyboardBehavior: KeyboardBehavior.alternative, + ); + await $.native.enterTextByIndex( + "", + index: 1, + keyboardBehavior: KeyboardBehavior.alternative, + ); + await $.native.enterTextByIndex( + password, + index: 2, + keyboardBehavior: KeyboardBehavior.alternative, + ); + await $.native.enterTextByIndex( + organization, + index: 3, + keyboardBehavior: KeyboardBehavior.alternative, + ); + + // Hide Keyboard + await $.native.tap(Selector(text: "Account sign-up")); + await Future.delayed(const Duration(seconds: 1)); + + await $.native.tap(Selector(text: "Sign up")); + + await $.native.waitUntilVisible(Selector(text: "Name is required")); + }, + ); + + patrolTest( + 'Failure Sign up with empty Password field', + ($) async { + await $.pumpWidget(const MyApp()); + await $.pumpAndSettle(); + + await $.tap(find.byKey(const ValueKey("LoginButton"))); + await Future.delayed(const Duration(seconds: 5)); + + await $.native.tap(Selector(text: "Sign up")); + await $.native.waitUntilVisible(Selector(text: "Account sign-up")); + + await $.native.enterTextByIndex( + email, + index: 0, + keyboardBehavior: KeyboardBehavior.alternative, + ); + await $.native.enterTextByIndex( + name, + index: 1, + keyboardBehavior: KeyboardBehavior.alternative, + ); + await $.native.enterTextByIndex( + "", + index: 2, + keyboardBehavior: KeyboardBehavior.alternative, + ); + await $.native.enterTextByIndex( + organization, + index: 3, + keyboardBehavior: KeyboardBehavior.alternative, + ); + + // Hide Keyboard + await $.native.tap(Selector(text: "Account sign-up")); + await Future.delayed(const Duration(seconds: 1)); + + await $.native.tap(Selector(text: "Sign up")); + + await $.native.waitUntilVisible(Selector(text: "Password is required")); + }, + ); + + patrolTest( + 'Failure Sign up with empty CompanyName field', + ($) async { + await $.pumpWidget(const MyApp()); + await $.pumpAndSettle(); + + await $.tap(find.byKey(const ValueKey("LoginButton"))); + await Future.delayed(const Duration(seconds: 5)); + + await $.native.tap(Selector(text: "Sign up")); + await $.native.waitUntilVisible(Selector(text: "Account sign-up")); + + await $.native.enterTextByIndex( + email, + index: 0, + keyboardBehavior: KeyboardBehavior.alternative, + ); + await $.native.enterTextByIndex( + name, + index: 1, + keyboardBehavior: KeyboardBehavior.alternative, + ); + await $.native.enterTextByIndex( + password, + index: 2, + keyboardBehavior: KeyboardBehavior.alternative, + ); + await $.native.enterTextByIndex( + "", + index: 3, + keyboardBehavior: KeyboardBehavior.alternative, + ); + + // Hide Keyboard + await $.native.tap(Selector(text: "Account sign-up")); + await Future.delayed(const Duration(seconds: 1)); + + await $.native.tap(Selector(text: "Sign up")); + + await $.native.waitUntilVisible(Selector(text: "Company name is required")); + }, + ); +} diff --git a/example/integration_test/src/switch_tenant_test.dart b/example/integration_test/src/switch_tenant_test.dart new file mode 100644 index 0000000..d8ce2ab --- /dev/null +++ b/example/integration_test/src/switch_tenant_test.dart @@ -0,0 +1,80 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:frontegg_flutter_example/main.dart'; +import 'package:patrol/patrol.dart'; + +void main() { + late final String email; + late final String password; + late final String tenantId1; + late final String tenantId2; + + late final String tenantName1; + late final String tenantName2; + + patrolSetUp(() { + email = const String.fromEnvironment('LOGIN_EMAIL'); + password = const String.fromEnvironment('LOGIN_PASSWORD'); + + tenantId1 = const String.fromEnvironment('TENANT_ID_1'); + tenantId2 = const String.fromEnvironment('TENANT_ID_2'); + + tenantName1 = const String.fromEnvironment('TENANT_NAME_1'); + tenantName2 = const String.fromEnvironment('TENANT_NAME_2'); + }); + + patrolTest( + 'Success tenant switch', + ($) async { + await $.pumpWidget(const MyApp()); + await $.pumpAndSettle(); + + await $.tap(find.byKey(const ValueKey("LoginButton"))); + await Future.delayed(const Duration(seconds: 5)); + + await $.native.enterTextByIndex( + email, + index: 0, + keyboardBehavior: KeyboardBehavior.alternative, + timeout: const Duration(seconds: 15), + ); + + await $.native.tap(Selector(text: "Continue")); + + await $.native.enterTextByIndex( + password, + index: 1, + keyboardBehavior: KeyboardBehavior.alternative, + timeout: const Duration(seconds: 15), + ); + + await $.native.tap(Selector(text: "Sign in")); + + await $.waitUntilVisible( + find.text("Logout"), + timeout: const Duration(seconds: 15), + ); + + // Switch to Tenant Tab + await $.tap(find.byKey(const ValueKey("TenantTab"))); + await $.pumpAndSettle(); + + // Switch tenant 2 + await $.tap(find.byKey(ValueKey(tenantId2))); + await $.pumpAndSettle(); + await $.waitUntilVisible(find.textContaining("$tenantName2 (active)", findRichText: true)); + + // Switch tenant 1 + await $.tap(find.byKey(ValueKey(tenantId1))); + await $.pumpAndSettle(); + await $.waitUntilVisible(find.textContaining("$tenantName1 (active)", findRichText: true)); + + // Logout + await $.tap(find.byKey(const ValueKey("ProfileTab"))); + await $.pumpAndSettle(); + + await $.tap(find.byKey(const ValueKey("LogoutButton"))); + await $.pumpAndSettle(); + }, + ); +} diff --git a/example/ios/Podfile b/example/ios/Podfile index 04c36cf..c44106a 100644 --- a/example/ios/Podfile +++ b/example/ios/Podfile @@ -32,8 +32,9 @@ target 'Runner' do use_modular_headers! flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) - target 'RunnerTests' do - inherit! :search_paths + + target 'RunnerUITests' do + inherit! :complete end end diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock index ce87498..2ab1560 100644 --- a/example/ios/Podfile.lock +++ b/example/ios/Podfile.lock @@ -1,4 +1,5 @@ PODS: + - CocoaAsyncSocket (7.6.5) - Flutter (1.0.0) - frontegg_flutter (1.0.6): - Flutter @@ -6,14 +7,20 @@ PODS: - FronteggSwift (1.2.31) - integration_test (0.0.1): - Flutter + - patrol (0.0.1): + - CocoaAsyncSocket (~> 7.6) + - Flutter + - FlutterMacOS DEPENDENCIES: - Flutter (from `Flutter`) - frontegg_flutter (from `.symlinks/plugins/frontegg_flutter/ios`) - integration_test (from `.symlinks/plugins/integration_test/ios`) + - patrol (from `.symlinks/plugins/patrol/darwin`) SPEC REPOS: trunk: + - CocoaAsyncSocket - FronteggSwift EXTERNAL SOURCES: @@ -23,13 +30,17 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/frontegg_flutter/ios" integration_test: :path: ".symlinks/plugins/integration_test/ios" + patrol: + :path: ".symlinks/plugins/patrol/darwin" SPEC CHECKSUMS: + CocoaAsyncSocket: 065fd1e645c7abab64f7a6a2007a48038fdc6a99 Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7 frontegg_flutter: 4c3493fd2835bf63d7322c33f30095236785f050 FronteggSwift: fe65e3758373aae89361d30aa3c5ec9b5d96fc18 integration_test: 252f60fa39af5e17c3aa9899d35d908a0721b573 + patrol: 0564cee315ff6c86fb802b3647db05cc2d3d0624 -PODFILE CHECKSUM: 1959d098c91d8a792531a723c4a9d7e9f6a01e38 +PODFILE CHECKSUM: c9be09f6a61958d6788db8b9ee489767b65cfa92 COCOAPODS: 1.15.2 diff --git a/example/ios/Runner.xcodeproj/project.pbxproj b/example/ios/Runner.xcodeproj/project.pbxproj index 6229ef3..637333e 100644 --- a/example/ios/Runner.xcodeproj/project.pbxproj +++ b/example/ios/Runner.xcodeproj/project.pbxproj @@ -8,19 +8,19 @@ /* Begin PBXBuildFile section */ 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; - 331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C807B294A618700263BE5 /* RunnerTests.swift */; }; 37500A84C02F75E2C9FEE8AC /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1077FBEDE727ECD84DEF6DCE /* Pods_Runner.framework */; }; 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; + 457722762D071AEF0058D3CA /* RunnerUITests.m in Sources */ = {isa = PBXBuildFile; fileRef = 457722742D071AEF0058D3CA /* RunnerUITests.m */; }; 45A8B1F22C7C64BE00E46965 /* Frontegg.plist in Resources */ = {isa = PBXBuildFile; fileRef = 45A8B1F12C7C64BE00E46965 /* Frontegg.plist */; }; 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; - B1B3BD91A34B073C6A5130B0 /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 23BDFC768B291813C2C7D9F6 /* Pods_RunnerTests.framework */; }; + ACE614A05BF3F39BA4A8E7CB /* Pods_Runner_RunnerUITests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DAB89492F93B6A5C7EE033F5 /* Pods_Runner_RunnerUITests.framework */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ - 331C8085294A63A400263BE5 /* PBXContainerItemProxy */ = { + 4577226C2D0719C00058D3CA /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 97C146E61CF9000F007C117D /* Project object */; proxyType = 1; @@ -47,15 +47,16 @@ 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 = ""; }; 23BDFC768B291813C2C7D9F6 /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 331C807B294A618700263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = ""; }; - 331C8081294A63A400263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; 43D1935C949734F254C4E697 /* Pods-RunnerTests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.profile.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.profile.xcconfig"; sourceTree = ""; }; + 457722662D0719C00058D3CA /* RunnerUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 457722742D071AEF0058D3CA /* RunnerUITests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RunnerUITests.m; sourceTree = ""; }; 45A8B1F12C7C64BE00E46965 /* Frontegg.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Frontegg.plist; sourceTree = ""; }; 45B6A8D82C18895700AC839D /* RunnerRelease.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = RunnerRelease.entitlements; sourceTree = ""; }; 45B6A8D92C1889C200AC839D /* Runner.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Runner.entitlements; sourceTree = ""; }; 45C0BA372C189294002CFC6C /* RunnerDebug.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = RunnerDebug.entitlements; sourceTree = ""; }; 5FE542CC9283FECB4F41F740 /* 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 = ""; }; + 676F6E8BC5D89190ED1F0100 /* 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 = ""; }; 6F0A8CFAB4E54471B253560F /* Pods-RunnerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release.xcconfig"; sourceTree = ""; }; 72FE6906BAEBBEE779A3FEAB /* Pods-RunnerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug.xcconfig"; sourceTree = ""; }; 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; @@ -69,15 +70,18 @@ 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 = ""; }; + C70146A59409FD915AEE910F /* 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 = ""; }; D8FA32ECBAB49AF3072AEA31 /* 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 = ""; }; + DAB89492F93B6A5C7EE033F5 /* Pods_Runner_RunnerUITests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner_RunnerUITests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + E70A2787799D5E18794660CE /* 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 = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ - 69ED80E0CAF0B42A6D096970 /* Frameworks */ = { + 457722632D0719C00058D3CA /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - B1B3BD91A34B073C6A5130B0 /* Pods_RunnerTests.framework in Frameworks */, + ACE614A05BF3F39BA4A8E7CB /* Pods_Runner_RunnerUITests.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -92,12 +96,12 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ - 331C8082294A63A400263BE5 /* RunnerTests */ = { + 457722752D071AEF0058D3CA /* RunnerUITests */ = { isa = PBXGroup; children = ( - 331C807B294A618700263BE5 /* RunnerTests.swift */, + 457722742D071AEF0058D3CA /* RunnerUITests.m */, ); - path = RunnerTests; + path = RunnerUITests; sourceTree = ""; }; 8820188ACF155A7E73677C18 /* Pods */ = { @@ -109,6 +113,9 @@ 72FE6906BAEBBEE779A3FEAB /* Pods-RunnerTests.debug.xcconfig */, 6F0A8CFAB4E54471B253560F /* Pods-RunnerTests.release.xcconfig */, 43D1935C949734F254C4E697 /* Pods-RunnerTests.profile.xcconfig */, + 676F6E8BC5D89190ED1F0100 /* Pods-Runner-RunnerUITests.debug.xcconfig */, + E70A2787799D5E18794660CE /* Pods-Runner-RunnerUITests.release.xcconfig */, + C70146A59409FD915AEE910F /* Pods-Runner-RunnerUITests.profile.xcconfig */, ); path = Pods; sourceTree = ""; @@ -129,8 +136,8 @@ children = ( 9740EEB11CF90186004384FC /* Flutter */, 97C146F01CF9000F007C117D /* Runner */, + 457722752D071AEF0058D3CA /* RunnerUITests */, 97C146EF1CF9000F007C117D /* Products */, - 331C8082294A63A400263BE5 /* RunnerTests */, 8820188ACF155A7E73677C18 /* Pods */, E9EB366081269FF5A13C1B89 /* Frameworks */, ); @@ -140,7 +147,7 @@ isa = PBXGroup; children = ( 97C146EE1CF9000F007C117D /* Runner.app */, - 331C8081294A63A400263BE5 /* RunnerTests.xctest */, + 457722662D0719C00058D3CA /* RunnerUITests.xctest */, ); name = Products; sourceTree = ""; @@ -169,6 +176,7 @@ children = ( 1077FBEDE727ECD84DEF6DCE /* Pods_Runner.framework */, 23BDFC768B291813C2C7D9F6 /* Pods_RunnerTests.framework */, + DAB89492F93B6A5C7EE033F5 /* Pods_Runner_RunnerUITests.framework */, ); name = Frameworks; sourceTree = ""; @@ -176,24 +184,27 @@ /* End PBXGroup section */ /* Begin PBXNativeTarget section */ - 331C8080294A63A400263BE5 /* RunnerTests */ = { + 457722652D0719C00058D3CA /* RunnerUITests */ = { isa = PBXNativeTarget; - buildConfigurationList = 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */; + buildConfigurationList = 457722712D0719C00058D3CA /* Build configuration list for PBXNativeTarget "RunnerUITests" */; buildPhases = ( - 99B072D23FBA4AB0C29BD63A /* [CP] Check Pods Manifest.lock */, - 331C807D294A63A400263BE5 /* Sources */, - 331C807F294A63A400263BE5 /* Resources */, - 69ED80E0CAF0B42A6D096970 /* Frameworks */, + 640992BE11F5A95BF23B8960 /* [CP] Check Pods Manifest.lock */, + 457722772D071B4C0058D3CA /* xcode_backend build */, + 457722622D0719C00058D3CA /* Sources */, + 457722632D0719C00058D3CA /* Frameworks */, + 457722642D0719C00058D3CA /* Resources */, + F46720EE90EEFB05A95D8BFE /* [CP] Embed Pods Frameworks */, + 457722782D071B4D0058D3CA /* xcode_backend embed_and_thin */, ); buildRules = ( ); dependencies = ( - 331C8086294A63A400263BE5 /* PBXTargetDependency */, + 4577226D2D0719C00058D3CA /* PBXTargetDependency */, ); - name = RunnerTests; - productName = RunnerTests; - productReference = 331C8081294A63A400263BE5 /* RunnerTests.xctest */; - productType = "com.apple.product-type.bundle.unit-test"; + name = RunnerUITests; + productName = RunnerUITests; + productReference = 457722662D0719C00058D3CA /* RunnerUITests.xctest */; + productType = "com.apple.product-type.bundle.ui-testing"; }; 97C146ED1CF9000F007C117D /* Runner */ = { isa = PBXNativeTarget; @@ -223,12 +234,12 @@ 97C146E61CF9000F007C117D /* Project object */ = { isa = PBXProject; attributes = { - BuildIndependentTargetsInParallel = YES; + BuildIndependentTargetsInParallel = NO; LastUpgradeCheck = 1510; ORGANIZATIONNAME = ""; TargetAttributes = { - 331C8080294A63A400263BE5 = { - CreatedOnToolsVersion = 14.0; + 457722652D0719C00058D3CA = { + CreatedOnToolsVersion = 16.1; TestTargetID = 97C146ED1CF9000F007C117D; }; 97C146ED1CF9000F007C117D = { @@ -251,13 +262,13 @@ projectRoot = ""; targets = ( 97C146ED1CF9000F007C117D /* Runner */, - 331C8080294A63A400263BE5 /* RunnerTests */, + 457722652D0719C00058D3CA /* RunnerUITests */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ - 331C807F294A63A400263BE5 /* Resources */ = { + 457722642D0719C00058D3CA /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( @@ -312,6 +323,42 @@ shellPath = /bin/sh; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; }; + 457722772D071B4C0058D3CA /* xcode_backend build */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + ); + name = "xcode_backend build"; + outputFileListPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build\n"; + }; + 457722782D071B4D0058D3CA /* 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 = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin\n"; + }; 5B9B6EA96B953F432275D1F1 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -334,6 +381,28 @@ 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; }; + 640992BE11F5A95BF23B8960 /* [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; + }; 9740EEB61CF901F6004384FC /* Run Script */ = { isa = PBXShellScriptBuildPhase; alwaysOutOfDate = 1; @@ -349,36 +418,31 @@ shellPath = /bin/sh; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; }; - 99B072D23FBA4AB0C29BD63A /* [CP] Check Pods Manifest.lock */ = { + F46720EE90EEFB05A95D8BFE /* [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", ); - 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-RunnerTests-checkManifestLockResult.txt", + "${PODS_ROOT}/Target Support Files/Pods-Runner-RunnerUITests/Pods-Runner-RunnerUITests-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-RunnerUITests/Pods-Runner-RunnerUITests-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ - 331C807D294A63A400263BE5 /* Sources */ = { + 457722622D0719C00058D3CA /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */, + 457722762D071AEF0058D3CA /* RunnerUITests.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -394,10 +458,10 @@ /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ - 331C8086294A63A400263BE5 /* PBXTargetDependency */ = { + 4577226D2D0719C00058D3CA /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 97C146ED1CF9000F007C117D /* Runner */; - targetProxy = 331C8085294A63A400263BE5 /* PBXContainerItemProxy */; + targetProxy = 4577226C2D0719C00058D3CA /* PBXContainerItemProxy */; }; /* End PBXTargetDependency section */ @@ -467,7 +531,7 @@ IPHONEOS_DEPLOYMENT_TARGET = 14.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; - SUPPORTED_PLATFORMS = iphoneos; + SUPPORTED_PLATFORMS = "iphonesimulator iphoneos"; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; }; @@ -486,6 +550,7 @@ DEVELOPMENT_TEAM = 3R2X6557U2; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = "Frontegg Demo"; IPHONEOS_DEPLOYMENT_TARGET = 14.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", @@ -494,59 +559,111 @@ PRODUCT_BUNDLE_IDENTIFIER = com.frontegg.demo; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; + SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = 1; VERSIONING_SYSTEM = "apple-generic"; }; name = Profile; }; - 331C8088294A63A400263BE5 /* Debug */ = { + 4577226E2D0719C00058D3CA /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 72FE6906BAEBBEE779A3FEAB /* Pods-RunnerTests.debug.xcconfig */; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; buildSettings = { - BUNDLE_LOADER = "$(TEST_HOST)"; + 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 = 3R2X6557U2; + ENABLE_USER_SCRIPT_SANDBOXING = NO; + GCC_C_LANGUAGE_STANDARD = gnu17; GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 14.0; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = com.frontegg.fronteggFlutterExample.RunnerTests; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = com.frontegg.demo.RunnerUITests; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 5.0; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; + SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO; + SWIFT_EMIT_LOC_STRINGS = NO; + TARGETED_DEVICE_FAMILY = 1; + TEST_TARGET_NAME = Runner; }; name = Debug; }; - 331C8089294A63A400263BE5 /* Release */ = { + 4577226F2D0719C00058D3CA /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 6F0A8CFAB4E54471B253560F /* Pods-RunnerTests.release.xcconfig */; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; buildSettings = { - BUNDLE_LOADER = "$(TEST_HOST)"; + 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 = 3R2X6557U2; + ENABLE_USER_SCRIPT_SANDBOXING = NO; + GCC_C_LANGUAGE_STANDARD = gnu17; GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 14.0; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = com.frontegg.fronteggFlutterExample.RunnerTests; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = com.frontegg.demo.RunnerUITests; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 5.0; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; + SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO; + SWIFT_EMIT_LOC_STRINGS = NO; + TARGETED_DEVICE_FAMILY = 1; + TEST_TARGET_NAME = Runner; }; name = Release; }; - 331C808A294A63A400263BE5 /* Profile */ = { + 457722702D0719C00058D3CA /* Profile */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 43D1935C949734F254C4E697 /* Pods-RunnerTests.profile.xcconfig */; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; buildSettings = { - BUNDLE_LOADER = "$(TEST_HOST)"; + 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 = 3R2X6557U2; + ENABLE_USER_SCRIPT_SANDBOXING = NO; + GCC_C_LANGUAGE_STANDARD = gnu17; GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 14.0; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = com.frontegg.fronteggFlutterExample.RunnerTests; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = com.frontegg.demo.RunnerUITests; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 5.0; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; + SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO; + SWIFT_EMIT_LOC_STRINGS = NO; + TARGETED_DEVICE_FAMILY = 1; + TEST_TARGET_NAME = Runner; }; name = Profile; }; @@ -653,7 +770,7 @@ IPHONEOS_DEPLOYMENT_TARGET = 14.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; - SUPPORTED_PLATFORMS = iphoneos; + SUPPORTED_PLATFORMS = "iphonesimulator iphoneos"; SWIFT_COMPILATION_MODE = wholemodule; SWIFT_OPTIMIZATION_LEVEL = "-O"; TARGETED_DEVICE_FAMILY = "1,2"; @@ -674,6 +791,7 @@ DEVELOPMENT_TEAM = 3R2X6557U2; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = "Frontegg Demo"; IPHONEOS_DEPLOYMENT_TARGET = 14.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", @@ -682,9 +800,14 @@ PRODUCT_BUNDLE_IDENTIFIER = com.frontegg.demo; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; + SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = 1; VERSIONING_SYSTEM = "apple-generic"; }; name = Debug; @@ -702,6 +825,7 @@ DEVELOPMENT_TEAM = 3R2X6557U2; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = "Frontegg Demo"; IPHONEOS_DEPLOYMENT_TARGET = 14.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", @@ -710,8 +834,13 @@ PRODUCT_BUNDLE_IDENTIFIER = com.frontegg.demo; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; + SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = 1; VERSIONING_SYSTEM = "apple-generic"; }; name = Release; @@ -719,12 +848,12 @@ /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ - 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */ = { + 457722712D0719C00058D3CA /* Build configuration list for PBXNativeTarget "RunnerUITests" */ = { isa = XCConfigurationList; buildConfigurations = ( - 331C8088294A63A400263BE5 /* Debug */, - 331C8089294A63A400263BE5 /* Release */, - 331C808A294A63A400263BE5 /* Profile */, + 4577226E2D0719C00058D3CA /* Debug */, + 4577226F2D0719C00058D3CA /* Release */, + 457722702D0719C00058D3CA /* Profile */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; diff --git a/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index 8e3ca5d..52bbc48 100644 --- a/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -38,13 +38,12 @@ + skipped = "NO"> diff --git a/example/ios/Runner/Frontegg.plist b/example/ios/Runner/Frontegg.plist index 3d32f08..3a3e9a4 100644 --- a/example/ios/Runner/Frontegg.plist +++ b/example/ios/Runner/Frontegg.plist @@ -5,10 +5,12 @@ embeddedMode baseUrl - https://autheu.davidantoon.me + https://app-axsx38m96enh.frontegg.com clientId - b6adfe4c-d695-4c04-b95f-3ec9fd0c6cca + 392b348b-a37c-471f-8f1b-2c35d23aa7e6 logLevel trace + keepUserLoggedInAfterReinstall + diff --git a/example/ios/Runner/Info.plist b/example/ios/Runner/Info.plist index cb0f783..7ef89ae 100644 --- a/example/ios/Runner/Info.plist +++ b/example/ios/Runner/Info.plist @@ -7,7 +7,7 @@ CFBundleDevelopmentRegion $(DEVELOPMENT_LANGUAGE) CFBundleDisplayName - Frontegg Flutter + Frontegg Demo CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier diff --git a/example/ios/RunnerTests/RunnerTests.swift b/example/ios/RunnerTests/RunnerTests.swift deleted file mode 100644 index 7cb9788..0000000 --- a/example/ios/RunnerTests/RunnerTests.swift +++ /dev/null @@ -1,26 +0,0 @@ -import Flutter -import UIKit -import XCTest - -@testable import frontegg_flutter - -// This demonstrates a simple unit test of the Swift portion of this plugin's implementation. -// -// See https://developer.apple.com/documentation/xctest for more information about using XCTest. - -class RunnerTests: XCTestCase { - - func testGetPlatformVersion() { - let plugin = FronteggFlutterPlugin() - - let call = FlutterMethodCall(methodName: "getPlatformVersion", arguments: []) - - let resultExpectation = expectation(description: "result block must be called.") - plugin.handle(call) { result in - XCTAssertEqual(result as! String, "iOS " + UIDevice.current.systemVersion) - resultExpectation.fulfill() - } - waitForExpectations(timeout: 1) - } - -} diff --git a/example/ios/RunnerUITests/RunnerUITests.m b/example/ios/RunnerUITests/RunnerUITests.m new file mode 100644 index 0000000..bfc5dbd --- /dev/null +++ b/example/ios/RunnerUITests/RunnerUITests.m @@ -0,0 +1,5 @@ +@import XCTest; +@import patrol; +@import ObjectiveC.runtime; + +PATROL_INTEGRATION_TEST_IOS_RUNNER(RunnerUITests) diff --git a/example/lib/login_page.dart b/example/lib/login_page.dart index 9522b33..d9e9cd9 100644 --- a/example/lib/login_page.dart +++ b/example/lib/login_page.dart @@ -39,6 +39,7 @@ class LoginPage extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.center, children: [ ElevatedButton( + key: const ValueKey("LoginButton"), child: const Text("Login"), onPressed: () async { await frontegg.login(); diff --git a/example/lib/tenants_tab.dart b/example/lib/tenants_tab.dart index 919fc43..afdf882 100644 --- a/example/lib/tenants_tab.dart +++ b/example/lib/tenants_tab.dart @@ -26,19 +26,27 @@ class TenantsTab extends StatelessWidget { (e) { final isActive = user.activeTenant.tenantId == e.tenantId; return ListTile( - title: Row( - children: [ - Text(e.name), - if (isActive) const SizedBox(width: 10), - if (isActive) - const Text( - "(active)", - style: TextStyle( - fontSize: 12, - fontWeight: FontWeight.w300, + key: ValueKey(e.tenantId), + title: RichText( + text: TextSpan( + children: [ + TextSpan( + text: e.name, + style: const TextStyle( + color: Colors.black, ), ), - ], + if (isActive) + const TextSpan( + text: " (active)", + style: TextStyle( + fontSize: 12, + fontWeight: FontWeight.w300, + color: Colors.black, + ), + ), + ], + ), ), onTap: () { frontegg.switchTenant(e.tenantId); diff --git a/example/lib/user_page.dart b/example/lib/user_page.dart index cb6df37..96d984d 100644 --- a/example/lib/user_page.dart +++ b/example/lib/user_page.dart @@ -43,10 +43,12 @@ class _UserPageState extends State { }, items: const [ BottomNavigationBarItem( + key: ValueKey("ProfileTab"), icon: Icon(Icons.person), label: "Profile", ), BottomNavigationBarItem( + key: ValueKey("TenantTab"), icon: Icon(Icons.notifications), label: "Tenant", ), diff --git a/example/lib/user_tab.dart b/example/lib/user_tab.dart index 702d17a..cc8916a 100644 --- a/example/lib/user_tab.dart +++ b/example/lib/user_tab.dart @@ -56,9 +56,8 @@ class UserTab extends StatelessWidget { ), if (!state.isLoading) ElevatedButton( - child: const Text( - "Logout", - ), + key: const ValueKey("LogoutButton"), + child: const Text("Logout"), onPressed: () async { await frontegg.logout(); debugPrint("Logout Finished"); diff --git a/example/pubspec.lock b/example/pubspec.lock index 7d44f63..03ae7ce 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -37,10 +37,34 @@ packages: dependency: transitive description: name: collection - sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a + sha256: a1ace0a119f20aabc852d165077c036cd864315bd99b7eaa10a60100341941bf url: "https://pub.dev" source: hosted - version: "1.18.0" + version: "1.19.0" + crypto: + dependency: transitive + description: + name: crypto + sha256: "1e445881f28f22d6140f181e07737b22f1e099a5e1ff94b0af2f9e4a463f4855" + url: "https://pub.dev" + source: hosted + version: "3.0.6" + dispose_scope: + dependency: transitive + description: + name: dispose_scope + sha256: "48ec38ca2631c53c4f8fa96b294c801e55c335db5e3fb9f82cede150cfe5a2af" + url: "https://pub.dev" + source: hosted + version: "2.1.0" + equatable: + dependency: transitive + description: + name: equatable + sha256: "567c64b3cb4cf82397aac55f4f0cbd3ca20d77c6c03bedbc4ceaddc08904aef7" + url: "https://pub.dev" + source: hosted + version: "2.0.7" fake_async: dependency: transitive description: @@ -57,6 +81,14 @@ packages: url: "https://pub.dev" source: hosted version: "7.0.0" + fixnum: + dependency: transitive + description: + name: fixnum + sha256: b6dc7065e46c974bc7c5f143080a6764ec7a4be6da1285ececdc37be96de53be + url: "https://pub.dev" + source: hosted + version: "1.1.1" flutter: dependency: "direct main" description: flutter @@ -92,27 +124,51 @@ packages: description: flutter source: sdk version: "0.0.0" + http: + dependency: transitive + description: + name: http + sha256: fe7ab022b76f3034adc518fb6ea04a82387620e19977665ea18d30a1cf43442f + url: "https://pub.dev" + source: hosted + version: "1.3.0" + http_parser: + dependency: transitive + description: + name: http_parser + sha256: "178d74305e7866013777bab2c3d8726205dc5a4dd935297175b19a23a2e66571" + url: "https://pub.dev" + source: hosted + version: "4.1.2" integration_test: dependency: "direct dev" description: flutter source: sdk version: "0.0.0" + json_annotation: + dependency: transitive + description: + name: json_annotation + sha256: "1ce844379ca14835a50d2f019a3099f419082cfdd231cd86a142af94dd5c6bb1" + url: "https://pub.dev" + source: hosted + version: "4.9.0" leak_tracker: dependency: transitive description: name: leak_tracker - sha256: "7f0df31977cb2c0b88585095d168e689669a2cc9b97c309665e3386f3e9d341a" + sha256: "7bb2830ebd849694d1ec25bf1f44582d6ac531a57a365a803a6034ff751d2d06" url: "https://pub.dev" source: hosted - version: "10.0.4" + version: "10.0.7" leak_tracker_flutter_testing: dependency: transitive description: name: leak_tracker_flutter_testing - sha256: "06e98f569d004c1315b991ded39924b21af84cf14cc94791b8aea337d25b57f8" + sha256: "9491a714cca3667b60b5c420da8217e6de0d1ba7a5ec322fab01758f6998f379" url: "https://pub.dev" source: hosted - version: "3.0.3" + version: "3.0.8" leak_tracker_testing: dependency: transitive description: @@ -141,18 +197,18 @@ packages: dependency: transitive description: name: material_color_utilities - sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a" + sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec url: "https://pub.dev" source: hosted - version: "0.8.0" + version: "0.11.1" meta: dependency: transitive description: name: meta - sha256: "7687075e408b093f36e6bbf6c91878cc0d4cd10f409506f7bc996f68220b9136" + sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7 url: "https://pub.dev" source: hosted - version: "1.12.0" + version: "1.15.0" path: dependency: transitive description: @@ -161,14 +217,38 @@ packages: url: "https://pub.dev" source: hosted version: "1.9.0" + patrol: + dependency: "direct dev" + description: + name: patrol + sha256: "2bb991db06b5e1eb2ec5c803067c41316d94d01dda93ddf16f5342073d791a20" + url: "https://pub.dev" + source: hosted + version: "3.14.0" + patrol_finders: + dependency: transitive + description: + name: patrol_finders + sha256: "4c6d78e00362fd15d7c21cfac110e501d08ada7d77000bad139b0c3c2e27ccaf" + url: "https://pub.dev" + source: hosted + version: "2.7.0" + patrol_log: + dependency: transitive + description: + name: patrol_log + sha256: "98b2701400c7a00b11533ab942bdeb44c3c714746e7cdb12e6cb93b6d06361da" + url: "https://pub.dev" + source: hosted + version: "0.3.0" platform: dependency: transitive description: name: platform - sha256: "12220bb4b65720483f8fa9450b4332347737cf8213dd2840d8b2c823e47243ec" + sha256: "9b71283fc13df574056616011fb138fd3b793ea47cc509c189a6c3fa5f8a1a65" url: "https://pub.dev" source: hosted - version: "3.1.4" + version: "3.1.5" plugin_platform_interface: dependency: transitive description: @@ -193,11 +273,19 @@ packages: url: "https://pub.dev" source: hosted version: "0.28.0" + shelf: + dependency: transitive + description: + name: shelf + sha256: e7dd780a7ffb623c57850b33f43309312fc863fb6aa3d276a754bb299839ef12 + url: "https://pub.dev" + source: hosted + version: "1.4.2" sky_engine: dependency: transitive description: flutter source: sdk - version: "0.0.99" + version: "0.0.0" source_span: dependency: transitive description: @@ -206,14 +294,22 @@ packages: 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" + sha256: "9f47fd3630d76be3ab26f0ee06d213679aa425996925ff3feffdec504931c377" url: "https://pub.dev" source: hosted - version: "1.11.1" + version: "1.12.0" stream_channel: dependency: transitive description: @@ -226,10 +322,10 @@ packages: dependency: transitive description: name: string_scanner - sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" + sha256: "688af5ed3402a4bde5b3a6c15fd768dbf2621a614950b17f04626c431ab3c4c3" url: "https://pub.dev" source: hosted - version: "1.2.0" + version: "1.3.0" sync_http: dependency: transitive description: @@ -250,10 +346,26 @@ packages: dependency: transitive description: name: test_api - sha256: "9955ae474176f7ac8ee4e989dadfb411a58c30415bcfb648fa04b2b8a03afa7f" + sha256: "664d3a9a64782fcdeb83ce9c6b39e78fd2971d4e37827b9b06c3aa1edc5e760c" + url: "https://pub.dev" + source: hosted + version: "0.7.3" + typed_data: + dependency: transitive + description: + name: typed_data + sha256: f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006 url: "https://pub.dev" source: hosted - version: "0.7.0" + version: "1.4.0" + uuid: + dependency: "direct dev" + description: + name: uuid + sha256: a5be9ef6618a7ac1e964353ef476418026db906c4facdedaa299b7a2e71690ff + url: "https://pub.dev" + source: hosted + version: "4.5.1" vector_math: dependency: transitive description: @@ -266,18 +378,26 @@ packages: dependency: transitive description: name: vm_service - sha256: "3923c89304b715fb1eb6423f017651664a03bf5f4b29983627c4da791f74a4ec" + sha256: f6be3ed8bd01289b34d679c2b62226f63c0e69f9fd2e50a6b3c1c729a961041b + url: "https://pub.dev" + source: hosted + version: "14.3.0" + web: + dependency: transitive + description: + name: web + sha256: cd3543bd5798f6ad290ea73d210f423502e71900302dde696f8bff84bf89a1cb url: "https://pub.dev" source: hosted - version: "14.2.1" + version: "1.1.0" webdriver: dependency: transitive description: name: webdriver - sha256: "003d7da9519e1e5f329422b36c4dcdf18d7d2978d1ba099ea4e45ba490ed845e" + sha256: "3d773670966f02a646319410766d3b5e1037efb7f07cc68f844d5e06cd4d61c8" url: "https://pub.dev" source: hosted - version: "3.0.3" + version: "3.0.4" sdks: - dart: ">=3.3.4 <4.0.0" - flutter: ">=3.18.0-18.0.pre.54" + dart: ">=3.5.0 <4.0.0" + flutter: ">=3.24.0" diff --git a/example/pubspec.yaml b/example/pubspec.yaml index b7205eb..004b477 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -18,6 +18,15 @@ dev_dependencies: flutter_test: sdk: flutter flutter_lints: ^4.0.0 + patrol: ^3.13.1 + uuid: ^4.5.1 flutter: uses-material-design: true + +patrol: + app_name: Frontegg Demo + android: + package_name: com.frontegg.demo + ios: + bundle_id: com.frontegg.demo diff --git a/run_integration_test.sh b/run_integration_test.sh new file mode 100644 index 0000000..820f7d7 --- /dev/null +++ b/run_integration_test.sh @@ -0,0 +1,50 @@ +#!/bin/sh + +while getopts ":a:i:t:" opt; do + case $opt in + a) android_device="$OPTARG" + ;; + i) ios_device="$OPTARG" + ;; + t) test_path="$OPTARG" + ;; + \?) echo "Invalid option -$OPTARG" >&2 + exit 1 + ;; + esac + + case $OPTARG in + -*) echo "Option $opt needs a valid argument" + exit 1 + ;; + esac +done + +cd example || exit 1 + +flutter pub global activate patrol_cli + +patrol doctor + + +if [ -z "$test_path" ]; then + test_path="integration_test/src/" +fi + +echo "Starting test on $test_path" + +# iOS run +if [ -n "$ios_device" ]; then + echo "Start iOS testing on '$ios_device' device..." + patrol test -d "$ios_device" -t "$test_path" --uninstall +fi + +# Android run +if [ -n "$android_device" ]; then + echo "Start Android testing on '$android_device' device..." + patrol test -d "$android_device" -t "$test_path" --uninstall +fi + + + +