Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace root node filtering with combination matcher #16

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 13 additions & 4 deletions compose/src/main/kotlin/io/github/kakaocup/compose/node/KNode.kt
Original file line number Diff line number Diff line change
@@ -1,13 +1,22 @@
package io.github.kakaocup.compose.node

import androidx.compose.ui.test.SemanticsNodeInteraction
import androidx.compose.ui.test.SemanticsMatcher
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
import io.github.kakaocup.compose.node.core.KDSL
import io.github.kakaocup.compose.screen.ComposeScreen
import java.lang.Exception

open class KNode : KDSL<KNode>, NodeAssertions, NodeActions, TextActions {
override val nodeInteraction: SemanticsNodeInteraction
override val nodeMatcher: SemanticsMatcher
override val composeTestRule: AndroidComposeTestRule<*, *>
override val useUnmergedTree: Boolean

constructor(composeScreen: ComposeScreen<*>, function: ViewBuilder.() -> Unit) {
nodeInteraction = ViewBuilder(composeScreen.composeTestRule).apply(function).nodeInteraction
composeTestRule = composeScreen.composeTestRule

val viewBuilder = ViewBuilder().apply(function)

nodeMatcher = viewBuilder.nodeMatcher ?: throw Exception("No matchers declared for KNode")
useUnmergedTree = viewBuilder.useUnmergedTree
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,19 @@ import androidx.compose.ui.semantics.SemanticsActions.ScrollToIndex
import androidx.compose.ui.semantics.SemanticsProperties.IndexForKey
import androidx.compose.ui.semantics.SemanticsPropertyKey
import androidx.compose.ui.test.*
import androidx.compose.ui.test.junit4.AndroidComposeTestRule

interface NodeActions {
val nodeInteraction: SemanticsNodeInteraction

val nodeMatcher: SemanticsMatcher
val composeTestRule: AndroidComposeTestRule<*, *>
val useUnmergedTree : Boolean

/**
* Performs a click action on the element represented by the given semantics node.
*/
fun performClick() {
nodeInteraction.performClick()
composeTestRule.onNode(nodeMatcher, useUnmergedTree).performClick()
}

/**
Expand All @@ -31,7 +34,7 @@ interface NodeActions {
* Throws an [AssertionError] if there is no scroll parent.
*/
fun performScrollTo() {
nodeInteraction.performScrollTo()
composeTestRule.onNode(nodeMatcher, useUnmergedTree).performScrollTo()
}

/**
Expand All @@ -51,7 +54,7 @@ interface NodeActions {
*/
@ExperimentalTestApi
fun performScrollToIndex(index: Int) {
nodeInteraction.performScrollToIndex(index)
composeTestRule.onNode(nodeMatcher, useUnmergedTree).performScrollToIndex(index)
}

/**
Expand All @@ -69,7 +72,7 @@ interface NodeActions {
*/
@ExperimentalTestApi
fun performScrollToKey(key: Any) {
nodeInteraction.performScrollToKey(key)
composeTestRule.onNode(nodeMatcher, useUnmergedTree).performScrollToKey(key)
}

/**
Expand Down Expand Up @@ -103,7 +106,7 @@ interface NodeActions {
fun performGesture(
block: GestureScope.() -> Unit
) {
nodeInteraction.performGesture(block)
composeTestRule.onNode(nodeMatcher, useUnmergedTree).performGesture(block)
}

/**
Expand All @@ -125,7 +128,7 @@ interface NodeActions {
key: SemanticsPropertyKey<AccessibilityAction<T>>,
invocation: (T) -> Unit
) {
nodeInteraction.performSemanticsAction(key, invocation)
composeTestRule.onNode(nodeMatcher, useUnmergedTree).performSemanticsAction(key, invocation)
}

/**
Expand All @@ -144,6 +147,6 @@ interface NodeActions {
fun performSemanticsAction(
key: SemanticsPropertyKey<AccessibilityAction<() -> Boolean>>
) {
nodeInteraction.performSemanticsAction(key)
composeTestRule.onNode(nodeMatcher, useUnmergedTree).performSemanticsAction(key)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,16 @@ package io.github.kakaocup.compose.node
import androidx.compose.ui.semantics.ProgressBarRangeInfo
import androidx.compose.ui.semantics.SemanticsProperties
import androidx.compose.ui.test.*
import androidx.compose.ui.test.junit4.AndroidComposeTestRule

interface NodeAssertions {
val nodeInteraction: SemanticsNodeInteraction

val nodeMatcher: SemanticsMatcher
val composeTestRule: AndroidComposeTestRule<*, *>
val useUnmergedTree : Boolean

fun assertIsDisplayed() {
nodeInteraction.assertIsDisplayed()
composeTestRule.onNode(nodeMatcher, useUnmergedTree).assertIsDisplayed()
}

/**
Expand All @@ -17,7 +21,7 @@ interface NodeAssertions {
* Throws [AssertionError] if the node is displayed.
*/
fun assertIsNotDisplayed() {
nodeInteraction.assertIsNotDisplayed()
composeTestRule.onNode(nodeMatcher, useUnmergedTree).assertIsNotDisplayed()
}

/**
Expand All @@ -26,7 +30,7 @@ interface NodeAssertions {
* Throws [AssertionError] if the node is not enabled or does not define the property at all.
*/
fun assertIsEnabled() {
nodeInteraction.assertIsEnabled()
composeTestRule.onNode(nodeMatcher, useUnmergedTree).assertIsEnabled()
}

/**
Expand All @@ -35,7 +39,7 @@ interface NodeAssertions {
* Throws [AssertionError] if the node is enabled or does not defined the property at all.
*/
fun assertIsNotEnabled(){
nodeInteraction.assertIsNotEnabled()
composeTestRule.onNode(nodeMatcher, useUnmergedTree).assertIsNotEnabled()
}

/**
Expand All @@ -44,7 +48,7 @@ interface NodeAssertions {
* Throws [AssertionError] if the node is not unchecked, indeterminate, or not toggleable.
*/
fun assertIsOn() {
nodeInteraction.assertIsOn()
composeTestRule.onNode(nodeMatcher, useUnmergedTree).assertIsOn()
}

/**
Expand All @@ -53,7 +57,7 @@ interface NodeAssertions {
* Throws [AssertionError] if the node is checked, indeterminate, or not toggleable.
*/
fun assertIsOff() {
nodeInteraction.assertIsOff()
composeTestRule.onNode(nodeMatcher, useUnmergedTree).assertIsOff()
}

/**
Expand All @@ -62,7 +66,7 @@ interface NodeAssertions {
* Throws [AssertionError] if the node is unselected or not selectable.
*/
fun assertIsSelected() {
nodeInteraction.assertIsSelected()
composeTestRule.onNode(nodeMatcher, useUnmergedTree).assertIsSelected()
}

/**
Expand All @@ -71,15 +75,15 @@ interface NodeAssertions {
* Throws [AssertionError] if the node is selected or not selectable.
*/
fun assertIsNotSelected() {
nodeInteraction.assertIsNotSelected()
composeTestRule.onNode(nodeMatcher, useUnmergedTree).assertIsNotSelected()
}
/**
* Asserts that the current semantics node is toggleable.
*
* Throws [AssertionError] if the node is not toggleable.
*/
fun assertIsToggleable() {
nodeInteraction.assertIsToggleable()
composeTestRule.onNode(nodeMatcher, useUnmergedTree).assertIsToggleable()
}

/**
Expand All @@ -88,15 +92,15 @@ interface NodeAssertions {
* Throws [AssertionError] if the node is not selectable.
*/
fun assertIsSelectable() {
nodeInteraction.assertIsSelectable()
composeTestRule.onNode(nodeMatcher, useUnmergedTree).assertIsSelectable()
}
/**
* Asserts that the current semantics node has a focus.
*
* Throws [AssertionError] if the node is not in the focus or does not defined the property at all.
*/
fun assertIsFocused() {
nodeInteraction.assertIsFocused()
composeTestRule.onNode(nodeMatcher, useUnmergedTree).assertIsFocused()
}

/**
Expand All @@ -105,7 +109,7 @@ interface NodeAssertions {
* Throws [AssertionError] if the node is in the focus or does not defined the property at all.
*/
fun assertIsNotFocused() {
nodeInteraction.assertIsNotFocused()
composeTestRule.onNode(nodeMatcher, useUnmergedTree).assertIsNotFocused()
}

/**
Expand All @@ -124,7 +128,7 @@ interface NodeAssertions {
fun assertContentDescriptionEquals(
vararg values: String
) {
nodeInteraction.assertContentDescriptionEquals(values = values)
composeTestRule.onNode(nodeMatcher, useUnmergedTree).assertContentDescriptionEquals(values = values)
}

/**
Expand All @@ -147,7 +151,7 @@ interface NodeAssertions {
substring: Boolean = false,
ignoreCase: Boolean = false
) {
nodeInteraction.assertContentDescriptionContains(value, substring, ignoreCase)
composeTestRule.onNode(nodeMatcher, useUnmergedTree).assertContentDescriptionContains(value, substring, ignoreCase)
}

/**
Expand All @@ -170,7 +174,7 @@ interface NodeAssertions {
vararg values: String,
includeEditableText: Boolean = true
) {
nodeInteraction.assertTextEquals(values = values, includeEditableText = includeEditableText)
composeTestRule.onNode(nodeMatcher, useUnmergedTree).assertTextEquals(values = values, includeEditableText = includeEditableText)
}

/**
Expand All @@ -195,7 +199,7 @@ interface NodeAssertions {
substring: Boolean = false,
ignoreCase: Boolean = false
) {
nodeInteraction.assertTextContains(value, substring, ignoreCase)
composeTestRule.onNode(nodeMatcher, useUnmergedTree).assertTextContains(value, substring, ignoreCase)
}

/**
Expand All @@ -205,7 +209,7 @@ interface NodeAssertions {
* Throws [AssertionError] if the node's value is not equal to `value`, or if the node has no value
*/
fun assertValueEquals(value: String) {
nodeInteraction.assertValueEquals(value)
composeTestRule.onNode(nodeMatcher, useUnmergedTree).assertValueEquals(value)
}

/**
Expand All @@ -215,7 +219,7 @@ interface NodeAssertions {
* Throws [AssertionError] if the node's value is not equal to `value`, or if the node has no value
*/
fun assertRangeInfoEquals(value: ProgressBarRangeInfo) {
nodeInteraction.assertRangeInfoEquals(value)
composeTestRule.onNode(nodeMatcher, useUnmergedTree).assertRangeInfoEquals(value)
}

/**
Expand All @@ -224,7 +228,7 @@ interface NodeAssertions {
* Throws [AssertionError] if the node is doesn't have a click action.
*/
fun assertHasClickAction() {
nodeInteraction.assertHasClickAction()
composeTestRule.onNode(nodeMatcher, useUnmergedTree).assertHasClickAction()
}

/**
Expand All @@ -233,7 +237,7 @@ interface NodeAssertions {
* Throws [AssertionError] if the node has a click action.
*/
fun assertHasNoClickAction() {
nodeInteraction.assertHasNoClickAction()
composeTestRule.onNode(nodeMatcher, useUnmergedTree).assertHasNoClickAction()
}

/**
Expand All @@ -244,7 +248,7 @@ interface NodeAssertions {
* @throws [AssertionError] if the assert fails.
*/
fun assertDoesNotExist() {
nodeInteraction.assertDoesNotExist()
composeTestRule.onNode(nodeMatcher, useUnmergedTree).assertDoesNotExist()
}

/**
Expand All @@ -261,6 +265,6 @@ interface NodeAssertions {
* @throws [AssertionError] if the assert fails.
*/
fun assertExists() {
nodeInteraction.assertExists()
composeTestRule.onNode(nodeMatcher, useUnmergedTree).assertExists()
}
}
}
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
package io.github.kakaocup.compose.node

import androidx.compose.ui.test.*
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
import androidx.compose.ui.text.TextRange

interface TextActions {
val nodeInteraction: SemanticsNodeInteraction

val nodeMatcher: SemanticsMatcher
val composeTestRule: AndroidComposeTestRule<*, *>
val useUnmergedTree : Boolean

/**
* Clears the text in this node in similar way to IME.
*/
fun performTextClearance() {
nodeInteraction.performTextClearance()
composeTestRule.onNode(nodeMatcher, useUnmergedTree).performTextClearance()
}

/**
Expand All @@ -19,7 +23,7 @@ interface TextActions {
* @param text Text to send.
*/
fun performTextInput(text: String) {
nodeInteraction.performTextInput(text)
composeTestRule.onNode(nodeMatcher, useUnmergedTree).performTextInput(text)
}

/**
Expand All @@ -29,7 +33,7 @@ interface TextActions {
*/
@ExperimentalTestApi
fun performTextInputSelection(selection: TextRange) {
nodeInteraction.performTextInputSelection(selection)
composeTestRule.onNode(nodeMatcher, useUnmergedTree).performTextInputSelection(selection)
}

/**
Expand All @@ -40,7 +44,7 @@ interface TextActions {
* @param text Text to send.
*/
fun performTextReplacement(text: String) {
nodeInteraction.performTextReplacement(text)
composeTestRule.onNode(nodeMatcher, useUnmergedTree).performTextReplacement(text)
}

/**
Expand All @@ -53,6 +57,6 @@ interface TextActions {
* focused)
*/
fun performImeAction() {
nodeInteraction.performImeAction()
composeTestRule.onNode(nodeMatcher, useUnmergedTree).performImeAction()
}
}
}
Loading