From 03e8a13abca43bc47f13e13f739165f3ba2b246e Mon Sep 17 00:00:00 2001 From: Areyana Date: Mon, 18 Dec 2023 20:10:00 +0300 Subject: [PATCH 1/3] add long and double click --- .../compose/node/action/NodeActions.kt | 33 +++++++++++++++++++ .../node/action/options/DoubleClickConfig.kt | 7 ++++ .../node/action/options/LongClickConfig.kt | 7 ++++ 3 files changed, 47 insertions(+) create mode 100644 compose/src/main/kotlin/io/github/kakaocup/compose/node/action/options/DoubleClickConfig.kt create mode 100644 compose/src/main/kotlin/io/github/kakaocup/compose/node/action/options/LongClickConfig.kt diff --git a/compose/src/main/kotlin/io/github/kakaocup/compose/node/action/NodeActions.kt b/compose/src/main/kotlin/io/github/kakaocup/compose/node/action/NodeActions.kt index 18d30279..ef55efbc 100644 --- a/compose/src/main/kotlin/io/github/kakaocup/compose/node/action/NodeActions.kt +++ b/compose/src/main/kotlin/io/github/kakaocup/compose/node/action/NodeActions.kt @@ -1,5 +1,6 @@ package io.github.kakaocup.compose.node.action +import androidx.compose.ui.geometry.Offset import androidx.compose.ui.semantics.AccessibilityAction import androidx.compose.ui.semantics.SemanticsActions import androidx.compose.ui.semantics.SemanticsActions.ScrollBy @@ -11,6 +12,8 @@ import androidx.compose.ui.semantics.SemanticsPropertyKey import androidx.compose.ui.test.* import io.github.kakaocup.compose.intercept.delegate.ComposeDelegate import io.github.kakaocup.compose.intercept.operation.ComposeOperationType +import io.github.kakaocup.compose.node.action.options.DoubleClickConfig +import io.github.kakaocup.compose.node.action.options.LongClickConfig interface NodeActions { val delegate: ComposeDelegate @@ -22,6 +25,34 @@ interface NodeActions { delegate.perform(ComposeBaseActionType.PERFORM_CLICK) { performClick() } } + /** + * Performs a double click action on the element represented by the given semantics node. + */ + fun performDoubleClick(doubleClickConfig: DoubleClickConfig? = null) { + delegate.perform(ComposeBaseActionType.PERFORM_DOUBLE_CLICK) { + performTouchInput { + doubleClick( + position = Offset(doubleClickConfig?.xOffset ?: centerX, doubleClickConfig?.yOffset ?: centerY), + delayMillis = doubleClickConfig?.delayMs ?: ((viewConfiguration.doubleTapMinTimeMillis + viewConfiguration.doubleTapTimeoutMillis) / 2) + ) + } + } + } + + /** + * Performs a long click action on the element represented by the given semantics node. + */ + fun performLongClick(longClickConfig: LongClickConfig? = null) { + delegate.perform(ComposeBaseActionType.PERFORM_LONG_CLICK) { + performTouchInput { + longClick( + position = Offset(longClickConfig?.xOffset ?: centerX, longClickConfig?.yOffset ?: centerY), + durationMillis = longClickConfig?.durationMs ?: ((viewConfiguration.doubleTapMinTimeMillis + viewConfiguration.doubleTapTimeoutMillis) / 2) + ) + } + } + } + /** * Scrolls the closest enclosing scroll parent by the smallest amount such that this node is fully * visible in its viewport. If this node is larger than the viewport, scrolls the scroll parent @@ -254,6 +285,8 @@ interface NodeActions { enum class ComposeBaseActionType : ComposeOperationType { PERFORM_CLICK, + PERFORM_DOUBLE_CLICK, + PERFORM_LONG_CLICK, PERFORM_SCROLL_TO, PERFORM_SCROLL_TO_INDEX, PERFORM_SCROLL_TO_KEY, diff --git a/compose/src/main/kotlin/io/github/kakaocup/compose/node/action/options/DoubleClickConfig.kt b/compose/src/main/kotlin/io/github/kakaocup/compose/node/action/options/DoubleClickConfig.kt new file mode 100644 index 00000000..ae8955cf --- /dev/null +++ b/compose/src/main/kotlin/io/github/kakaocup/compose/node/action/options/DoubleClickConfig.kt @@ -0,0 +1,7 @@ +package io.github.kakaocup.compose.node.action.options + +data class DoubleClickConfig( + val xOffset: Float = 0F, + val yOffset: Float = 0F, + val delayMs: Long? = null +) diff --git a/compose/src/main/kotlin/io/github/kakaocup/compose/node/action/options/LongClickConfig.kt b/compose/src/main/kotlin/io/github/kakaocup/compose/node/action/options/LongClickConfig.kt new file mode 100644 index 00000000..0087020b --- /dev/null +++ b/compose/src/main/kotlin/io/github/kakaocup/compose/node/action/options/LongClickConfig.kt @@ -0,0 +1,7 @@ +package io.github.kakaocup.compose.node.action.options + +data class LongClickConfig( + val xOffset: Float = 0F, + val yOffset: Float = 0F, + val durationMs: Long? = null +) From 5d71e8fa25deb91b620ba30daebcfbe99a0be5e9 Mon Sep 17 00:00:00 2001 From: Areyana Date: Mon, 18 Dec 2023 21:12:20 +0300 Subject: [PATCH 2/3] add options for click --- .../compose/node/action/NodeActions.kt | 29 ++++++++++++------- .../action/extension/TouchInjectionScope.kt | 25 ++++++++++++++++ .../compose/node/action/option/ClickConfig.kt | 3 ++ .../{options => option}/DoubleClickConfig.kt | 2 +- .../{options => option}/LongClickConfig.kt | 2 +- .../compose/node/action/option/Offsets.kt | 7 +++++ 6 files changed, 55 insertions(+), 13 deletions(-) create mode 100644 compose/src/main/kotlin/io/github/kakaocup/compose/node/action/extension/TouchInjectionScope.kt create mode 100644 compose/src/main/kotlin/io/github/kakaocup/compose/node/action/option/ClickConfig.kt rename compose/src/main/kotlin/io/github/kakaocup/compose/node/action/{options => option}/DoubleClickConfig.kt (68%) rename compose/src/main/kotlin/io/github/kakaocup/compose/node/action/{options => option}/LongClickConfig.kt (68%) create mode 100644 compose/src/main/kotlin/io/github/kakaocup/compose/node/action/option/Offsets.kt diff --git a/compose/src/main/kotlin/io/github/kakaocup/compose/node/action/NodeActions.kt b/compose/src/main/kotlin/io/github/kakaocup/compose/node/action/NodeActions.kt index ef55efbc..339e11e7 100644 --- a/compose/src/main/kotlin/io/github/kakaocup/compose/node/action/NodeActions.kt +++ b/compose/src/main/kotlin/io/github/kakaocup/compose/node/action/NodeActions.kt @@ -1,6 +1,5 @@ package io.github.kakaocup.compose.node.action -import androidx.compose.ui.geometry.Offset import androidx.compose.ui.semantics.AccessibilityAction import androidx.compose.ui.semantics.SemanticsActions import androidx.compose.ui.semantics.SemanticsActions.ScrollBy @@ -12,8 +11,11 @@ import androidx.compose.ui.semantics.SemanticsPropertyKey import androidx.compose.ui.test.* import io.github.kakaocup.compose.intercept.delegate.ComposeDelegate import io.github.kakaocup.compose.intercept.operation.ComposeOperationType -import io.github.kakaocup.compose.node.action.options.DoubleClickConfig -import io.github.kakaocup.compose.node.action.options.LongClickConfig +import io.github.kakaocup.compose.node.action.extension.createOffset +import io.github.kakaocup.compose.node.action.option.ClickConfig +import io.github.kakaocup.compose.node.action.option.DoubleClickConfig +import io.github.kakaocup.compose.node.action.option.LongClickConfig +import io.github.kakaocup.compose.node.action.option.Offsets interface NodeActions { val delegate: ComposeDelegate @@ -21,19 +23,24 @@ interface NodeActions { /** * Performs a click action on the element represented by the given semantics node. */ - fun performClick() { - delegate.perform(ComposeBaseActionType.PERFORM_CLICK) { performClick() } + fun performClick(offset: Offsets = Offsets.CENTER, config: ClickConfig? = null) { + delegate.perform(ComposeBaseActionType.PERFORM_CLICK) { + performTouchInput { + click(position = createOffset(offset, config?.xOffset, config?.yOffset)) + } + } } /** * Performs a double click action on the element represented by the given semantics node. */ - fun performDoubleClick(doubleClickConfig: DoubleClickConfig? = null) { + fun performDoubleClick(offset: Offsets = Offsets.CENTER, config: DoubleClickConfig? = null) { delegate.perform(ComposeBaseActionType.PERFORM_DOUBLE_CLICK) { performTouchInput { doubleClick( - position = Offset(doubleClickConfig?.xOffset ?: centerX, doubleClickConfig?.yOffset ?: centerY), - delayMillis = doubleClickConfig?.delayMs ?: ((viewConfiguration.doubleTapMinTimeMillis + viewConfiguration.doubleTapTimeoutMillis) / 2) + delayMillis = config?.delayMs + ?: ((viewConfiguration.doubleTapMinTimeMillis + viewConfiguration.doubleTapTimeoutMillis) / 2), + position = createOffset(offset, config?.xOffset, config?.yOffset) ) } } @@ -42,12 +49,12 @@ interface NodeActions { /** * Performs a long click action on the element represented by the given semantics node. */ - fun performLongClick(longClickConfig: LongClickConfig? = null) { + fun performLongClick(offset: Offsets = Offsets.CENTER, config: LongClickConfig? = null) { delegate.perform(ComposeBaseActionType.PERFORM_LONG_CLICK) { performTouchInput { longClick( - position = Offset(longClickConfig?.xOffset ?: centerX, longClickConfig?.yOffset ?: centerY), - durationMillis = longClickConfig?.durationMs ?: ((viewConfiguration.doubleTapMinTimeMillis + viewConfiguration.doubleTapTimeoutMillis) / 2) + position = createOffset(offset, config?.xOffset, config?.yOffset), + durationMillis = config?.durationMs ?: viewConfiguration.longPressTimeoutMillis ) } } diff --git a/compose/src/main/kotlin/io/github/kakaocup/compose/node/action/extension/TouchInjectionScope.kt b/compose/src/main/kotlin/io/github/kakaocup/compose/node/action/extension/TouchInjectionScope.kt new file mode 100644 index 00000000..7bf121b8 --- /dev/null +++ b/compose/src/main/kotlin/io/github/kakaocup/compose/node/action/extension/TouchInjectionScope.kt @@ -0,0 +1,25 @@ +package io.github.kakaocup.compose.node.action.extension + +import androidx.compose.ui.geometry.Offset +import androidx.compose.ui.test.TouchInjectionScope +import io.github.kakaocup.compose.node.action.option.Offsets + +internal fun TouchInjectionScope.createOffset( + offset: Offsets, + offsetX: Float? = null, + offsetY: Float? = null +): Offset { + return when (offset) { + Offsets.CENTER -> center + Offsets.CENTER_LEFT -> centerLeft.copy(x = 1f) + Offsets.CENTER_RIGHT -> centerRight + Offsets.TOP_CENTER -> topCenter.copy(y = 1f) + Offsets.TOP_LEFT -> topLeft.copy(x = 1f, y = 1f) + Offsets.TOP_RIGHT -> topRight.copy(y = 1f) + Offsets.BOTTOM_CENTER -> bottomCenter + Offsets.BOTTOM_LEFT -> bottomLeft.copy(x = 1f) + Offsets.BOTTOM_RIGHT -> bottomRight + }.run { + copy(x = x + (offsetX ?: 0F), y = y + (offsetY ?: 0F)) + } +} \ No newline at end of file diff --git a/compose/src/main/kotlin/io/github/kakaocup/compose/node/action/option/ClickConfig.kt b/compose/src/main/kotlin/io/github/kakaocup/compose/node/action/option/ClickConfig.kt new file mode 100644 index 00000000..1d862201 --- /dev/null +++ b/compose/src/main/kotlin/io/github/kakaocup/compose/node/action/option/ClickConfig.kt @@ -0,0 +1,3 @@ +package io.github.kakaocup.compose.node.action.option + +data class ClickConfig(val xOffset: Float = 0F, val yOffset: Float = 0F) \ No newline at end of file diff --git a/compose/src/main/kotlin/io/github/kakaocup/compose/node/action/options/DoubleClickConfig.kt b/compose/src/main/kotlin/io/github/kakaocup/compose/node/action/option/DoubleClickConfig.kt similarity index 68% rename from compose/src/main/kotlin/io/github/kakaocup/compose/node/action/options/DoubleClickConfig.kt rename to compose/src/main/kotlin/io/github/kakaocup/compose/node/action/option/DoubleClickConfig.kt index ae8955cf..ff3cbc35 100644 --- a/compose/src/main/kotlin/io/github/kakaocup/compose/node/action/options/DoubleClickConfig.kt +++ b/compose/src/main/kotlin/io/github/kakaocup/compose/node/action/option/DoubleClickConfig.kt @@ -1,4 +1,4 @@ -package io.github.kakaocup.compose.node.action.options +package io.github.kakaocup.compose.node.action.option data class DoubleClickConfig( val xOffset: Float = 0F, diff --git a/compose/src/main/kotlin/io/github/kakaocup/compose/node/action/options/LongClickConfig.kt b/compose/src/main/kotlin/io/github/kakaocup/compose/node/action/option/LongClickConfig.kt similarity index 68% rename from compose/src/main/kotlin/io/github/kakaocup/compose/node/action/options/LongClickConfig.kt rename to compose/src/main/kotlin/io/github/kakaocup/compose/node/action/option/LongClickConfig.kt index 0087020b..9a7768a9 100644 --- a/compose/src/main/kotlin/io/github/kakaocup/compose/node/action/options/LongClickConfig.kt +++ b/compose/src/main/kotlin/io/github/kakaocup/compose/node/action/option/LongClickConfig.kt @@ -1,4 +1,4 @@ -package io.github.kakaocup.compose.node.action.options +package io.github.kakaocup.compose.node.action.option data class LongClickConfig( val xOffset: Float = 0F, diff --git a/compose/src/main/kotlin/io/github/kakaocup/compose/node/action/option/Offsets.kt b/compose/src/main/kotlin/io/github/kakaocup/compose/node/action/option/Offsets.kt new file mode 100644 index 00000000..253e0f46 --- /dev/null +++ b/compose/src/main/kotlin/io/github/kakaocup/compose/node/action/option/Offsets.kt @@ -0,0 +1,7 @@ +package io.github.kakaocup.compose.node.action.option + +enum class Offsets { + CENTER, CENTER_LEFT, CENTER_RIGHT, + TOP_CENTER, TOP_LEFT, TOP_RIGHT, + BOTTOM_CENTER, BOTTOM_LEFT, BOTTOM_RIGHT +} \ No newline at end of file From 48f9d97e9eeb8c91544086469c1862b810085132 Mon Sep 17 00:00:00 2001 From: Areyana Date: Wed, 20 Dec 2023 20:05:42 +0300 Subject: [PATCH 3/3] add ime action --- .../io/github/kakaocup/compose/node/action/NodeActions.kt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/compose/src/main/kotlin/io/github/kakaocup/compose/node/action/NodeActions.kt b/compose/src/main/kotlin/io/github/kakaocup/compose/node/action/NodeActions.kt index 339e11e7..18886c65 100644 --- a/compose/src/main/kotlin/io/github/kakaocup/compose/node/action/NodeActions.kt +++ b/compose/src/main/kotlin/io/github/kakaocup/compose/node/action/NodeActions.kt @@ -290,6 +290,12 @@ interface NodeActions { delegate.perform(ComposeBaseActionType.PERFORM_SEMANTICS_ACTION) { performSemanticsAction(key) } } + fun performImeAction() { + delegate.perform(ComposeBaseActionType.PERFORM_IME_ACTION) { + performImeAction() + } + } + enum class ComposeBaseActionType : ComposeOperationType { PERFORM_CLICK, PERFORM_DOUBLE_CLICK, @@ -301,5 +307,6 @@ interface NodeActions { PERFORM_GESTURE, PERFORM_TOUCH_INPUT, PERFORM_SEMANTICS_ACTION, + PERFORM_IME_ACTION } }