diff --git a/maestro-ios-driver/src/main/resources/maestro-driver-ios-config.xctestrun b/maestro-ios-driver/src/main/resources/maestro-driver-ios-config.xctestrun index 73724610a4..c5e7c04356 100644 --- a/maestro-ios-driver/src/main/resources/maestro-driver-ios-config.xctestrun +++ b/maestro-ios-driver/src/main/resources/maestro-driver-ios-config.xctestrun @@ -20,6 +20,8 @@ maestro-driver-iosUITests BlueprintProviderName maestro-driver-ios + BlueprintProviderRelativePath + maestro-driver-ios.xcodeproj BundleIdentifiersForCrashReportEmphasis dev.mobile.maestro-driver-ios @@ -39,6 +41,8 @@ 1 EnvironmentVariables + APP_DISTRIBUTOR_ID_OVERRIDE + com.apple.AppStore OS_ACTIVITY_DT_MODE YES SQLITE_ENABLE_THREAD_ASSERTIONS @@ -48,6 +52,8 @@ IsXCTRunnerHostedTestBundle + PreferredScreenCaptureFormat + screenRecording ProductModuleName maestro_driver_iosUITests RunOrder @@ -85,6 +91,8 @@ UITargetAppEnvironmentVariables + APP_DISTRIBUTOR_ID_OVERRIDE + com.apple.AppStore DYLD_FRAMEWORK_PATH __TESTROOT__/Debug-iphonesimulator:__TESTROOT__/Debug-iphonesimulator/PackageFrameworks DYLD_LIBRARY_PATH diff --git a/maestro-ios-driver/src/main/resources/maestro-driver-ios.zip b/maestro-ios-driver/src/main/resources/maestro-driver-ios.zip index 57efc0ff27..9e27dc6702 100644 Binary files a/maestro-ios-driver/src/main/resources/maestro-driver-ios.zip and b/maestro-ios-driver/src/main/resources/maestro-driver-ios.zip differ diff --git a/maestro-ios-driver/src/main/resources/maestro-driver-iosUITests-Runner.zip b/maestro-ios-driver/src/main/resources/maestro-driver-iosUITests-Runner.zip index 95d3f6f470..913a55f771 100644 Binary files a/maestro-ios-driver/src/main/resources/maestro-driver-iosUITests-Runner.zip and b/maestro-ios-driver/src/main/resources/maestro-driver-iosUITests-Runner.zip differ diff --git a/maestro-ios-xctest-runner/maestro-driver-iosUITests/Routes/Handlers/SwipeRouteHandlerV2.swift b/maestro-ios-xctest-runner/maestro-driver-iosUITests/Routes/Handlers/SwipeRouteHandlerV2.swift index 464746ad2c..a952615bc5 100644 --- a/maestro-ios-xctest-runner/maestro-driver-iosUITests/Routes/Handlers/SwipeRouteHandlerV2.swift +++ b/maestro-ios-xctest-runner/maestro-driver-iosUITests/Routes/Handlers/SwipeRouteHandlerV2.swift @@ -14,6 +14,10 @@ struct SwipeRouteHandlerV2: HTTPHandler { return AppError(type: .precondition, message: "incorrect request body provided for swipe request v2").httpResponse } + if (requestBody.duration < 0) { + return AppError(type: .precondition, message: "swipe duration can not be negative").httpResponse + } + do { try await swipePrivateAPI(requestBody) return HTTPResponse(statusCode: .ok) diff --git a/maestro-orchestra-models/src/main/java/maestro/orchestra/Commands.kt b/maestro-orchestra-models/src/main/java/maestro/orchestra/Commands.kt index 1cc4b1f244..d0098b4fde 100644 --- a/maestro-orchestra-models/src/main/java/maestro/orchestra/Commands.kt +++ b/maestro-orchestra-models/src/main/java/maestro/orchestra/Commands.kt @@ -110,7 +110,8 @@ data class ScrollUntilVisibleCommand( val visibilityPercentageNormalized = (visibilityPercentage / 100).toDouble() private fun String.speedToDuration(): String { - return ((1000 * (100 - this.toLong()).toDouble() / 100).toLong() + 1).toString() + val duration = ((1000 * (100 - this.toLong()).toDouble() / 100).toLong() + 1) + return if (duration < 0) { DEFAULT_SCROLL_DURATION } else duration.toString() } private fun String.timeoutToMillis(): String { diff --git a/maestro-test/src/test/kotlin/maestro/test/IntegrationTest.kt b/maestro-test/src/test/kotlin/maestro/test/IntegrationTest.kt index 9c95ca4d68..972f1c2f81 100644 --- a/maestro-test/src/test/kotlin/maestro/test/IntegrationTest.kt +++ b/maestro-test/src/test/kotlin/maestro/test/IntegrationTest.kt @@ -3135,6 +3135,42 @@ class IntegrationTest { ) } + @Test + fun `Case 118 - Scroll until view is visible - no negative values allowed`() { + // Given + val commands = readCommands("118_scroll_until_visible_negative") + val expectedDuration = "40" + val expectedTimeout = "20000" + val info = driver { }.deviceInfo() + + val elementBounds = Bounds(0, 0 + info.heightGrid, 100, 100 + info.heightGrid) + val driver = driver { + element { + id = "maestro" + bounds = elementBounds + } + } + + // When + var scrollDuration = "0" + var timeout = "0" + Maestro(driver).use { + orchestra(it, onCommandMetadataUpdate = { _, metaData -> + scrollDuration = metaData.evaluatedCommand?.scrollUntilVisible?.scrollDuration.toString() + timeout = metaData.evaluatedCommand?.scrollUntilVisible?.timeout.toString() + }).runFlow(commands) + } + + // Then + assertThat(scrollDuration).isEqualTo(expectedDuration) + assertThat(timeout).isEqualTo(expectedTimeout) + driver.assertEvents( + listOf( + Event.SwipeElementWithDirection(Point(270, 480), SwipeDirection.UP, expectedDuration.toLong()), + ) + ) + } + private fun orchestra( maestro: Maestro, ) = Orchestra( diff --git a/maestro-test/src/test/resources/118_scroll_until_visible_negative.yaml b/maestro-test/src/test/resources/118_scroll_until_visible_negative.yaml new file mode 100644 index 0000000000..44ee4468e9 --- /dev/null +++ b/maestro-test/src/test/resources/118_scroll_until_visible_negative.yaml @@ -0,0 +1,8 @@ +appId: com.example.app +--- +- scrollUntilVisible: + element: + id: "maestro" + direction: DOWN + speed: 110 + timeout: -200 \ No newline at end of file