From 444d7c094765edc201fddb56b69dff29e0dca91a Mon Sep 17 00:00:00 2001 From: Aleksei Tiurin Date: Wed, 7 Aug 2024 00:46:01 +0500 Subject: [PATCH] Refresh SemanticsNodeInteraction provider state --- .../com/atiurin/sampleapp/tests/BaseTest.kt | 5 +- .../tests/compose/SampleClassTest.kt | 41 ++++ .../ultron/core/config/UltronConfig.kt | 2 + .../com/atiurin/ultron/log/UltronLog.kt | 1 - .../config/UltronComposeConfig.android.kt | 8 + ...ComposeSemanticsNodeInteraction.android.kt | 4 +- .../compose/config/UltronComposeConfig.kt | 9 +- .../UltronComposeSemanticsNodeInteraction.kt | 180 ++++++++++++++++-- .../config/UltronComposeConfig.shared.kt | 7 + 9 files changed, 232 insertions(+), 25 deletions(-) create mode 100644 sample-app/src/androidTest/java/com/atiurin/sampleapp/tests/compose/SampleClassTest.kt create mode 100644 ultron-compose/src/androidMain/kotlin/com/atiurin/ultron/core/compose/config/UltronComposeConfig.android.kt create mode 100644 ultron-compose/src/shared/kotlin/com/atiurin/ultron/core/compose/config/UltronComposeConfig.shared.kt diff --git a/sample-app/src/androidTest/java/com/atiurin/sampleapp/tests/BaseTest.kt b/sample-app/src/androidTest/java/com/atiurin/sampleapp/tests/BaseTest.kt index ea19df99..ad0bf7d5 100644 --- a/sample-app/src/androidTest/java/com/atiurin/sampleapp/tests/BaseTest.kt +++ b/sample-app/src/androidTest/java/com/atiurin/sampleapp/tests/BaseTest.kt @@ -2,15 +2,12 @@ package com.atiurin.sampleapp.tests import android.os.Environment import androidx.test.platform.app.InstrumentationRegistry -import com.atiurin.ultron.testlifecycle.rulesequence.RuleSequence import com.atiurin.sampleapp.data.repositories.CURRENT_USER import com.atiurin.sampleapp.managers.AccountManager import com.atiurin.ultron.allure.config.UltronAllureConfig -import com.atiurin.ultron.allure.listeners.DetailedOperationAllureListener -import com.atiurin.ultron.allure.listeners.ScreenshotAttachListener -import com.atiurin.ultron.allure.listeners.WindowHierarchyAttachListener import com.atiurin.ultron.core.compose.config.UltronComposeConfig import com.atiurin.ultron.core.config.UltronConfig +import com.atiurin.ultron.testlifecycle.rulesequence.RuleSequence import com.atiurin.ultron.testlifecycle.setupteardown.SetUpRule import org.junit.BeforeClass import org.junit.Rule diff --git a/sample-app/src/androidTest/java/com/atiurin/sampleapp/tests/compose/SampleClassTest.kt b/sample-app/src/androidTest/java/com/atiurin/sampleapp/tests/compose/SampleClassTest.kt new file mode 100644 index 00000000..ec4a67e0 --- /dev/null +++ b/sample-app/src/androidTest/java/com/atiurin/sampleapp/tests/compose/SampleClassTest.kt @@ -0,0 +1,41 @@ +package com.atiurin.sampleapp.tests.compose + +import androidx.compose.ui.test.hasTestTag +import com.atiurin.sampleapp.activity.ComposeElementsActivity +import com.atiurin.sampleapp.tests.BaseTest +import com.atiurin.ultron.core.compose.createUltronComposeRule +import com.atiurin.ultron.extensions.assertIsDisplayed +import com.atiurin.ultron.extensions.withName +import com.atiurin.ultron.extensions.withTimeout +import com.atiurin.ultron.page.Page +import org.junit.Rule +import org.junit.Test + +class SampleClassTest : BaseTest() { + @get:Rule + val composeRuleBase = createUltronComposeRule() + + @Test + fun test() { + SomePage{ + elementWithName.assertIsDisplayed() + elementWithTimeout.assertIsDisplayed() + elementMatcher.assertIsDisplayed() + } + } + + @Test + fun test2() { + SomePage{ + elementWithName.assertIsDisplayed() + elementWithTimeout.assertIsDisplayed() + elementMatcher.assertIsDisplayed() + } + } +} + +object SomePage : Page() { + val elementWithName = hasTestTag("statusText").withName("sample element name") + val elementWithTimeout = hasTestTag("statusText").withTimeout(4000) + val elementMatcher = hasTestTag("statusText") +} \ No newline at end of file diff --git a/ultron-android/src/main/kotlin/com/atiurin/ultron/core/config/UltronConfig.kt b/ultron-android/src/main/kotlin/com/atiurin/ultron/core/config/UltronConfig.kt index ad268e4f..ace67cde 100644 --- a/ultron-android/src/main/kotlin/com/atiurin/ultron/core/config/UltronConfig.kt +++ b/ultron-android/src/main/kotlin/com/atiurin/ultron/core/config/UltronConfig.kt @@ -37,6 +37,7 @@ import com.atiurin.ultron.extensions.simpleClassName import com.atiurin.ultron.listeners.LogLifecycleListener import com.atiurin.ultron.listeners.UltronLifecycleListener import com.atiurin.ultron.log.UltronLog +import com.atiurin.ultron.log.UltronLogcatLogger import com.atiurin.ultron.log.getFileLogger import com.atiurin.ultron.testlifecycle.setupteardown.ConditionExecutorWrapper import com.atiurin.ultron.testlifecycle.setupteardown.ConditionsExecutor @@ -75,6 +76,7 @@ object UltronConfig { Espresso.ASSERTION_TIMEOUT = params.operationTimeoutMs UiAutomator.OPERATION_TIMEOUT = params.operationTimeoutMs UltronCommonConfig.addListener(LogLifecycleListener()) + UltronLog.addLogger(UltronLogcatLogger()) if (params.logToFile) { UltronLog.addLogger(UltronLog.fileLogger) } else { diff --git a/ultron-common/src/commonMain/kotlin/com/atiurin/ultron/log/UltronLog.kt b/ultron-common/src/commonMain/kotlin/com/atiurin/ultron/log/UltronLog.kt index acef51ac..c124719f 100644 --- a/ultron-common/src/commonMain/kotlin/com/atiurin/ultron/log/UltronLog.kt +++ b/ultron-common/src/commonMain/kotlin/com/atiurin/ultron/log/UltronLog.kt @@ -2,7 +2,6 @@ package com.atiurin.ultron.log expect fun getFileLogger(): UltronFileLogger - object UltronLog { val fileLogger by lazy { getFileLogger() } diff --git a/ultron-compose/src/androidMain/kotlin/com/atiurin/ultron/core/compose/config/UltronComposeConfig.android.kt b/ultron-compose/src/androidMain/kotlin/com/atiurin/ultron/core/compose/config/UltronComposeConfig.android.kt new file mode 100644 index 00000000..48027c5e --- /dev/null +++ b/ultron-compose/src/androidMain/kotlin/com/atiurin/ultron/core/compose/config/UltronComposeConfig.android.kt @@ -0,0 +1,8 @@ +package com.atiurin.ultron.core.compose.config + +import com.atiurin.ultron.log.ULogger +import com.atiurin.ultron.log.UltronLogcatLogger + +actual fun getPlatformLoggers(): List { + return listOf(UltronLogcatLogger()) +} \ No newline at end of file diff --git a/ultron-compose/src/androidMain/kotlin/com/atiurin/ultron/core/compose/nodeinteraction/UltronComposeSemanticsNodeInteraction.android.kt b/ultron-compose/src/androidMain/kotlin/com/atiurin/ultron/core/compose/nodeinteraction/UltronComposeSemanticsNodeInteraction.android.kt index c15fbef8..c57d4c6b 100644 --- a/ultron-compose/src/androidMain/kotlin/com/atiurin/ultron/core/compose/nodeinteraction/UltronComposeSemanticsNodeInteraction.android.kt +++ b/ultron-compose/src/androidMain/kotlin/com/atiurin/ultron/core/compose/nodeinteraction/UltronComposeSemanticsNodeInteraction.android.kt @@ -2,15 +2,15 @@ package com.atiurin.ultron.core.compose.nodeinteraction import android.os.Build import androidx.annotation.RequiresApi -import com.atiurin.ultron.core.compose.operation.ComposeOperationType -import java.util.concurrent.atomic.AtomicReference import androidx.compose.ui.graphics.ImageBitmap import androidx.compose.ui.semantics.AccessibilityAction import androidx.compose.ui.semantics.SemanticsPropertyKey import androidx.compose.ui.test.SemanticsNodeInteraction import androidx.compose.ui.test.captureToImage +import com.atiurin.ultron.core.compose.operation.ComposeOperationType import com.atiurin.ultron.extensions.requireSemantics import com.atiurin.ultron.utils.runOnUiThread +import java.util.concurrent.atomic.AtomicReference @RequiresApi(Build.VERSION_CODES.O) fun UltronComposeSemanticsNodeInteraction.captureToImage(): ImageBitmap { diff --git a/ultron-compose/src/commonMain/kotlin/com/atiurin/ultron/core/compose/config/UltronComposeConfig.kt b/ultron-compose/src/commonMain/kotlin/com/atiurin/ultron/core/compose/config/UltronComposeConfig.kt index 13e13d9a..e1b09967 100644 --- a/ultron-compose/src/commonMain/kotlin/com/atiurin/ultron/core/compose/config/UltronComposeConfig.kt +++ b/ultron-compose/src/commonMain/kotlin/com/atiurin/ultron/core/compose/config/UltronComposeConfig.kt @@ -1,6 +1,5 @@ package com.atiurin.ultron.core.compose.config -import com.atiurin.ultron.core.config.UltronCommonConfig import com.atiurin.ultron.core.common.Operation import com.atiurin.ultron.core.common.OperationResult import com.atiurin.ultron.core.common.OperationResultAnalyzer @@ -8,13 +7,14 @@ import com.atiurin.ultron.core.common.UltronDefaultOperationResultAnalyzer import com.atiurin.ultron.core.compose.operation.ComposeOperationResult import com.atiurin.ultron.core.compose.operation.ComposeOperationType import com.atiurin.ultron.core.compose.operation.UltronComposeOperation -import com.atiurin.ultron.core.compose.operation.UltronComposeOperationLifecycle +import com.atiurin.ultron.core.config.UltronCommonConfig import com.atiurin.ultron.exceptions.UltronAssertionException import com.atiurin.ultron.exceptions.UltronException import com.atiurin.ultron.exceptions.UltronWrapperException import com.atiurin.ultron.extensions.simpleClassName import com.atiurin.ultron.listeners.LogLifecycleListener import com.atiurin.ultron.listeners.UltronLifecycleListener +import com.atiurin.ultron.log.ULogger import com.atiurin.ultron.log.UltronLog object UltronComposeConfig { @@ -88,6 +88,9 @@ object UltronComposeConfig { } private fun modify(){ + getPlatformLoggers().forEach { + UltronLog.addLogger(it) + } UltronCommonConfig.addListener(LogLifecycleListener()) if (UltronCommonConfig.logToFile) { UltronLog.addLogger(UltronLog.fileLogger) @@ -97,3 +100,5 @@ object UltronComposeConfig { UltronLog.info("UltronComposeConfig applied with params $params}") } } + +expect fun getPlatformLoggers(): List diff --git a/ultron-compose/src/commonMain/kotlin/com/atiurin/ultron/core/compose/nodeinteraction/UltronComposeSemanticsNodeInteraction.kt b/ultron-compose/src/commonMain/kotlin/com/atiurin/ultron/core/compose/nodeinteraction/UltronComposeSemanticsNodeInteraction.kt index 332bb640..f54556ae 100644 --- a/ultron-compose/src/commonMain/kotlin/com/atiurin/ultron/core/compose/nodeinteraction/UltronComposeSemanticsNodeInteraction.kt +++ b/ultron-compose/src/commonMain/kotlin/com/atiurin/ultron/core/compose/nodeinteraction/UltronComposeSemanticsNodeInteraction.kt @@ -2,42 +2,179 @@ package com.atiurin.ultron.core.compose.nodeinteraction import androidx.compose.ui.input.key.KeyEvent -import androidx.compose.ui.semantics.* -import androidx.compose.ui.test.* +import androidx.compose.ui.semantics.AccessibilityAction +import androidx.compose.ui.semantics.ProgressBarRangeInfo +import androidx.compose.ui.semantics.SemanticsActions +import androidx.compose.ui.semantics.SemanticsNode +import androidx.compose.ui.semantics.SemanticsPropertyKey +import androidx.compose.ui.test.ExperimentalTestApi +import androidx.compose.ui.test.MouseInjectionScope +import androidx.compose.ui.test.SemanticsMatcher +import androidx.compose.ui.test.SemanticsNodeInteraction +import androidx.compose.ui.test.assert +import androidx.compose.ui.test.assertContentDescriptionContains +import androidx.compose.ui.test.assertContentDescriptionEquals +import androidx.compose.ui.test.assertHasClickAction +import androidx.compose.ui.test.assertHasNoClickAction +import androidx.compose.ui.test.assertHeightIsAtLeast +import androidx.compose.ui.test.assertHeightIsEqualTo +import androidx.compose.ui.test.assertIsDisplayed +import androidx.compose.ui.test.assertIsEnabled +import androidx.compose.ui.test.assertIsFocused +import androidx.compose.ui.test.assertIsNotDisplayed +import androidx.compose.ui.test.assertIsNotEnabled +import androidx.compose.ui.test.assertIsNotFocused +import androidx.compose.ui.test.assertIsNotSelected +import androidx.compose.ui.test.assertIsOff +import androidx.compose.ui.test.assertIsOn +import androidx.compose.ui.test.assertIsSelectable +import androidx.compose.ui.test.assertIsSelected +import androidx.compose.ui.test.assertIsToggleable +import androidx.compose.ui.test.assertRangeInfoEquals +import androidx.compose.ui.test.assertTextContains +import androidx.compose.ui.test.assertTextEquals +import androidx.compose.ui.test.assertValueEquals +import androidx.compose.ui.test.assertWidthIsAtLeast +import androidx.compose.ui.test.assertWidthIsEqualTo +import androidx.compose.ui.test.click +import androidx.compose.ui.test.doubleClick +import androidx.compose.ui.test.longClick +import androidx.compose.ui.test.performImeAction +import androidx.compose.ui.test.performKeyPress +import androidx.compose.ui.test.performMouseInput +import androidx.compose.ui.test.performScrollTo +import androidx.compose.ui.test.performScrollToIndex +import androidx.compose.ui.test.performScrollToKey +import androidx.compose.ui.test.performScrollToNode +import androidx.compose.ui.test.performSemanticsAction +import androidx.compose.ui.test.performTextClearance +import androidx.compose.ui.test.performTextInput +import androidx.compose.ui.test.performTextInputSelection +import androidx.compose.ui.test.performTextReplacement +import androidx.compose.ui.test.performTouchInput +import androidx.compose.ui.test.printToLog +import androidx.compose.ui.test.swipe import androidx.compose.ui.text.AnnotatedString import androidx.compose.ui.text.TextRange import androidx.compose.ui.unit.Dp import com.atiurin.ultron.core.common.CommonOperationType -import com.atiurin.ultron.core.common.ElementInfo import com.atiurin.ultron.core.common.DefaultElementInfo +import com.atiurin.ultron.core.common.ElementInfo import com.atiurin.ultron.core.common.UltronOperationType import com.atiurin.ultron.core.common.assertion.DefaultOperationAssertion import com.atiurin.ultron.core.common.assertion.EmptyOperationAssertion import com.atiurin.ultron.core.common.assertion.OperationAssertion -import com.atiurin.ultron.core.common.options.* +import com.atiurin.ultron.core.common.options.ClickOption +import com.atiurin.ultron.core.common.options.ContentDescriptionContainsOption +import com.atiurin.ultron.core.common.options.DoubleClickOption +import com.atiurin.ultron.core.common.options.LongClickOption +import com.atiurin.ultron.core.common.options.PerformCustomBlockOption +import com.atiurin.ultron.core.common.options.TextContainsOption +import com.atiurin.ultron.core.common.options.TextEqualsOption import com.atiurin.ultron.core.compose.SemanticsNodeInteractionProviderContainer import com.atiurin.ultron.core.compose.config.UltronComposeConfig import com.atiurin.ultron.core.compose.operation.ComposeOperationExecutor import com.atiurin.ultron.core.compose.operation.ComposeOperationResult -import com.atiurin.ultron.core.compose.operation.ComposeOperationType.* +import com.atiurin.ultron.core.compose.operation.ComposeOperationType.ASSERT_MATCHES +import com.atiurin.ultron.core.compose.operation.ComposeOperationType.CLEAR_TEXT +import com.atiurin.ultron.core.compose.operation.ComposeOperationType.CLICK +import com.atiurin.ultron.core.compose.operation.ComposeOperationType.COLLAPSE +import com.atiurin.ultron.core.compose.operation.ComposeOperationType.CONTAINS_TEXT +import com.atiurin.ultron.core.compose.operation.ComposeOperationType.CONTENT_DESCRIPTION_CONTAINS_TEXT +import com.atiurin.ultron.core.compose.operation.ComposeOperationType.COPY_TEXT +import com.atiurin.ultron.core.compose.operation.ComposeOperationType.CUT_TEXT +import com.atiurin.ultron.core.compose.operation.ComposeOperationType.DISMISS +import com.atiurin.ultron.core.compose.operation.ComposeOperationType.DOES_NOT_EXIST +import com.atiurin.ultron.core.compose.operation.ComposeOperationType.DOUBLE_CLICK +import com.atiurin.ultron.core.compose.operation.ComposeOperationType.EXISTS +import com.atiurin.ultron.core.compose.operation.ComposeOperationType.EXPAND +import com.atiurin.ultron.core.compose.operation.ComposeOperationType.GET_SEMANTICS_NODE +import com.atiurin.ultron.core.compose.operation.ComposeOperationType.GET_TEXT +import com.atiurin.ultron.core.compose.operation.ComposeOperationType.HAS_CLICK_ACTION +import com.atiurin.ultron.core.compose.operation.ComposeOperationType.HAS_CONTENT_DESCRIPTION +import com.atiurin.ultron.core.compose.operation.ComposeOperationType.HAS_NO_CLICK_ACTION +import com.atiurin.ultron.core.compose.operation.ComposeOperationType.HEIGHT_IS_AT_LEAST +import com.atiurin.ultron.core.compose.operation.ComposeOperationType.HEIGHT_IS_EQUAL_TO +import com.atiurin.ultron.core.compose.operation.ComposeOperationType.IME_ACTION +import com.atiurin.ultron.core.compose.operation.ComposeOperationType.IS_DISPLAYED +import com.atiurin.ultron.core.compose.operation.ComposeOperationType.IS_ENABLED +import com.atiurin.ultron.core.compose.operation.ComposeOperationType.IS_FOCUSED +import com.atiurin.ultron.core.compose.operation.ComposeOperationType.IS_INDETERMINATE +import com.atiurin.ultron.core.compose.operation.ComposeOperationType.IS_NOT_DISPLAYED +import com.atiurin.ultron.core.compose.operation.ComposeOperationType.IS_NOT_ENABLED +import com.atiurin.ultron.core.compose.operation.ComposeOperationType.IS_NOT_FOCUSED +import com.atiurin.ultron.core.compose.operation.ComposeOperationType.IS_NOT_SELECTED +import com.atiurin.ultron.core.compose.operation.ComposeOperationType.IS_OFF +import com.atiurin.ultron.core.compose.operation.ComposeOperationType.IS_ON +import com.atiurin.ultron.core.compose.operation.ComposeOperationType.IS_SELECTABLE +import com.atiurin.ultron.core.compose.operation.ComposeOperationType.IS_SELECTED +import com.atiurin.ultron.core.compose.operation.ComposeOperationType.IS_TOGGLEABLE +import com.atiurin.ultron.core.compose.operation.ComposeOperationType.LONG_CLICK +import com.atiurin.ultron.core.compose.operation.ComposeOperationType.MOUSE_INPUT +import com.atiurin.ultron.core.compose.operation.ComposeOperationType.PASTE_TEXT +import com.atiurin.ultron.core.compose.operation.ComposeOperationType.PRESS_KEY +import com.atiurin.ultron.core.compose.operation.ComposeOperationType.PRINT_TO_LOG +import com.atiurin.ultron.core.compose.operation.ComposeOperationType.PROGRESS_BAR_RANGE_EQUALS +import com.atiurin.ultron.core.compose.operation.ComposeOperationType.REPLACE_TEXT +import com.atiurin.ultron.core.compose.operation.ComposeOperationType.SCROLL_TO +import com.atiurin.ultron.core.compose.operation.ComposeOperationType.SCROLL_TO_INDEX +import com.atiurin.ultron.core.compose.operation.ComposeOperationType.SCROLL_TO_KEY +import com.atiurin.ultron.core.compose.operation.ComposeOperationType.SCROLL_TO_NODE +import com.atiurin.ultron.core.compose.operation.ComposeOperationType.SEMANTIC_ACTION +import com.atiurin.ultron.core.compose.operation.ComposeOperationType.SET_PROGRESS +import com.atiurin.ultron.core.compose.operation.ComposeOperationType.SET_SELECTION +import com.atiurin.ultron.core.compose.operation.ComposeOperationType.SET_TEXT +import com.atiurin.ultron.core.compose.operation.ComposeOperationType.SWIPE_DOWN +import com.atiurin.ultron.core.compose.operation.ComposeOperationType.SWIPE_LEFT +import com.atiurin.ultron.core.compose.operation.ComposeOperationType.SWIPE_RIGHT +import com.atiurin.ultron.core.compose.operation.ComposeOperationType.SWIPE_UP +import com.atiurin.ultron.core.compose.operation.ComposeOperationType.TEXT_EQUALS +import com.atiurin.ultron.core.compose.operation.ComposeOperationType.TEXT_INPUT +import com.atiurin.ultron.core.compose.operation.ComposeOperationType.TEXT_INPUT_SELECTION +import com.atiurin.ultron.core.compose.operation.ComposeOperationType.VALUE_EQUALS +import com.atiurin.ultron.core.compose.operation.ComposeOperationType.WIDTH_IS_AT_LEAST +import com.atiurin.ultron.core.compose.operation.ComposeOperationType.WIDTH_IS_EQUAL_TO import com.atiurin.ultron.core.compose.operation.UltronComposeOperation import com.atiurin.ultron.core.compose.operation.UltronComposeOperationLifecycle import com.atiurin.ultron.core.compose.operation.UltronComposeOperationParams import com.atiurin.ultron.core.compose.option.ComposeSwipeOption import com.atiurin.ultron.exceptions.UltronOperationException -import com.atiurin.ultron.extensions.* +import com.atiurin.ultron.extensions.assertIsIndeterminate +import com.atiurin.ultron.extensions.getDefaultDoubleClickDelay +import com.atiurin.ultron.extensions.getDefaultLongClickDuration +import com.atiurin.ultron.extensions.getOneOfConfigFields +import com.atiurin.ultron.extensions.getSelectorDescription +import com.atiurin.ultron.extensions.getUltronComposeOffset +import com.atiurin.ultron.extensions.provideSwipeDownPosition +import com.atiurin.ultron.extensions.provideSwipeLeftPosition +import com.atiurin.ultron.extensions.provideSwipeRightPosition +import com.atiurin.ultron.extensions.provideSwipeUpPosition import com.atiurin.ultron.listeners.setListenersState import kotlinx.atomicfu.AtomicRef import kotlinx.atomicfu.atomic import kotlinx.atomicfu.update open class UltronComposeSemanticsNodeInteraction constructor( - val semanticsNodeInteraction: SemanticsNodeInteraction, + private val semanticsNodeInteractionProvider: () -> SemanticsNodeInteraction, val timeoutMs: Long = UltronComposeConfig.params.operationTimeoutMs, val resultHandler: ((ComposeOperationResult) -> Unit) = UltronComposeConfig.resultHandler, val assertion: OperationAssertion = EmptyOperationAssertion(), val elementInfo: ElementInfo = DefaultElementInfo() ) { + val semanticsNodeInteraction: SemanticsNodeInteraction + get() = semanticsNodeInteractionProvider() + + constructor( + semanticsNodeInteraction: SemanticsNodeInteraction, + timeoutMs: Long = UltronComposeConfig.params.operationTimeoutMs, + resultHandler: ((ComposeOperationResult) -> Unit) = UltronComposeConfig.resultHandler, + assertion: OperationAssertion = EmptyOperationAssertion(), + elementInfo: ElementInfo = DefaultElementInfo() + ) : this( + semanticsNodeInteractionProvider = { semanticsNodeInteraction }, + timeoutMs, resultHandler, assertion, elementInfo + ) + constructor( matcher: SemanticsMatcher, useUnmergedTree: Boolean = UltronComposeConfig.params.useUnmergedTree, @@ -45,7 +182,10 @@ open class UltronComposeSemanticsNodeInteraction constructor( resultHandler: ((ComposeOperationResult) -> Unit) = UltronComposeConfig.resultHandler, assertion: OperationAssertion = EmptyOperationAssertion(), elementInfo: ElementInfo = DefaultElementInfo() - ) : this(SemanticsNodeInteractionProviderContainer.getProvider().onNode(matcher, useUnmergedTree), timeoutMs, resultHandler, assertion, elementInfo) + ) : this( + semanticsNodeInteractionProvider = { SemanticsNodeInteractionProviderContainer.getProvider().onNode(matcher, useUnmergedTree) }, + timeoutMs, resultHandler, assertion, elementInfo + ) init { if (elementInfo.name.isEmpty()) elementInfo.name = semanticsNodeInteraction.getSelectorDescription() @@ -54,22 +194,30 @@ open class UltronComposeSemanticsNodeInteraction constructor( fun isSuccess(action: UltronComposeSemanticsNodeInteraction.() -> T): Boolean = runCatching { action() }.isSuccess fun withResultHandler(resultHandler: (ComposeOperationResult) -> Unit) = UltronComposeSemanticsNodeInteraction( - semanticsNodeInteraction, this.timeoutMs, resultHandler, this.assertion, this.elementInfo + semanticsNodeInteractionProvider, this.timeoutMs, resultHandler, this.assertion, this.elementInfo ) fun withTimeout(timeoutMs: Long) = UltronComposeSemanticsNodeInteraction( - semanticsNodeInteraction, timeoutMs, this.resultHandler, this.assertion, this.elementInfo + semanticsNodeInteractionProvider, timeoutMs, this.resultHandler, this.assertion, this.elementInfo ) - fun withAssertion(assertion: OperationAssertion) = UltronComposeSemanticsNodeInteraction(semanticsNodeInteraction, timeoutMs, resultHandler, assertion, this.elementInfo) + fun withAssertion(assertion: OperationAssertion) = + UltronComposeSemanticsNodeInteraction(semanticsNodeInteractionProvider, timeoutMs, resultHandler, assertion, this.elementInfo) + fun withAssertion(name: String = "", isListened: Boolean = false, block: () -> Unit) = - UltronComposeSemanticsNodeInteraction(semanticsNodeInteraction, timeoutMs, resultHandler, DefaultOperationAssertion(name, block.setListenersState(isListened)), this.elementInfo) + UltronComposeSemanticsNodeInteraction( + semanticsNodeInteractionProvider, + timeoutMs, + resultHandler, + DefaultOperationAssertion(name, block.setListenersState(isListened)), + this.elementInfo + ) fun withName(name: String) = apply { elementInfo.name = name } - + fun withMetaInfo(meta: Any) = apply { elementInfo.meta = meta } - + internal fun click(position: UltronComposeOffsets, option: ClickOption? = null) = apply { val _option = option ?: ClickOption(0, 0) executeOperation( @@ -428,7 +576,7 @@ open class UltronComposeSemanticsNodeInteraction constructor( @Deprecated("Use the method 'execute' instead", ReplaceWith("execute(params, block)")) fun perform(params: UltronComposeOperationParams? = null, block: (SemanticsNodeInteraction) -> T): T { val _params = params ?: getDefaultOperationParams() - val container : AtomicRef = atomic(null) + val container: AtomicRef = atomic(null) executeOperation( operationBlock = { container.update { block(semanticsNodeInteraction) } }, name = _params.operationName, @@ -477,7 +625,7 @@ open class UltronComposeSemanticsNodeInteraction constructor( */ fun execute(params: UltronComposeOperationParams? = null, block: (SemanticsNodeInteraction) -> T): T { val _params = params ?: getDefaultOperationParams() - val container : AtomicRef = atomic(null) + val container: AtomicRef = atomic(null) executeOperation( operationBlock = { container.update { block(semanticsNodeInteraction) } }, name = _params.operationName, diff --git a/ultron-compose/src/shared/kotlin/com/atiurin/ultron/core/compose/config/UltronComposeConfig.shared.kt b/ultron-compose/src/shared/kotlin/com/atiurin/ultron/core/compose/config/UltronComposeConfig.shared.kt new file mode 100644 index 00000000..b1e5c1ef --- /dev/null +++ b/ultron-compose/src/shared/kotlin/com/atiurin/ultron/core/compose/config/UltronComposeConfig.shared.kt @@ -0,0 +1,7 @@ +package com.atiurin.ultron.core.compose.config + +import com.atiurin.ultron.log.ULogger + +actual fun getPlatformLoggers(): List { + return emptyList() +} \ No newline at end of file