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 = ' : '';