From df3b104805a738b464b10de9484f743913f50898 Mon Sep 17 00:00:00 2001 From: Evgenii S Date: Thu, 18 Jun 2020 17:08:22 +0300 Subject: [PATCH] Watcher with Kotlin support (#34) * Watcher with Kotlin support * version = "0.6.4" * targetSdkVersion 29 --- .circleci/config.yml.not.used | 2 +- .travis.yml | 2 +- library/build.gradle | 8 ++--- .../kopi/library/steps/DeviceSteps.kt | 4 +-- .../kopi/library/wait/BaseInstruction.kt | 2 +- .../kopi/library/wait/ViewMatcherWaiter.kt | 20 ++++++----- .../kopi/library/wait/WaitForActivity.kt | 4 +-- .../kopi/library/watcher/Instruction.kt | 10 ++++++ .../kopi/library/watcher/Watcher.kt | 36 +++++++++++++++++++ sample/build.gradle | 4 +-- .../kopi/sample/ElementActionTest.kt | 0 .../kopi/sample/ElementAssertionTest.kt | 0 .../kopi/sample/ElementMatcherTest.kt | 0 .../kopi/sample/ElementWaitTest.kt | 0 14 files changed, 70 insertions(+), 22 deletions(-) create mode 100644 library/src/main/java/com/qautomatron/kopi/library/watcher/Instruction.kt create mode 100644 library/src/main/java/com/qautomatron/kopi/library/watcher/Watcher.kt rename sample/src/androidTest/{java => kotlin}/com/qautomatron/kopi/sample/ElementActionTest.kt (100%) rename sample/src/androidTest/{java => kotlin}/com/qautomatron/kopi/sample/ElementAssertionTest.kt (100%) rename sample/src/androidTest/{java => kotlin}/com/qautomatron/kopi/sample/ElementMatcherTest.kt (100%) rename sample/src/androidTest/{java => kotlin}/com/qautomatron/kopi/sample/ElementWaitTest.kt (100%) diff --git a/.circleci/config.yml.not.used b/.circleci/config.yml.not.used index 556b868..251553c 100644 --- a/.circleci/config.yml.not.used +++ b/.circleci/config.yml.not.used @@ -3,7 +3,7 @@ jobs: build: working_directory: ~/code docker: - - image: circleci/android:api-28 + - image: circleci/android:api-29 environment: JVM_OPTS: -Xmx3200m steps: diff --git a/.travis.yml b/.travis.yml index 1cb310e..895825b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,7 +5,7 @@ android: - tools - platform-tools - build-tools-29.0.2 - - android-28 + - android-29 - android-22 - sys-img-armeabi-v7a-android-22 - extra diff --git a/library/build.gradle b/library/build.gradle index 7c39b91..db3956f 100644 --- a/library/build.gradle +++ b/library/build.gradle @@ -5,14 +5,14 @@ plugins { id 'digital.wup.android-maven-publish' version '3.6.3' } -version = "0.6.3" +version = "0.6.4" android { - compileSdkVersion 28 + compileSdkVersion 29 defaultConfig { minSdkVersion 15 - targetSdkVersion 28 + targetSdkVersion 29 versionCode 1 versionName "1.0" @@ -35,10 +35,10 @@ dependencies { api "androidx.test.espresso:espresso-contrib:$espressoVersion" api "androidx.test.espresso:espresso-intents:$espressoVersion" api "androidx.test.uiautomator:uiautomator:$uiAutomatorVersion" - api "com.azimolabs.conditionwatcher:conditionwatcher:$conditionWatcherVersion" testImplementation 'junit:junit:4.13' api "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" + api "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.7" } repositories { diff --git a/library/src/main/java/com/qautomatron/kopi/library/steps/DeviceSteps.kt b/library/src/main/java/com/qautomatron/kopi/library/steps/DeviceSteps.kt index a1f4b00..e823ecb 100644 --- a/library/src/main/java/com/qautomatron/kopi/library/steps/DeviceSteps.kt +++ b/library/src/main/java/com/qautomatron/kopi/library/steps/DeviceSteps.kt @@ -6,10 +6,10 @@ import androidx.test.espresso.matcher.ViewMatchers.isRoot import androidx.test.uiautomator.By import androidx.test.uiautomator.UiDevice import androidx.test.uiautomator.Until -import com.azimolabs.conditionwatcher.ConditionWatcher import com.qautomatron.kopi.library.element.action.SleepAction import com.qautomatron.kopi.library.instrumentation import com.qautomatron.kopi.library.wait.WaitForActivity +import com.qautomatron.kopi.library.watcher.Watcher import org.junit.Assert.assertTrue /** @@ -20,7 +20,7 @@ object DeviceSteps { /** * Wait for activity by name */ - fun waitForActivity(fullName: String) = ConditionWatcher.waitForCondition(WaitForActivity(fullName)) + fun waitForActivity(fullName: String) = Watcher.waitForCondition(WaitForActivity(fullName)) /** * Will use UI Automator to wait for package with name to be active diff --git a/library/src/main/java/com/qautomatron/kopi/library/wait/BaseInstruction.kt b/library/src/main/java/com/qautomatron/kopi/library/wait/BaseInstruction.kt index cb37855..0c1975e 100644 --- a/library/src/main/java/com/qautomatron/kopi/library/wait/BaseInstruction.kt +++ b/library/src/main/java/com/qautomatron/kopi/library/wait/BaseInstruction.kt @@ -3,8 +3,8 @@ package com.qautomatron.kopi.library.wait import android.app.Activity import androidx.test.runner.lifecycle.ActivityLifecycleMonitorRegistry import androidx.test.runner.lifecycle.Stage -import com.azimolabs.conditionwatcher.Instruction import com.qautomatron.kopi.library.instrumentation +import com.qautomatron.kopi.library.watcher.Instruction /** * Base instruction to provide activity to watchers diff --git a/library/src/main/java/com/qautomatron/kopi/library/wait/ViewMatcherWaiter.kt b/library/src/main/java/com/qautomatron/kopi/library/wait/ViewMatcherWaiter.kt index 9829e68..7ee491d 100644 --- a/library/src/main/java/com/qautomatron/kopi/library/wait/ViewMatcherWaiter.kt +++ b/library/src/main/java/com/qautomatron/kopi/library/wait/ViewMatcherWaiter.kt @@ -7,8 +7,8 @@ import androidx.test.espresso.Root import androidx.test.espresso.ViewAssertion import androidx.test.espresso.assertion.ViewAssertions.matches import androidx.test.espresso.matcher.RootMatchers -import com.azimolabs.conditionwatcher.ConditionWatcher.waitForCondition -import com.azimolabs.conditionwatcher.Instruction +import com.qautomatron.kopi.library.watcher.Instruction +import com.qautomatron.kopi.library.watcher.Watcher.waitForCondition import org.hamcrest.Matcher import org.hamcrest.StringDescription @@ -34,12 +34,13 @@ class ViewMatcherWaiter constructor(val viewMatcher: Matcher, val inRoot: */ fun toMatch(viewChecker: Matcher) = waitForCondition(object : Instruction() { - override fun getDescription(): String { - val desc = desc - desc.appendText(" to match ") - viewChecker.describeTo(desc) - return desc.toString() - } + override val description: String + get() { + val desc = desc + desc.appendText(" to match ") + viewChecker.describeTo(desc) + return desc.toString() + } override fun checkCondition(): Boolean { return try { @@ -55,7 +56,8 @@ class ViewMatcherWaiter constructor(val viewMatcher: Matcher, val inRoot: fun toCheck(viewAssertion: ViewAssertion) = waitForCondition(object : Instruction() { - override fun getDescription(): String = desc.appendText(" to check ").toString() + override val description: String + get() = desc.appendText(" to check ").toString() override fun checkCondition(): Boolean { return try { diff --git a/library/src/main/java/com/qautomatron/kopi/library/wait/WaitForActivity.kt b/library/src/main/java/com/qautomatron/kopi/library/wait/WaitForActivity.kt index cf0c162..d8b78b9 100644 --- a/library/src/main/java/com/qautomatron/kopi/library/wait/WaitForActivity.kt +++ b/library/src/main/java/com/qautomatron/kopi/library/wait/WaitForActivity.kt @@ -5,8 +5,8 @@ package com.qautomatron.kopi.library.wait */ class WaitForActivity(private val name: String) : BaseInstruction() { - override fun getDescription(): String = - "Current activity should be same as <$name> but was <${activityInstance?.localClassName}>" + override val description: String + get() = "Current activity should be same as <$name> but was <${activityInstance?.localClassName}>" override fun checkCondition(): Boolean { val activity = activityInstance ?: return false diff --git a/library/src/main/java/com/qautomatron/kopi/library/watcher/Instruction.kt b/library/src/main/java/com/qautomatron/kopi/library/watcher/Instruction.kt new file mode 100644 index 0000000..778a91f --- /dev/null +++ b/library/src/main/java/com/qautomatron/kopi/library/watcher/Instruction.kt @@ -0,0 +1,10 @@ +package com.qautomatron.kopi.library.watcher + +import android.os.Bundle + +abstract class Instruction { + var dataContainer = Bundle() + + abstract val description: String + abstract fun checkCondition(): Boolean +} \ No newline at end of file diff --git a/library/src/main/java/com/qautomatron/kopi/library/watcher/Watcher.kt b/library/src/main/java/com/qautomatron/kopi/library/watcher/Watcher.kt new file mode 100644 index 0000000..158acfd --- /dev/null +++ b/library/src/main/java/com/qautomatron/kopi/library/watcher/Watcher.kt @@ -0,0 +1,36 @@ +package com.qautomatron.kopi.library.watcher + +import kotlinx.coroutines.delay +import kotlinx.coroutines.runBlocking + +object Watcher { + + private const val DEFAULT_TIMEOUT_LIMIT = 1000 * 60 + private const val DEFAULT_INTERVAL = 250 + + var timeoutLimit = DEFAULT_TIMEOUT_LIMIT + var watchInterval = DEFAULT_INTERVAL + + @Throws(Exception::class) + fun waitForCondition(instruction: Instruction) { + var status = Status.CONDITION_NOT_MET + var elapsedTime = 0 + do { + if (instruction.checkCondition()) { + status = Status.CONDITION_MET + } else { + elapsedTime += watchInterval + runBlocking { delay(watchInterval.toLong()) } + } + if (elapsedTime >= timeoutLimit) { + status = Status.TIMEOUT + break + } + } while (status != Status.CONDITION_MET) + if (status == Status.TIMEOUT) throw Exception(instruction.description + " - took more than " + timeoutLimit / 1000 + " seconds. Test stopped.") + } + + enum class Status { + CONDITION_NOT_MET, CONDITION_MET, TIMEOUT + } +} \ No newline at end of file diff --git a/sample/build.gradle b/sample/build.gradle index 0d29189..5588d78 100644 --- a/sample/build.gradle +++ b/sample/build.gradle @@ -5,11 +5,11 @@ plugins { } android { - compileSdkVersion 28 + compileSdkVersion 29 defaultConfig { applicationId "com.qautomatron.kopi.sample" minSdkVersion 15 - targetSdkVersion 28 + targetSdkVersion 29 versionCode 1 versionName "1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" diff --git a/sample/src/androidTest/java/com/qautomatron/kopi/sample/ElementActionTest.kt b/sample/src/androidTest/kotlin/com/qautomatron/kopi/sample/ElementActionTest.kt similarity index 100% rename from sample/src/androidTest/java/com/qautomatron/kopi/sample/ElementActionTest.kt rename to sample/src/androidTest/kotlin/com/qautomatron/kopi/sample/ElementActionTest.kt diff --git a/sample/src/androidTest/java/com/qautomatron/kopi/sample/ElementAssertionTest.kt b/sample/src/androidTest/kotlin/com/qautomatron/kopi/sample/ElementAssertionTest.kt similarity index 100% rename from sample/src/androidTest/java/com/qautomatron/kopi/sample/ElementAssertionTest.kt rename to sample/src/androidTest/kotlin/com/qautomatron/kopi/sample/ElementAssertionTest.kt diff --git a/sample/src/androidTest/java/com/qautomatron/kopi/sample/ElementMatcherTest.kt b/sample/src/androidTest/kotlin/com/qautomatron/kopi/sample/ElementMatcherTest.kt similarity index 100% rename from sample/src/androidTest/java/com/qautomatron/kopi/sample/ElementMatcherTest.kt rename to sample/src/androidTest/kotlin/com/qautomatron/kopi/sample/ElementMatcherTest.kt diff --git a/sample/src/androidTest/java/com/qautomatron/kopi/sample/ElementWaitTest.kt b/sample/src/androidTest/kotlin/com/qautomatron/kopi/sample/ElementWaitTest.kt similarity index 100% rename from sample/src/androidTest/java/com/qautomatron/kopi/sample/ElementWaitTest.kt rename to sample/src/androidTest/kotlin/com/qautomatron/kopi/sample/ElementWaitTest.kt