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..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 @@ -11,6 +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.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 @@ -18,8 +23,41 @@ 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(offset: Offsets = Offsets.CENTER, config: DoubleClickConfig? = null) { + delegate.perform(ComposeBaseActionType.PERFORM_DOUBLE_CLICK) { + performTouchInput { + doubleClick( + delayMillis = config?.delayMs + ?: ((viewConfiguration.doubleTapMinTimeMillis + viewConfiguration.doubleTapTimeoutMillis) / 2), + position = createOffset(offset, config?.xOffset, config?.yOffset) + ) + } + } + } + + /** + * Performs a long click action on the element represented by the given semantics node. + */ + fun performLongClick(offset: Offsets = Offsets.CENTER, config: LongClickConfig? = null) { + delegate.perform(ComposeBaseActionType.PERFORM_LONG_CLICK) { + performTouchInput { + longClick( + position = createOffset(offset, config?.xOffset, config?.yOffset), + durationMillis = config?.durationMs ?: viewConfiguration.longPressTimeoutMillis + ) + } + } } /** @@ -252,8 +290,16 @@ 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, + PERFORM_LONG_CLICK, PERFORM_SCROLL_TO, PERFORM_SCROLL_TO_INDEX, PERFORM_SCROLL_TO_KEY, @@ -261,5 +307,6 @@ interface NodeActions { PERFORM_GESTURE, PERFORM_TOUCH_INPUT, PERFORM_SEMANTICS_ACTION, + PERFORM_IME_ACTION } } 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/option/DoubleClickConfig.kt b/compose/src/main/kotlin/io/github/kakaocup/compose/node/action/option/DoubleClickConfig.kt new file mode 100644 index 00000000..ff3cbc35 --- /dev/null +++ b/compose/src/main/kotlin/io/github/kakaocup/compose/node/action/option/DoubleClickConfig.kt @@ -0,0 +1,7 @@ +package io.github.kakaocup.compose.node.action.option + +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/option/LongClickConfig.kt b/compose/src/main/kotlin/io/github/kakaocup/compose/node/action/option/LongClickConfig.kt new file mode 100644 index 00000000..9a7768a9 --- /dev/null +++ b/compose/src/main/kotlin/io/github/kakaocup/compose/node/action/option/LongClickConfig.kt @@ -0,0 +1,7 @@ +package io.github.kakaocup.compose.node.action.option + +data class LongClickConfig( + val xOffset: Float = 0F, + val yOffset: Float = 0F, + val durationMs: Long? = null +) 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