mirror of
https://github.com/priyanshujain/sanderling.git
synced 2026-10-04 20:17:09 +00:00
feat(sidecar): EraseText backend support on android and ios
This commit is contained in:
1 parent
89e9601e43
commit
5ede139945
5 files changed
+45
No files matched your search
@@ -6,6 +6,7 @@ interface DriverBackend {
|
|||||||
fun tap(x: Int, y: Int)
|
fun tap(x: Int, y: Int)
|
||||||
fun tapSelector(selector: String)
|
fun tapSelector(selector: String)
|
||||||
fun inputText(text: String)
|
fun inputText(text: String)
|
||||||
|
fun eraseText(characterCount: Int)
|
||||||
fun swipe(fromX: Int, fromY: Int, toX: Int, toY: Int, durationMillis: Long)
|
fun swipe(fromX: Int, fromY: Int, toX: Int, toY: Int, durationMillis: Long)
|
||||||
fun pressKey(key: String)
|
fun pressKey(key: String)
|
||||||
fun longPress(x: Int, y: Int)
|
fun longPress(x: Int, y: Int)
|
||||||
@@ -402,6 +403,16 @@ class StubDriverBackend(
|
|||||||
runAdb(listOf("shell", "input", "text", escapeForAdbInputText(text)))
|
runAdb(listOf("shell", "input", "text", escapeForAdbInputText(text)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Volatile var lastEraseCharacterCount: Int? = null
|
||||||
|
private set
|
||||||
|
|
||||||
|
override fun eraseText(characterCount: Int) {
|
||||||
|
lastEraseCharacterCount = characterCount
|
||||||
|
repeat(characterCount) {
|
||||||
|
runAdb(listOf("shell", "input", "keyevent", "KEYCODE_DEL"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Volatile var lastSwipe: SwipeRecord? = null
|
@Volatile var lastSwipe: SwipeRecord? = null
|
||||||
private set
|
private set
|
||||||
@Volatile var lastKey: String? = null
|
@Volatile var lastKey: String? = null
|
||||||
@@ -531,6 +542,8 @@ class MaestroDriverBackend(private val serial: String?) : DriverBackend {
|
|||||||
|
|
||||||
override fun inputText(text: String) = driver.inputText(text)
|
override fun inputText(text: String) = driver.inputText(text)
|
||||||
|
|
||||||
|
override fun eraseText(characterCount: Int) = driver.eraseText(characterCount)
|
||||||
|
|
||||||
override fun swipe(fromX: Int, fromY: Int, toX: Int, toY: Int, durationMillis: Long) =
|
override fun swipe(fromX: Int, fromY: Int, toX: Int, toY: Int, durationMillis: Long) =
|
||||||
driver.swipe(maestro.Point(fromX, fromY), maestro.Point(toX, toY), maxOf(durationMillis, 250L))
|
driver.swipe(maestro.Point(fromX, fromY), maestro.Point(toX, toY), maxOf(durationMillis, 250L))
|
||||||
|
|
||||||
@@ -732,6 +745,8 @@ class IosDriverBackend(private val udid: String) : DriverBackend {
|
|||||||
|
|
||||||
override fun inputText(text: String) = withReconnect { driver.inputText(text) }
|
override fun inputText(text: String) = withReconnect { driver.inputText(text) }
|
||||||
|
|
||||||
|
override fun eraseText(characterCount: Int) = withReconnect { driver.eraseText(characterCount) }
|
||||||
|
|
||||||
override fun swipe(fromX: Int, fromY: Int, toX: Int, toY: Int, durationMillis: Long) = withReconnect {
|
override fun swipe(fromX: Int, fromY: Int, toX: Int, toY: Int, durationMillis: Long) = withReconnect {
|
||||||
driver.swipe(maestro.Point(fromX, fromY), maestro.Point(toX, toY), maxOf(durationMillis, 250L))
|
driver.swipe(maestro.Point(fromX, fromY), maestro.Point(toX, toY), maxOf(durationMillis, 250L))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import com.google.protobuf.ByteString
|
|||||||
import dev.sanderling.driver.v1.DriverGrpc
|
import dev.sanderling.driver.v1.DriverGrpc
|
||||||
import dev.sanderling.driver.v1.Duration
|
import dev.sanderling.driver.v1.Duration
|
||||||
import dev.sanderling.driver.v1.Empty
|
import dev.sanderling.driver.v1.Empty
|
||||||
|
import dev.sanderling.driver.v1.EraseTextRequest
|
||||||
import dev.sanderling.driver.v1.HealthStatus
|
import dev.sanderling.driver.v1.HealthStatus
|
||||||
import dev.sanderling.driver.v1.HierarchyJSON
|
import dev.sanderling.driver.v1.HierarchyJSON
|
||||||
import dev.sanderling.driver.v1.Image
|
import dev.sanderling.driver.v1.Image
|
||||||
@@ -74,6 +75,13 @@ class DriverService(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun eraseText(request: EraseTextRequest, responseObserver: StreamObserver<Empty>) {
|
||||||
|
runRpc(responseObserver) {
|
||||||
|
backend.eraseText(request.characterCount)
|
||||||
|
Empty.getDefaultInstance()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun swipe(request: SwipeRequest, responseObserver: StreamObserver<Empty>) {
|
override fun swipe(request: SwipeRequest, responseObserver: StreamObserver<Empty>) {
|
||||||
runRpc(responseObserver) {
|
runRpc(responseObserver) {
|
||||||
val from = request.from
|
val from = request.from
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package dev.sanderling.sidecar
|
|||||||
import dev.sanderling.driver.v1.DriverGrpc
|
import dev.sanderling.driver.v1.DriverGrpc
|
||||||
import dev.sanderling.driver.v1.Duration
|
import dev.sanderling.driver.v1.Duration
|
||||||
import dev.sanderling.driver.v1.Empty
|
import dev.sanderling.driver.v1.Empty
|
||||||
|
import dev.sanderling.driver.v1.EraseTextRequest
|
||||||
import dev.sanderling.driver.v1.LaunchRequest
|
import dev.sanderling.driver.v1.LaunchRequest
|
||||||
import dev.sanderling.driver.v1.Point
|
import dev.sanderling.driver.v1.Point
|
||||||
import dev.sanderling.driver.v1.PressKeyRequest
|
import dev.sanderling.driver.v1.PressKeyRequest
|
||||||
@@ -82,6 +83,14 @@ class DriverServiceTest {
|
|||||||
assertEquals("hello world", backend.lastInputText)
|
assertEquals("hello world", backend.lastInputText)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test fun eraseTextForwardsCharacterCount() {
|
||||||
|
val backend = StubDriverBackend("android")
|
||||||
|
val client = newClient(backend)
|
||||||
|
|
||||||
|
client.eraseText(EraseTextRequest.newBuilder().setCharacterCount(11).build())
|
||||||
|
assertEquals(11, backend.lastEraseCharacterCount)
|
||||||
|
}
|
||||||
|
|
||||||
@Test fun screenshotReturnsBackendBytes() {
|
@Test fun screenshotReturnsBackendBytes() {
|
||||||
val backend = object : DriverBackend by StubDriverBackend("android") {
|
val backend = object : DriverBackend by StubDriverBackend("android") {
|
||||||
override fun screenshot(): Triple<ByteArray, Int, Int> = Triple(byteArrayOf(1, 2, 3), 1080, 2340)
|
override fun screenshot(): Triple<ByteArray, Int, Int> = Triple(byteArrayOf(1, 2, 3), 1080, 2340)
|
||||||
|
|||||||
@@ -15,6 +15,18 @@ class InputTextTest {
|
|||||||
assertEquals(listOf(listOf("shell", "input", "text", "Emergency%sFund")), commands)
|
assertEquals(listOf(listOf("shell", "input", "text", "Emergency%sFund")), commands)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test fun eraseTextSendsOneDeleteKeyPerCharacter() {
|
||||||
|
val commands = mutableListOf<List<String>>()
|
||||||
|
val backend = StubDriverBackend("android") { commands.add(it) }
|
||||||
|
|
||||||
|
backend.eraseText(3)
|
||||||
|
|
||||||
|
assertEquals(
|
||||||
|
List(3) { listOf("shell", "input", "keyevent", "KEYCODE_DEL") },
|
||||||
|
commands,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
@Test fun escapeForAdbInputTextSubstitutesSpaces() {
|
@Test fun escapeForAdbInputTextSubstitutesSpaces() {
|
||||||
assertEquals("hello%sworld", StubDriverBackend.escapeForAdbInputText("hello world"))
|
assertEquals("hello%sworld", StubDriverBackend.escapeForAdbInputText("hello world"))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ class SnapshotHandlerTest {
|
|||||||
override fun tap(x: Int, y: Int) {}
|
override fun tap(x: Int, y: Int) {}
|
||||||
override fun tapSelector(selector: String) {}
|
override fun tapSelector(selector: String) {}
|
||||||
override fun inputText(text: String) {}
|
override fun inputText(text: String) {}
|
||||||
|
override fun eraseText(characterCount: Int) {}
|
||||||
override fun swipe(fromX: Int, fromY: Int, toX: Int, toY: Int, durationMillis: Long) {}
|
override fun swipe(fromX: Int, fromY: Int, toX: Int, toY: Int, durationMillis: Long) {}
|
||||||
override fun pressKey(key: String) {}
|
override fun pressKey(key: String) {}
|
||||||
override fun longPress(x: Int, y: Int) {}
|
override fun longPress(x: Int, y: Int) {}
|
||||||
|
|||||||
Reference in new issue
Block a user