Skip to content

Commit

Permalink
Watcher with Kotlin support (#34)
Browse files Browse the repository at this point in the history
* Watcher with Kotlin support

* version = "0.6.4"

* targetSdkVersion 29
  • Loading branch information
Evgenii S authored Jun 18, 2020
1 parent c1b5328 commit df3b104
Show file tree
Hide file tree
Showing 14 changed files with 70 additions and 22 deletions.
2 changes: 1 addition & 1 deletion .circleci/config.yml.not.used
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
8 changes: 4 additions & 4 deletions library/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand All @@ -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 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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

/**
Expand All @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -34,12 +34,13 @@ class ViewMatcherWaiter constructor(val viewMatcher: Matcher<View>, val inRoot:
*/
fun toMatch(viewChecker: Matcher<View>) =
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 {
Expand All @@ -55,7 +56,8 @@ class ViewMatcherWaiter constructor(val viewMatcher: Matcher<View>, 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 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
@@ -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
}
Original file line number Diff line number Diff line change
@@ -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
}
}
4 changes: 2 additions & 2 deletions sample/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down

0 comments on commit df3b104

Please sign in to comment.