Skip to content

Commit

Permalink
Adding CreateTransactionE2E
Browse files Browse the repository at this point in the history
  • Loading branch information
philipplackner committed Aug 9, 2023
1 parent 5a355f0 commit 3c1723b
Show file tree
Hide file tree
Showing 7 changed files with 208 additions and 4 deletions.
52 changes: 52 additions & 0 deletions app/src/androidTest/java/com/ivy/CreateTransactionE2E.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package com.ivy

import androidx.compose.ui.test.junit4.createAndroidComposeRule
import com.ivy.common.androidtest.IvyAndroidTest
import com.ivy.core.data.CategoryType
import com.ivy.home.HomeScreenRobot
import com.ivy.navigation.Navigator
import com.ivy.transaction.NewTransactionRobot
import com.ivy.wallet.ui.RootActivity
import dagger.hilt.android.testing.HiltAndroidTest
import org.junit.Rule
import org.junit.Test
import javax.inject.Inject

@HiltAndroidTest
class CreateTransactionE2E: IvyAndroidTest() {

@get:Rule
val composeRule = createAndroidComposeRule<RootActivity>()

@Inject
lateinit var navigator: Navigator

@Test
fun testCreatingExpenseWithCategoriesAndAccount() {
val homeScreenRobot = HomeScreenRobot(composeRule)

homeScreenRobot
.navigateTo(navigator)
.clickNewTransaction()
.clickExpense()

NewTransactionRobot(composeRule)
.addAccount("PayPal")
.selectAccount("PayPal")
.enterTransactionAmount(65)
.addCategory("Transport", CategoryType.Expense, null)
.addCategory("Car", CategoryType.Expense, "Transport")
.chooseSubCategory("Transport", "Car")
.enterTransactionTitle("Fuel")
.enterTransactionDescription("For my Ford")
.clickAddTransaction()

homeScreenRobot
.assertTotalExpensesIs(65)
.assertTransactionIsDisplayed(
transactionTitle = "Fuel",
accountName = "PayPal",
categoryName = "Car"
)
}
}
33 changes: 33 additions & 0 deletions app/src/androidTest/java/com/ivy/home/HomeScreenRobot.kt
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
package com.ivy.home

import androidx.compose.ui.test.assertIsDisplayed
import androidx.compose.ui.test.assertTextEquals
import androidx.compose.ui.test.hasAnySibling
import androidx.compose.ui.test.hasText
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
import androidx.compose.ui.test.onAllNodesWithTag
import androidx.compose.ui.test.onFirst
import androidx.compose.ui.test.onLast
import androidx.compose.ui.test.onNodeWithContentDescription
import androidx.compose.ui.test.onNodeWithText
import androidx.compose.ui.test.performClick
import androidx.compose.ui.test.performScrollTo
Expand Down Expand Up @@ -76,6 +80,17 @@ class HomeScreenRobot(
return this
}

fun assertTransactionIsDisplayed(
transactionTitle: String,
accountName: String,
categoryName: String
): HomeScreenRobot {
composeRule.onNodeWithText(transactionTitle).assertIsDisplayed()
composeRule.onNodeWithText(accountName).assertIsDisplayed()
composeRule.onNodeWithText(categoryName).assertIsDisplayed()
return this
}

fun openOverdue(): HomeScreenRobot {
composeRule
.onNodeWithText("Overdue")
Expand Down Expand Up @@ -104,4 +119,22 @@ class HomeScreenRobot(
return this
}

fun clickNewTransaction(): HomeScreenRobot {
composeRule.onNodeWithContentDescription("Add new transaction").performClick()
return this
}

fun clickExpense(): HomeScreenRobot {
composeRule.onNodeWithContentDescription("Create new expense").performClick()
return this
}

fun assertTotalExpensesIs(amount: Int): HomeScreenRobot {
composeRule
.onAllNodesWithTag("amount", useUnmergedTree = true)
.onLast()
.assertTextEquals(amount.toString())
return this
}

}
101 changes: 101 additions & 0 deletions app/src/androidTest/java/com/ivy/transaction/NewTransactionRobot.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
package com.ivy.transaction

import androidx.compose.ui.test.hasClickAction
import androidx.compose.ui.test.hasTestTag
import androidx.compose.ui.test.hasText
import androidx.compose.ui.test.onAllNodesWithText
import androidx.compose.ui.test.onLast
import androidx.compose.ui.test.onNodeWithContentDescription
import androidx.compose.ui.test.onNodeWithText
import androidx.compose.ui.test.performClick
import androidx.compose.ui.test.performTextInput
import com.ivy.IvyComposeRule
import com.ivy.core.data.CategoryType

class NewTransactionRobot(
private val composeRule: IvyComposeRule
) {
fun addAccount(name: String): NewTransactionRobot {
composeRule.onNodeWithText("Add account").performClick()
composeRule.onNodeWithContentDescription("New account").performTextInput(name)
composeRule.onAllNodesWithText("Add account").onLast().performClick()
return this
}

fun selectAccount(name: String): NewTransactionRobot {
composeRule.onNodeWithText(name).performClick()
return this
}

fun enterTransactionAmount(amount: Int): NewTransactionRobot {
val digits = amount.toString().map { it.digitToInt() }
digits.forEach { digit ->
composeRule.onNode(
hasText(digit.toString()) and hasClickAction()
).performClick()
}
composeRule.onNodeWithText("Enter").performClick()
return this
}

fun addCategory(name: String, type: CategoryType, parentName: String?): NewTransactionRobot {
clickAddCategoryOnNewCategoryModal()
.enterCategoryName(name)
.selectCategoryType(type)
.apply {
if(parentName != null) {
chooseParent(parentName)
}
}
.clickAddCategoryOnNewCategoryModal()
return this
}

private fun clickAddCategoryOnNewCategoryModal(): NewTransactionRobot {
composeRule.onAllNodesWithText("Add category").onLast().performClick()
return this
}

private fun enterCategoryName(name: String): NewTransactionRobot {
composeRule.onNodeWithContentDescription("New Category").performTextInput(name)
return this
}

private fun selectCategoryType(type: CategoryType): NewTransactionRobot {
composeRule.onNode(
hasText(type.toString()) and hasTestTag("category_type_button")
).performClick()
return this
}

private fun chooseParent(parentName: String): NewTransactionRobot {
composeRule.onNodeWithText("Choose parent").performClick()
composeRule.onAllNodesWithText(parentName).onLast().performClick()
return this
}

fun chooseSubCategory(parentName: String, subName: String): NewTransactionRobot {
composeRule.onNodeWithText(parentName).performClick()
composeRule.onNodeWithText(subName).performClick()
return this
}

fun enterTransactionTitle(title: String): NewTransactionRobot {
composeRule.onNodeWithContentDescription("Title").performTextInput(title)
return this
}

fun enterTransactionDescription(description: String): NewTransactionRobot {
composeRule.onNodeWithText("Add description").performClick()
composeRule
.onNodeWithContentDescription("Enter any details here")
.performTextInput(description)
composeRule.onAllNodesWithText("Add").onLast().performClick()
return this
}

fun clickAddTransaction(): NewTransactionRobot {
composeRule.onNodeWithText("Add").performClick()
return this
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.ivy.data.category.CategoryType
Expand Down Expand Up @@ -68,7 +69,7 @@ private fun CategoryTypeButton(
onSelect: (CategoryType) -> Unit
) {
IvyButton(
modifier = modifier,
modifier = modifier.testTag("category_type_button"),
size = ButtonSize.Small,
visibility = if (selected) Visibility.High else Visibility.Medium,
feeling = if (selected) Feeling.Custom(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Shape
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardCapitalization
Expand Down Expand Up @@ -42,7 +44,10 @@ fun IvyInputField(
) {
val keyboardController = LocalSoftwareKeyboardController.current
InputField(
modifier = modifier,
modifier = modifier
.semantics {
contentDescription = placeholder
},
initialValue = initialValue,
placeholder = placeholder,
isError = isError,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.ivy.design.animation.slideInBottom
Expand Down Expand Up @@ -141,7 +143,11 @@ private fun ActionButton(
onClick: () -> Unit
) {
IvyButton(
modifier = Modifier.size(52.dp),
modifier = Modifier
.size(52.dp)
.semantics {
contentDescription = "Add new transaction"
},
// modifier = Modifier.pointerInput(Unit) {
// detectDragGestures(
// onDragCancel = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.ivy.design.l0_system.UI
Expand Down Expand Up @@ -60,7 +62,11 @@ internal fun BoxScope.AddTransactionModal(
)
SpacerVer(height = 12.dp)
IvyButton(
modifier = Modifier.padding(horizontal = 16.dp),
modifier = Modifier
.padding(horizontal = 16.dp)
.semantics {
contentDescription = "Create new expense"
},
size = ButtonSize.Big,
visibility = Visibility.Medium,
feeling = Feeling.Custom(UI.colors.red),
Expand Down

0 comments on commit 3c1723b

Please sign in to comment.