diff --git a/README.md b/README.md index 59b619d2a..5d6ae4b15 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,8 @@ ![Patrol promotial graphics][promo_graphics] Simple yet powerful Flutter-first UI testing framework overcoming limitations of -`flutter_test`, `integration_test`, and `flutter_driver`. +`flutter_test`, `integration_test`, and `flutter_driver`. Created and supported +by [LeanCode](https://leancode.co). Learn more about Patrol: diff --git a/docs.json b/docs.json index aa6edb8d8..417f1e32a 100644 --- a/docs.json +++ b/docs.json @@ -20,19 +20,19 @@ [ "Finders", [ - ["Overview", "/patrol/finders/overview"], - ["Usage", "/patrol/finders/usage"], - ["Advanced", "/patrol/finders/advanced"], - ["Using Patrol finders in widget tests", "/patrol/finders/finders-setup"] + ["Overview", "/finders/overview"], + ["Usage", "/finders/usage"], + ["Advanced", "/finders/advanced"], + ["Using Patrol finders in widget tests", "/finders/finders-setup"] ] ], [ "Native automation", [ - ["Overview", "/patrol/native/overview"], - ["Usage", "/patrol/native/usage"], - ["Advanced", "/patrol/native/advanced"], - ["Feature parity", "/patrol/native/feature-parity"] + ["Overview", "/native/overview"], + ["Usage", "/native/usage"], + ["Advanced", "/native/advanced"], + ["Feature parity", "/native/feature-parity"] ] ], [ @@ -62,6 +62,7 @@ ] ], ["Effective Patrol", "/effective-patrol"], - ["Tips and tricks", "/tips-and-tricks"] + ["Tips and tricks", "/tips-and-tricks"], + ["LeanCode", "https://leancode.co"] ] } diff --git a/docs/cli-commands/build.mdx b/docs/cli-commands/build.mdx index aa699fe06..2cf6c7582 100644 --- a/docs/cli-commands/build.mdx +++ b/docs/cli-commands/build.mdx @@ -34,7 +34,7 @@ Test Lab. It works the same as `patrol test`, except that it does run tests. ### Examples -**To build for Android in debug mode** +**To build a single test for Android in debug mode** ``` patrol build android --target integration_test/example_test.dart @@ -46,48 +46,29 @@ or alternatively (but redundantly): patrol build android --target integration_test/example_test.dart --debug ``` -**To build for iOS device in release mode** +**To build all tests for Android in debug mode** ``` -patrol build ios --target integration_test/example_test.dart --release +patrol build android ``` -**To build for iOS simulator in debug mode** +**To build a single test for iOS device in release mode** ``` -patrol build ios --target integration_test/example_test.dart --debug -``` - -### Caveats - -Only a single test target file can be built. For example, consider the following -`integration_test` directory containing 4 test targets: - -``` -integration_test/ -├── common.dart -├── example_test.dart -├── notifications_test.dart -├── permissions_location_test.dart -├── webview_login_test.dart +patrol build ios --target integration_test/example_test.dart --release ``` -Dart file must end with `_test.dart` to be considered to be a test. - -To build the app for testing on Android, you have to run: +**To build a single test for iOS simulator in debug mode** ``` -patrol build android --target +patrol build ios --target integration_test/example_test.dart --debug ``` -4 times, each time with a different `--target`, to get 4 different app binaries. - -These 4 different binaries are almost the same – the only difference is the -entrypoint. This is needlessly inefficient for apps with many tests, but it's a -design flaw in the way integration testing in Flutter works. - -[We know about this issue][bundling_issue] and we're aiming to fix it soon with -an approach we call "test bundling". This will dramatically speed up testing -apps with many integration tests. +### Under the hood -[bundling_issue]: https://github.com/leancodepl/patrol/issues/1004 +The `patrol build` command walks through hierarchy of the `integration_test` +directory and finds all files that end with `_test.dart`, and then creates an +additional "test bundle" file that references all the tests it found. Thanks to +this, all tests are built into a single app binary - only a single build is +required. If you're curious to learn more about this problem, see [Flutter issue +#115751](https://github.com/flutter/flutter/issues/115751) diff --git a/docs/patrol/finders/advanced.mdx b/docs/finders/advanced.mdx similarity index 100% rename from docs/patrol/finders/advanced.mdx rename to docs/finders/advanced.mdx diff --git a/docs/patrol/finders/finders-setup.mdx b/docs/finders/finders-setup.mdx similarity index 100% rename from docs/patrol/finders/finders-setup.mdx rename to docs/finders/finders-setup.mdx diff --git a/docs/patrol/finders/overview.mdx b/docs/finders/overview.mdx similarity index 100% rename from docs/patrol/finders/overview.mdx rename to docs/finders/overview.mdx diff --git a/docs/patrol/finders/usage.mdx b/docs/finders/usage.mdx similarity index 100% rename from docs/patrol/finders/usage.mdx rename to docs/finders/usage.mdx diff --git a/docs/getting-started.mdx b/docs/getting-started.mdx index a1a70584c..56caf1167 100644 --- a/docs/getting-started.mdx +++ b/docs/getting-started.mdx @@ -302,8 +302,8 @@ up. To run `integration_test/example_test.dart` on a local Android or iOS device To learn how to write Patrol tests, see [finders] and [native automation] sections. -[native automation]: /patrol/native/usage +[native automation]: /native/usage [finders]: /patrol/finders/usage [Using Patrol finders in widget tests]: /patrol/finders/finders-setup -[Here's why]: /patrol/native/advanced#embrace-the-native-tests +[Here's why]: /native/advanced#embrace-the-native-tests [Patrol CLI]: https://pub.dev/packages/patrol_cli diff --git a/docs/index.mdx b/docs/index.mdx index 43fec1aad..092e91744 100644 --- a/docs/index.mdx +++ b/docs/index.mdx @@ -3,14 +3,16 @@ title: Main description: The powerful Flutter-first UI testing framework. Ready for action! --- -# About +# Patrol by LeanCode ![Patrol promotial graphics][promo_graphics] -Patrol is a new testing framework for Flutter. It builds on top of Flutter's -existing test tooling to let you do things which were previously impossible. +Patrol is a powerful, open-source testing framework for Flutter apps created and +maintained by [LeanCode] – one of the leading Flutter development consultancies +in the world. Patrol builds on top of Flutter's existing test tooling to enable +you to do things which were previously impossible. -Patrol lets you [access native features of the platform][native] that the +It lets you [access native features of the platform][native] that the Flutter app is running on. Finally, you can interact with permission dialogs, notifications, WebViews, change device settings, toggle Wi-Fi, and much more – and you can code this very easily in plain Dart. @@ -24,23 +26,31 @@ Patrol is also a revamped, production-quality version of Flutter's built-in `integration_test` plugin. It fixes its shortcomings and enables features such as full isolation between tests and sharding. -Patrol is an open-source project which is being developed and maintained by us – -[LeanCode][leancode]! We use it to test our clients' production-grade apps, and -you can do the same! +Patrol is a fully open-source project and we're proud to share it with the +awesome Flutter community. -Learn more about Patrol: +At LeanCode, we use Patrol to test our clients' production-grade apps, and you +can do the same! -- [Read the article about the first public pre-release][article_0x] -- [Read the article about the stable 1.0 release][article_1x] -- [Read the article about the about how Patrol fixes integration_test][article_2x] +[Get Patrol from pub.dev now!][patrol_on_pubdev] -or [get Patrol from pub.dev!][patrol_on_pubdev] +### Learn more about Patrol + +See the talk we gave at Fluttercon 2023: + + + +or [read the article][article_2x] explaining how Patrol fixes deficiencies of +Flutter's official integration_test plugin. + +We also provide professional services related to Flutter app testing – check +them out: [![Automated UI testing services][services_graphics]][services] [leancode]: https://leancode.co -[native]: /patrol/native/overview -[finders]: /patrol/finders/overview +[native]: /native/overview +[finders]: /finders/overview [hot restart]: /cli-commands/develop [article_0x]: https://leancode.co/blog/patrol-flutter-first-ui-testing-framework [article_1x]: https://leancode.co/blog/patrol-1-0-powerful-flutter-ui-testing-framework @@ -48,4 +58,4 @@ or [get Patrol from pub.dev!][patrol_on_pubdev] [promo_graphics]: /assets/promo.png [patrol_on_pubdev]: https://pub.dev/packages/patrol [services_graphics]: /assets/services.png -[services]: https://leancode.co/products/automated-ui-testing-in-flutter?utm_source=patrol_page&utm_medium=banner&utm_campaign=service \ No newline at end of file +[services]: https://leancode.co/products/automated-ui-testing-in-flutter?utm_source=patrol_page&utm_medium=banner&utm_campaign=service diff --git a/docs/patrol/native/advanced.mdx b/docs/native/advanced.mdx similarity index 100% rename from docs/patrol/native/advanced.mdx rename to docs/native/advanced.mdx diff --git a/docs/patrol/native/feature-parity.mdx b/docs/native/feature-parity.mdx similarity index 99% rename from docs/patrol/native/feature-parity.mdx rename to docs/native/feature-parity.mdx index cd342402d..3d9f1729d 100644 --- a/docs/patrol/native/feature-parity.mdx +++ b/docs/native/feature-parity.mdx @@ -35,7 +35,7 @@ impossible to reach 100%. ### Platfom support Patrol works on virtual and physical devices running Android 5.0 (API 21) and -newer, and iOS 13 and newer. +newer, and iOS 11 and newer. [#244]: https://github.com/leancodepl/patrol/issues/244 [#282]: https://github.com/leancodepl/patrol/issues/282 diff --git a/docs/patrol/native/overview.mdx b/docs/native/overview.mdx similarity index 100% rename from docs/patrol/native/overview.mdx rename to docs/native/overview.mdx diff --git a/docs/patrol/native/usage.mdx b/docs/native/usage.mdx similarity index 100% rename from docs/patrol/native/usage.mdx rename to docs/native/usage.mdx diff --git a/packages/patrol/CHANGELOG.md b/packages/patrol/CHANGELOG.md index 0e8bb1daa..ab0148d6c 100644 --- a/packages/patrol/CHANGELOG.md +++ b/packages/patrol/CHANGELOG.md @@ -1,7 +1,12 @@ -## 2.4.0-dev.1 +## 2.4.0-dev.3 - Add support for iOS 11 and 12 (#1733) +## 2.3.1 + +- Add support for iOS 11 and 12 (#1733) +- Fix build-time and run-time crashes when app doesn't use Kotlin 1.8.x (#1782) + ## 2.3.0 - Add support for nested test hierarchies using `group()`s (#1634) diff --git a/packages/patrol/README.md b/packages/patrol/README.md index 71d1839dc..6d35d5020 100644 --- a/packages/patrol/README.md +++ b/packages/patrol/README.md @@ -4,12 +4,15 @@ [![codestyle][pub_badge_style]][pub_badge_link] `patrol` package builds on top of `flutter_test` and `integration_test` to make -it easy to control the native UI from Dart test code. +it easy to control the native UI from Dart test code. Created and supported by +[LeanCode](https://leancode.co). -It also provides a new custom finder system to make Flutter widget tests more -concise and understandable, and writing them – faster and more fun. +It must be used together with [patrol_cli]. -It can be used on its own or with [patrol_cli]. +It also provides a new custom finder system to make Flutter widget tests more +concise and understandable, and writing them – faster and more fun. It you want +to only use custom finders, check out +[patrol_finders](https://pub.dev/packages/patrol_finders). ## Installation diff --git a/packages/patrol/android/build.gradle b/packages/patrol/android/build.gradle index 681dd2537..1a5c07e83 100644 --- a/packages/patrol/android/build.gradle +++ b/packages/patrol/android/build.gradle @@ -13,14 +13,12 @@ buildscript { classpath "com.android.tools.build:gradle:7.4.2" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "org.jlleitschuh.gradle:ktlint-gradle:11.5.0" - classpath "org.jetbrains.kotlin:kotlin-serialization:$kotlin_version" } } apply plugin: "com.android.library" apply plugin: "kotlin-android" apply plugin: "org.jlleitschuh.gradle.ktlint" -apply plugin: "kotlinx-serialization" ktlint { filter { @@ -65,11 +63,14 @@ android { api "androidx.test.espresso:espresso-core:3.5.0" api "androidx.test.uiautomator:uiautomator:2.2.0" - implementation platform("org.http4k:http4k-bom:5.7.4.0") + // We need to downgrade http4k-bom to 4.48.0.0 because apps with kotlin version (ext.kotlin_version) lower than 1.8 + // end up with compile-time errors. We can find more details in a similar problem: + // https://stackoverflow.com/questions/67699823/module-was-compiled-with-an-incompatible-version-of-kotlin-the-binary-version-o + implementation platform("org.http4k:http4k-bom:4.48.0.0") implementation "org.http4k:http4k-core" implementation "com.squareup.okhttp:okhttp:2.7.5" // See https://github.com/square/okhttp/issues/8031 implementation "org.http4k:http4k-server-ktorcio" - implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.0" + implementation "com.google.code.gson:gson:2.10.1" testImplementation "org.jetbrains.kotlin:kotlin-test" } diff --git a/packages/patrol/android/src/main/kotlin/pl/leancode/patrol/PatrolServerFilters.kt b/packages/patrol/android/src/main/kotlin/pl/leancode/patrol/PatrolServerFilters.kt index 55d71f44e..2b488bee0 100644 --- a/packages/patrol/android/src/main/kotlin/pl/leancode/patrol/PatrolServerFilters.kt +++ b/packages/patrol/android/src/main/kotlin/pl/leancode/patrol/PatrolServerFilters.kt @@ -1,15 +1,12 @@ package pl.leancode.patrol import androidx.test.uiautomator.UiObjectNotFoundException -import kotlinx.serialization.json.Json import org.http4k.core.Filter import org.http4k.core.Response import org.http4k.core.Status.Companion.INTERNAL_SERVER_ERROR import org.http4k.core.Status.Companion.NOT_FOUND import org.http4k.core.Status.Companion.NOT_IMPLEMENTED -private val json = Json { ignoreUnknownKeys = true } - val printer = Filter { next -> { request -> diff --git a/packages/patrol/android/src/main/kotlin/pl/leancode/patrol/contracts/Contracts.kt b/packages/patrol/android/src/main/kotlin/pl/leancode/patrol/contracts/Contracts.kt index cf0ac5b2d..820eca3f8 100644 --- a/packages/patrol/android/src/main/kotlin/pl/leancode/patrol/contracts/Contracts.kt +++ b/packages/patrol/android/src/main/kotlin/pl/leancode/patrol/contracts/Contracts.kt @@ -5,59 +5,48 @@ package pl.leancode.patrol.contracts; -import kotlinx.serialization.Serializable - class Contracts { - @Serializable enum class GroupEntryType { group, test, } - @Serializable enum class RunDartTestResponseResult { success, skipped, failure, } - @Serializable enum class KeyboardBehavior { showAndDismiss, alternative, } - @Serializable enum class HandlePermissionRequestCode { whileUsing, onlyThisTime, denied, } - @Serializable enum class SetLocationAccuracyRequestLocationAccuracy { coarse, fine, } - @Serializable data class DartGroupEntry ( val name: String, val type: GroupEntryType, val entries: List ) - @Serializable data class ListDartTestsResponse ( val group: DartGroupEntry ) - @Serializable data class RunDartTestRequest ( val name: String ) - @Serializable data class RunDartTestResponse ( val result: RunDartTestResponseResult, val details: String? = null @@ -67,22 +56,18 @@ class Contracts { } } - @Serializable data class ConfigureRequest ( val findTimeoutMillis: Long ) - @Serializable data class OpenAppRequest ( val appId: String ) - @Serializable class OpenQuickSettingsRequest ( ) - @Serializable data class Selector ( val text: String? = null, val textStartsWith: String? = null, @@ -135,13 +120,11 @@ class Contracts { } } - @Serializable data class GetNativeViewsRequest ( val selector: Selector, val appId: String ) - @Serializable data class NativeView ( val className: String? = null, val text: String? = null, @@ -173,18 +156,15 @@ class Contracts { } } - @Serializable data class GetNativeViewsResponse ( val nativeViews: List ) - @Serializable data class TapRequest ( val selector: Selector, val appId: String ) - @Serializable data class EnterTextRequest ( val data: String, val appId: String, @@ -200,7 +180,6 @@ class Contracts { } } - @Serializable data class SwipeRequest ( val startX: Double, val startY: Double, @@ -209,18 +188,15 @@ class Contracts { val steps: Long ) - @Serializable data class WaitUntilVisibleRequest ( val selector: Selector, val appId: String ) - @Serializable data class DarkModeRequest ( val appId: String ) - @Serializable data class Notification ( val appName: String? = null, val title: String, @@ -235,17 +211,14 @@ class Contracts { } } - @Serializable data class GetNotificationsResponse ( val notifications: List ) - @Serializable class GetNotificationsRequest ( ) - @Serializable data class TapOnNotificationRequest ( val index: Long? = null, val selector: Selector? = null @@ -258,22 +231,18 @@ class Contracts { } } - @Serializable data class PermissionDialogVisibleResponse ( val visible: Boolean ) - @Serializable data class PermissionDialogVisibleRequest ( val timeoutMillis: Long ) - @Serializable data class HandlePermissionRequest ( val code: HandlePermissionRequestCode ) - @Serializable data class SetLocationAccuracyRequest ( val locationAccuracy: SetLocationAccuracyRequestLocationAccuracy ) diff --git a/packages/patrol/android/src/main/kotlin/pl/leancode/patrol/contracts/NativeAutomatorServer.kt b/packages/patrol/android/src/main/kotlin/pl/leancode/patrol/contracts/NativeAutomatorServer.kt index a61c499a9..617aee7cc 100644 --- a/packages/patrol/android/src/main/kotlin/pl/leancode/patrol/contracts/NativeAutomatorServer.kt +++ b/packages/patrol/android/src/main/kotlin/pl/leancode/patrol/contracts/NativeAutomatorServer.kt @@ -5,13 +5,12 @@ package pl.leancode.patrol.contracts; +import com.google.gson.Gson import org.http4k.core.Response import org.http4k.core.Method.POST import org.http4k.routing.bind import org.http4k.core.Status.Companion.OK import org.http4k.routing.routes -import kotlinx.serialization.encodeToString -import kotlinx.serialization.json.Json abstract class NativeAutomatorServer { abstract fun initialize() @@ -55,7 +54,7 @@ abstract class NativeAutomatorServer { Response(OK) }, "configure" bind POST to { - val body = json.decodeFromString(it.bodyString()) + val body = json.fromJson(it.bodyString(), Contracts.ConfigureRequest::class.java) configure(body) Response(OK) }, @@ -76,42 +75,42 @@ abstract class NativeAutomatorServer { Response(OK) }, "openApp" bind POST to { - val body = json.decodeFromString(it.bodyString()) + val body = json.fromJson(it.bodyString(), Contracts.OpenAppRequest::class.java) openApp(body) Response(OK) }, "openQuickSettings" bind POST to { - val body = json.decodeFromString(it.bodyString()) + val body = json.fromJson(it.bodyString(), Contracts.OpenQuickSettingsRequest::class.java) openQuickSettings(body) Response(OK) }, "getNativeViews" bind POST to { - val body = json.decodeFromString(it.bodyString()) + val body = json.fromJson(it.bodyString(), Contracts.GetNativeViewsRequest::class.java) val response = getNativeViews(body) - Response(OK).body(json.encodeToString(response)) + Response(OK).body(json.toJson(response)) }, "tap" bind POST to { - val body = json.decodeFromString(it.bodyString()) + val body = json.fromJson(it.bodyString(), Contracts.TapRequest::class.java) tap(body) Response(OK) }, "doubleTap" bind POST to { - val body = json.decodeFromString(it.bodyString()) + val body = json.fromJson(it.bodyString(), Contracts.TapRequest::class.java) doubleTap(body) Response(OK) }, "enterText" bind POST to { - val body = json.decodeFromString(it.bodyString()) + val body = json.fromJson(it.bodyString(), Contracts.EnterTextRequest::class.java) enterText(body) Response(OK) }, "swipe" bind POST to { - val body = json.decodeFromString(it.bodyString()) + val body = json.fromJson(it.bodyString(), Contracts.SwipeRequest::class.java) swipe(body) Response(OK) }, "waitUntilVisible" bind POST to { - val body = json.decodeFromString(it.bodyString()) + val body = json.fromJson(it.bodyString(), Contracts.WaitUntilVisibleRequest::class.java) waitUntilVisible(body) Response(OK) }, @@ -148,12 +147,12 @@ abstract class NativeAutomatorServer { Response(OK) }, "enableDarkMode" bind POST to { - val body = json.decodeFromString(it.bodyString()) + val body = json.fromJson(it.bodyString(), Contracts.DarkModeRequest::class.java) enableDarkMode(body) Response(OK) }, "disableDarkMode" bind POST to { - val body = json.decodeFromString(it.bodyString()) + val body = json.fromJson(it.bodyString(), Contracts.DarkModeRequest::class.java) disableDarkMode(body) Response(OK) }, @@ -170,27 +169,27 @@ abstract class NativeAutomatorServer { Response(OK) }, "getNotifications" bind POST to { - val body = json.decodeFromString(it.bodyString()) + val body = json.fromJson(it.bodyString(), Contracts.GetNotificationsRequest::class.java) val response = getNotifications(body) - Response(OK).body(json.encodeToString(response)) + Response(OK).body(json.toJson(response)) }, "tapOnNotification" bind POST to { - val body = json.decodeFromString(it.bodyString()) + val body = json.fromJson(it.bodyString(), Contracts.TapOnNotificationRequest::class.java) tapOnNotification(body) Response(OK) }, "isPermissionDialogVisible" bind POST to { - val body = json.decodeFromString(it.bodyString()) + val body = json.fromJson(it.bodyString(), Contracts.PermissionDialogVisibleRequest::class.java) val response = isPermissionDialogVisible(body) - Response(OK).body(json.encodeToString(response)) + Response(OK).body(json.toJson(response)) }, "handlePermissionDialog" bind POST to { - val body = json.decodeFromString(it.bodyString()) + val body = json.fromJson(it.bodyString(), Contracts.HandlePermissionRequest::class.java) handlePermissionDialog(body) Response(OK) }, "setLocationAccuracy" bind POST to { - val body = json.decodeFromString(it.bodyString()) + val body = json.fromJson(it.bodyString(), Contracts.SetLocationAccuracyRequest::class.java) setLocationAccuracy(body) Response(OK) }, @@ -204,6 +203,6 @@ abstract class NativeAutomatorServer { } ) - private val json = Json { ignoreUnknownKeys = true } + private val json = Gson() } diff --git a/packages/patrol/android/src/main/kotlin/pl/leancode/patrol/contracts/PatrolAppServiceClient.kt b/packages/patrol/android/src/main/kotlin/pl/leancode/patrol/contracts/PatrolAppServiceClient.kt index 5f39bd12e..3896e9f77 100644 --- a/packages/patrol/android/src/main/kotlin/pl/leancode/patrol/contracts/PatrolAppServiceClient.kt +++ b/packages/patrol/android/src/main/kotlin/pl/leancode/patrol/contracts/PatrolAppServiceClient.kt @@ -5,24 +5,23 @@ package pl.leancode.patrol.contracts; +import com.google.gson.Gson import com.squareup.okhttp.MediaType import com.squareup.okhttp.OkHttpClient import com.squareup.okhttp.Request import com.squareup.okhttp.RequestBody -import kotlinx.serialization.encodeToString -import kotlinx.serialization.json.Json import java.util.concurrent.TimeUnit class PatrolAppServiceClient(address: String, port: Int, private val timeout: Long, private val timeUnit: TimeUnit) { fun listDartTests(): Contracts.ListDartTestsResponse { val response = performRequest("listDartTests") - return json.decodeFromString(response) + return json.fromJson(response, Contracts.ListDartTestsResponse::class.java) } fun runDartTest(request: Contracts.RunDartTestRequest): Contracts.RunDartTestResponse { - val response = performRequest("runDartTest", json.encodeToString(request)) - return json.decodeFromString(response) + val response = performRequest("runDartTest", json.toJson(request)) + return json.fromJson(response, Contracts.RunDartTestResponse::class.java) } private fun performRequest(path: String, requestBody: String? = null): String { @@ -53,7 +52,7 @@ class PatrolAppServiceClient(address: String, port: Int, private val timeout: Lo val serverUrl = "http://$address:$port/" - private val json = Json { ignoreUnknownKeys = true } + private val json = Gson() private val jsonMediaType = MediaType.parse("application/json; charset=utf-8") } diff --git a/packages/patrol/example/ios/Runner.xcodeproj/project.pbxproj b/packages/patrol/example/ios/Runner.xcodeproj/project.pbxproj index db11d1e62..de113a8ae 100644 --- a/packages/patrol/example/ios/Runner.xcodeproj/project.pbxproj +++ b/packages/patrol/example/ios/Runner.xcodeproj/project.pbxproj @@ -578,7 +578,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 13.0; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SUPPORTED_PLATFORMS = iphoneos; @@ -656,7 +656,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 13.0; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; @@ -705,7 +705,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 13.0; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SUPPORTED_PLATFORMS = iphoneos; diff --git a/packages/patrol/pubspec.yaml b/packages/patrol/pubspec.yaml index ae07d235c..35ef9a925 100644 --- a/packages/patrol/pubspec.yaml +++ b/packages/patrol/pubspec.yaml @@ -2,7 +2,7 @@ name: patrol description: > Powerful Flutter-native UI testing framework overcoming limitations of existing Flutter testing tools. Ready for action! -version: 2.4.0-dev.1 +version: 2.4.0-dev.3 homepage: https://patrol.leancode.co repository: https://github.com/leancodepl/patrol issue_tracker: https://github.com/leancodepl/patrol/issues diff --git a/packages/patrol_cli/CHANGELOG.md b/packages/patrol_cli/CHANGELOG.md index b96c200e3..fb4d0415e 100644 --- a/packages/patrol_cli/CHANGELOG.md +++ b/packages/patrol_cli/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.2.1 + +- Fix bug with `test_bundle.dart` being sometimes garbled on Windows (#1797) + ## 2.2.0 - Add support for `group()` (#1634) diff --git a/packages/patrol_cli/lib/src/base/constants.dart b/packages/patrol_cli/lib/src/base/constants.dart index 92a6523a0..e16dd10df 100644 --- a/packages/patrol_cli/lib/src/base/constants.dart +++ b/packages/patrol_cli/lib/src/base/constants.dart @@ -1,2 +1,2 @@ /// Version of Patrol CLI. Must be kept in sync with pubspec.yaml. -const version = '2.2.0'; +const version = '2.2.1'; diff --git a/packages/patrol_cli/lib/src/test_bundler.dart b/packages/patrol_cli/lib/src/test_bundler.dart index 4b2c489d9..472eb66b9 100644 --- a/packages/patrol_cli/lib/src/test_bundler.dart +++ b/packages/patrol_cli/lib/src/test_bundler.dart @@ -177,7 +177,10 @@ ${generateGroupsCode([testFilePath]).split('\n').map((e) => ' $e').join('\n')} for (final testFilePath in testFilePaths) { final relativeTestFilePath = _normalizeTestPath(testFilePath); final testName = _createTestName(relativeTestFilePath); - imports.add("import '$relativeTestFilePath' as $testName;"); + final relativeTestFilePathWithoutSlash = relativeTestFilePath[0] == '/' + ? relativeTestFilePath.replaceFirst('/', '') + : relativeTestFilePath; + imports.add("import '$relativeTestFilePathWithoutSlash' as $testName;"); } return imports.join('\n'); diff --git a/packages/patrol_cli/pubspec.yaml b/packages/patrol_cli/pubspec.yaml index 143b42a7c..3e2e0f8ee 100644 --- a/packages/patrol_cli/pubspec.yaml +++ b/packages/patrol_cli/pubspec.yaml @@ -1,7 +1,7 @@ name: patrol_cli description: > Command-line tool for Patrol, a powerful Flutter-native UI testing framework. -version: 2.2.0 # Must be kept in sync with constants.dart +version: 2.2.1 # Must be kept in sync with constants.dart homepage: https://patrol.leancode.co repository: https://github.com/leancodepl/patrol issue_tracker: https://github.com/leancodepl/patrol/issues diff --git a/packages/patrol_gen/lib/src/generators/android/android_contracts_generator.dart b/packages/patrol_gen/lib/src/generators/android/android_contracts_generator.dart index d18a113a0..c2a1ca671 100644 --- a/packages/patrol_gen/lib/src/generators/android/android_contracts_generator.dart +++ b/packages/patrol_gen/lib/src/generators/android/android_contracts_generator.dart @@ -33,8 +33,6 @@ class AndroidContractsGenerator { package ${config.package}; -import kotlinx.serialization.Serializable - '''; } @@ -59,7 +57,6 @@ $optionalFieldUtils } return ''' - @Serializable ${dataKeyword}class ${message.name} ( $fields )$optionalFieldUtils @@ -77,7 +74,6 @@ $fields final cases = enumDefinition.fields.map((e) => ' $e,').join('\n'); return ''' - @Serializable enum class ${enumDefinition.name} { $cases } diff --git a/packages/patrol_gen/lib/src/generators/android/android_http4k_client_generator.dart b/packages/patrol_gen/lib/src/generators/android/android_http4k_client_generator.dart index 2ecf09a90..d4ce57e3a 100644 --- a/packages/patrol_gen/lib/src/generators/android/android_http4k_client_generator.dart +++ b/packages/patrol_gen/lib/src/generators/android/android_http4k_client_generator.dart @@ -25,12 +25,11 @@ class AndroidHttp4kClientGenerator { package ${config.package}; +import com.google.gson.Gson import com.squareup.okhttp.MediaType import com.squareup.okhttp.OkHttpClient import com.squareup.okhttp.Request import com.squareup.okhttp.RequestBody -import kotlinx.serialization.encodeToString -import kotlinx.serialization.json.Json import java.util.concurrent.TimeUnit '''; @@ -77,7 +76,7 @@ $endpoints val serverUrl = $url - private val json = Json { ignoreUnknownKeys = true } + private val json = Gson() private val jsonMediaType = MediaType.parse("application/json; charset=utf-8") }'''; @@ -92,12 +91,12 @@ $endpoints : ''; final serializeParameter = - endpoint.request != null ? ', json.encodeToString(request)' : ''; + endpoint.request != null ? ', json.toJson(request)' : ''; final body = endpoint.response != null ? ''' val response = performRequest("${endpoint.name}"$serializeParameter) - return json.decodeFromString(response)''' + return json.fromJson(response, Contracts.${endpoint.response!.name}::class.java)''' : ''' return performRequest("${endpoint.name}"$serializeParameter)'''; diff --git a/packages/patrol_gen/lib/src/generators/android/android_http4k_server_generator.dart b/packages/patrol_gen/lib/src/generators/android/android_http4k_server_generator.dart index 20277c235..44d5abba7 100644 --- a/packages/patrol_gen/lib/src/generators/android/android_http4k_server_generator.dart +++ b/packages/patrol_gen/lib/src/generators/android/android_http4k_server_generator.dart @@ -23,13 +23,12 @@ class AndroidHttp4kServerGenerator { package ${config.package}; +import com.google.gson.Gson import org.http4k.core.Response import org.http4k.core.Method.POST import org.http4k.routing.bind import org.http4k.core.Status.Companion.OK import org.http4k.routing.routes -import kotlinx.serialization.encodeToString -import kotlinx.serialization.json.Json '''; } @@ -46,7 +45,7 @@ $handlers $routes ) - private val json = Json { ignoreUnknownKeys = true } + private val json = Gson() } '''; } @@ -56,12 +55,12 @@ $routes final requestDeserialization = e.request != null ? ''' - val body = json.decodeFromString(it.bodyString())''' + val body = json.fromJson(it.bodyString(), Contracts.${e.request!.name}::class.java)''' : ''; final requestArg = e.request != null ? 'body' : ''; final responseSerialization = - e.response != null ? '.body(json.encodeToString(response))' : ''; + e.response != null ? '.body(json.toJson(response))' : ''; final responseVariable = e.response != null ? 'val response = ' : '';