Skip to content

Commit

Permalink
Merge pull request KasperskyLab#76 from RuslanMingaliev/feature/botto…
Browse files Browse the repository at this point in the history
…m_nav_checkbox

feature=Kautomator_views: BottomNavigationView + Checkbox
  • Loading branch information
matzuk authored Jan 16, 2020
2 parents e6d5f6d + 1c2f758 commit 4ca5586
Show file tree
Hide file tree
Showing 15 changed files with 347 additions and 19 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
@file:Suppress("unused")
package com.kaspersky.components.kautomator.dsl.bottomnav

import com.kaspersky.components.kautomator.dsl.common.builders.UiViewBuilder
import com.kaspersky.components.kautomator.dsl.common.builders.UiViewSelector
import com.kaspersky.components.kautomator.dsl.common.views.UiBaseView

/**
* View for acting and asserting on BottomNavigationView
*
* @see UiBottomNavigationViewActions
* @see UiBottomNavigationViewAssertions
*/
class UiBottomNavigationView : UiBaseView<UiBottomNavigationView>, UiBottomNavigationViewActions, UiBottomNavigationViewAssertions {
constructor(selector: UiViewSelector) : super(selector)
constructor(builder: UiViewBuilder.() -> Unit) : super(builder)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
@file:Suppress("unused")
package com.kaspersky.components.kautomator.dsl.bottomnav

import androidx.test.uiautomator.By
import com.kaspersky.components.kautomator.dsl.common.actions.UiBaseActions
import com.kaspersky.components.kautomator.intercepting.operation.UiOperationType

/**
* Provides actions for BottomNavigationView
*/
interface UiBottomNavigationViewActions : UiBaseActions {

/**
* Selects menu item with given id
*
* @param id Menu item id
*/
fun setSelectedItemWithId(id: String) {
view.perform(UiBottomNavigationViewActionType.SELECT_WITH_ID) {
findObject(By.res(applicationPackage, id)).click()
}
}

/**
* Selects menu item with given index. Note that this method uses view hierarchy which could be changed at any time.
*
* @param index Menu item index
*/
fun setSelectedItemWithIndex(index: Int) {
view.perform(UiBottomNavigationViewActionType.SELECT_WITH_INDEX) {
children[0] // ViewGroup with menu items
.children[index] // Menu item with index
.click()
}
}

/**
* Selects menu item with given title. Note that this method uses view hierarchy which could be changed at any time.
*
* @param title Menu item title
*/
fun setSelectedItemWithTitle(title: String) {
view.perform(UiBottomNavigationViewActionType.SELECT_WITH_TITLE) {
findObject(By.text(title)).click()
}
}

enum class UiBottomNavigationViewActionType : UiOperationType {
SELECT_WITH_ID,
SELECT_WITH_INDEX,
SELECT_WITH_TITLE
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
@file:Suppress("unused")
package com.kaspersky.components.kautomator.dsl.bottomnav

import androidx.test.uiautomator.By
import com.google.common.truth.Truth.assertThat
import com.kaspersky.components.kautomator.dsl.common.assertions.UiBaseAssertions
import com.kaspersky.components.kautomator.intercepting.operation.UiOperationType

/**
* Provides assertions for BottomNavigationview
*/
interface UiBottomNavigationViewAssertions : UiBaseAssertions {

/**
* Checks if the view's selected menu item id matches given one
*
* @param id Menu item id
*/
fun hasSelectedItemWithId(id: String) {
view.check(UiBottomNavigationViewAssertionType.IS_SELECTED_ITEM_WITH_ID) {
val item = findObject(By.res(applicationPackage, id))
assertThat(item.isSelected).isTrue()
}
}

/**
* Checks if the view's selected menu item id does not match given one.
*
* @param id Menu item id
*/
fun hasNotSelectedItemWithId(id: String) {
view.check(UiBottomNavigationViewAssertionType.IS_NOT_SELECTED_ITEM_WITH_ID) {
val item = findObject(By.res(applicationPackage, id))
assertThat(item.isSelected).isFalse()
}
}

/**
* Checks if the view's selected menu item index matches given one.
* Note that this method uses view hierarchy which could be changed at any time.
*
* @param index Menu item index
*/
fun hasSelectedItemWithIndex(index: Int) {
view.check(UiBottomNavigationViewAssertionType.IS_SELECTED_ITEM_WITH_INDEX) {
val item = children[0] // ViewGroup with menu items
.children[index] // Menu item with index
assertThat(item.isSelected).isTrue()
}
}

/**
* Checks if the view's selected menu item index does not match given one.
* Note that this method uses view hierarchy which could be changed at any time.
*
* @param index Menu item index
*/
fun hasNotSelectedItemWithIndex(index: Int) {
view.check(UiBottomNavigationViewAssertionType.IS_NOT_SELECTED_ITEM_WITH_INDEX) {
val item = children[0] // ViewGroup with menu items
.children[index] // Menu item with index
assertThat(item.isSelected).isFalse()
}
}

/**
* Checks if the view's selected menu item title matches given one.
* Note that this method uses view hierarchy which could be changed at any time.
*
* @param title Menu item title
*/
fun hasSelectedItemWithTitle(title: String) {
view.check(UiBottomNavigationViewAssertionType.IS_SELECTED_ITEM_WITH_TITLE) {
val item = findObject(By.text(title))
.parent // BaselineLayout
.parent // Menu item
assertThat(item.isSelected).isTrue()
}
}

/**
* Checks if the view's selected menu item title does not match given one.
* Note that this method uses view hierarchy which could be changed at any time.
*
* @param title Menu item title
*/
fun hasNotSelectedItemWithTitle(title: String) {
view.check(UiBottomNavigationViewAssertionType.IS_NOT_SELECTED_ITEM_WITH_TITLE) {
val item = findObject(By.text(title))
.parent // BaselineLayout
.parent // Menu item
assertThat(item.isSelected).isFalse()
}
}

enum class UiBottomNavigationViewAssertionType : UiOperationType {
IS_SELECTED_ITEM_WITH_ID,
IS_NOT_SELECTED_ITEM_WITH_ID,
IS_SELECTED_ITEM_WITH_INDEX,
IS_NOT_SELECTED_ITEM_WITH_INDEX,
IS_SELECTED_ITEM_WITH_TITLE,
IS_NOT_SELECTED_ITEM_WITH_TITLE
}
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
@file:Suppress("unused")
package com.kaspersky.components.kautomator.dsl.check

import com.kaspersky.components.kautomator.dsl.common.builders.UiViewBuilder
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
@file:Suppress("unused")
package com.kaspersky.components.kautomator.dsl.check

import com.kaspersky.components.kautomator.dsl.check.UiCheckableActions.CheckableActionType.SET_CHECKED
import com.kaspersky.components.kautomator.dsl.common.actions.UiBaseActions
import com.kaspersky.components.kautomator.intercepting.operation.UiOperationType

/**
* Provides actions for checkable views
*/
interface UiCheckableActions : UiBaseActions {

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
@file:Suppress("unused")
package com.kaspersky.components.kautomator.dsl.check

import com.google.common.truth.Truth.assertThat
import com.kaspersky.components.kautomator.dsl.common.assertions.UiBaseAssertions
import com.kaspersky.components.kautomator.intercepting.operation.UiOperationType

/**
* Provides assertions for UiCheckBox
* Provides assertions for checkable views
*/
interface UiCheckableAssertions : UiBaseAssertions {

Expand All @@ -23,24 +24,8 @@ interface UiCheckableAssertions : UiBaseAssertions {
view.check(CheckableAssertionType.IS_NOT_CHECKED) { assertThat(isChecked).isFalse() }
}

/**
* Checks if the view is checkable
*/
fun isCheckable() {
view.check(CheckableAssertionType.IS_CHECKABLE) { assertThat(isCheckable).isTrue() }
}

/**
* Checks if the view is not checkable
*/
fun isNotCheckable() {
view.check(CheckableAssertionType.IS_NOT_CHECKABLE) { assertThat(isCheckable).isFalse() }
}

enum class CheckableAssertionType : UiOperationType {
IS_CHECKED,
IS_NOT_CHECKED,
IS_CHECKABLE,
IS_NOT_CHECKABLE
IS_NOT_CHECKED
}
}
3 changes: 2 additions & 1 deletion sample_kautomator/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ android {
buildToolsVersion versions.buildTools

defaultConfig {
applicationId "com.kaspersky.kaspresso.sample_uiautomator_dsl"
applicationId "com.kaspersky.kaspresso.sample_kautomator"
minSdkVersion versions.minSdk
targetSdkVersion versions.targetSdk
versionCode 1
Expand All @@ -28,6 +28,7 @@ android {

dependencies {
implementation "androidx.appcompat:appcompat:$versions.androidSupport"
implementation 'com.google.android.material:material:1.0.0'
implementation "androidx.constraintlayout:constraintlayout:$versions.constraint"

testImplementation "junit:junit:$versions.junit"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.kaspersky.kaspresso.sample_kautomator.screen

import com.kaspersky.components.kautomator.dsl.bottomnav.UiBottomNavigationView
import com.kaspersky.components.kautomator.dsl.check.UiCheckBox
import com.kaspersky.components.kautomator.dsl.screen.UiScreen

object ComponentsScreen : UiScreen<ComponentsScreen>() {

private const val MAIN_APP_PACKAGE_ID = "com.kaspersky.kaspresso.sample_kautomator"

val bottomNav = UiBottomNavigationView { withId(this@ComponentsScreen.MAIN_APP_PACKAGE_ID, "bottomNav") }
val checkbox = UiCheckBox { withId(this@ComponentsScreen.MAIN_APP_PACKAGE_ID, "checkBox") }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package com.kaspersky.kaspresso.sample_kautomator.test.components

import androidx.test.rule.ActivityTestRule
import com.kaspersky.kaspresso.sample_kautomator.ComponentsActivity
import com.kaspersky.kaspresso.sample_kautomator.screen.ComponentsScreen
import com.kaspersky.kaspresso.testcases.api.testcase.TestCase
import org.junit.Rule
import org.junit.Test

class BottomNavigationViewTest : TestCase() {

companion object {
private const val ITEM_0_TEXT = "Menu Item 1"
private const val ITEM_1_TEXT = "Menu Item 2"

private const val ITEM_0_ID = "menu_item_1"
private const val ITEM_1_ID = "menu_item_2"
}

@get:Rule
val rule = ActivityTestRule(ComponentsActivity::class.java, true, true)

@Test
fun test() {
run {

step("Select item by id") {
ComponentsScreen {
bottomNav {
setSelectedItemWithId(ITEM_1_ID)
hasSelectedItemWithId(ITEM_1_ID)
hasNotSelectedItemWithId(ITEM_0_ID)
}
}
}

step("Select item by index") {
ComponentsScreen {
bottomNav {
setSelectedItemWithIndex(0)
hasSelectedItemWithIndex(0)
hasNotSelectedItemWithIndex(1)
}
}
}

step("Select item by label") {
ComponentsScreen {
bottomNav {
setSelectedItemWithTitle(ITEM_1_TEXT)
hasSelectedItemWithTitle(ITEM_1_TEXT)
hasNotSelectedItemWithTitle(ITEM_0_TEXT)
}
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package com.kaspersky.kaspresso.sample_kautomator.test.components

import androidx.test.rule.ActivityTestRule
import com.kaspersky.kaspresso.sample_kautomator.ComponentsActivity
import com.kaspersky.kaspresso.sample_kautomator.screen.ComponentsScreen
import com.kaspersky.kaspresso.testcases.api.testcase.TestCase
import org.junit.Rule
import org.junit.Test

class CheckboxTest : TestCase() {

@get:Rule
val rule = ActivityTestRule(ComponentsActivity::class.java, true, true)

@Test
fun test() {
run {
step("Set checked") {
ComponentsScreen {
checkbox {
setChecked(true)
isChecked()
}
}
}

step("Set not checked") {
ComponentsScreen {
checkbox {
setChecked(false)
isNotChecked()
}
}
}
}
}
}
2 changes: 2 additions & 0 deletions sample_kautomator/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

<activity android:name=".ComponentsActivity"/>
</application>

</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.kaspersky.kaspresso.sample_kautomator

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity

class ComponentsActivity : AppCompatActivity() {

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_ui_components)
}
}
Loading

0 comments on commit 4ca5586

Please sign in to comment.