Skip to content

Commit

Permalink
Add initial CustomerSheet end-to-end tests.
Browse files Browse the repository at this point in the history
  • Loading branch information
samer-stripe committed May 23, 2024
1 parent c79c564 commit 476b725
Show file tree
Hide file tree
Showing 4 changed files with 220 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,14 @@ import com.stripe.android.paymentsheet.example.playground.settings.CollectAddres
import com.stripe.android.paymentsheet.example.playground.settings.CollectEmailSettingsDefinition
import com.stripe.android.paymentsheet.example.playground.settings.CollectNameSettingsDefinition
import com.stripe.android.paymentsheet.example.playground.settings.CollectPhoneSettingsDefinition
import com.stripe.android.paymentsheet.example.playground.settings.Country
import com.stripe.android.paymentsheet.example.playground.settings.CountrySettingsDefinition
import com.stripe.android.paymentsheet.example.playground.settings.CustomerSettingsDefinition
import com.stripe.android.paymentsheet.example.playground.settings.CustomerSheetPaymentMethodModeDefinition
import com.stripe.android.paymentsheet.example.playground.settings.CustomerType
import com.stripe.android.paymentsheet.example.playground.settings.DefaultBillingAddress
import com.stripe.android.paymentsheet.example.playground.settings.DefaultBillingAddressSettingsDefinition
import com.stripe.android.paymentsheet.example.playground.settings.PaymentMethodMode
import com.stripe.android.paymentsheet.example.samples.ui.shared.PAYMENT_METHOD_SELECTOR_TEST_TAG
import com.stripe.android.paymentsheet.ui.SAVED_PAYMENT_OPTION_TEST_TAG
import com.stripe.android.test.core.AuthorizeAction
Expand Down Expand Up @@ -312,4 +318,112 @@ internal class TestCard : BasePlaygroundTest() {
values = FieldPopulator.Values(cardNumber = "4000000000003220")
)
}

@Test
fun testCardInCustomerSheet() {
testDriver.savePaymentMethodInCustomerSheet(
TestParameters.create(paymentMethodCode = "card").copyPlaygroundSettings { settings ->
settings[CustomerSettingsDefinition] = CustomerType.NEW
settings[CountrySettingsDefinition] = Country.US
settings[CustomerSheetPaymentMethodModeDefinition] = PaymentMethodMode.CreateAndAttach
},
populateCustomLpmFields = {
populateCardDetails()
},
)
}

@Test
fun testCardWithSetupIntentInCustomerSheet() {
testDriver.savePaymentMethodInCustomerSheet(
TestParameters.create(paymentMethodCode = "card").copyPlaygroundSettings { settings ->
settings[CustomerSettingsDefinition] = CustomerType.NEW
settings[CountrySettingsDefinition] = Country.US
settings[CustomerSheetPaymentMethodModeDefinition] = PaymentMethodMode.SetupIntent
},
populateCustomLpmFields = {
populateCardDetails()
},
)
}

@Test
fun testCardWithNonUsMerchantInCustomerSheet() {
testDriver.savePaymentMethodInCustomerSheet(
TestParameters.create(paymentMethodCode = "card").copyPlaygroundSettings { settings ->
settings[CustomerSettingsDefinition] = CustomerType.NEW
settings[CountrySettingsDefinition] = Country.FR
settings[CustomerSheetPaymentMethodModeDefinition] = PaymentMethodMode.CreateAndAttach
},
populateCustomLpmFields = {
populateCardDetails()
},
)
}

@Test
fun testCardWithSetupIntentAndNonUsMerchantInCustomerSheet() {
testDriver.savePaymentMethodInCustomerSheet(
TestParameters.create(paymentMethodCode = "card").copyPlaygroundSettings { settings ->
settings[CustomerSettingsDefinition] = CustomerType.NEW
settings[CountrySettingsDefinition] = Country.FR
settings[CustomerSheetPaymentMethodModeDefinition] = PaymentMethodMode.SetupIntent
},
populateCustomLpmFields = {
populateCardDetails()
},
)
}

@Test
fun testCardWithBillingDetailsCollectionInCustomerSheet() {
testDriver.savePaymentMethodInCustomerSheet(
TestParameters.create(
paymentMethodCode = "card",
) { settings ->
settings[CustomerSettingsDefinition] = CustomerType.NEW
settings[CountrySettingsDefinition] = Country.US
settings[DefaultBillingAddressSettingsDefinition] = DefaultBillingAddress.Off
settings[CollectNameSettingsDefinition] =
PaymentSheet.BillingDetailsCollectionConfiguration.CollectionMode.Always
settings[CollectEmailSettingsDefinition] =
PaymentSheet.BillingDetailsCollectionConfiguration.CollectionMode.Always
settings[CollectPhoneSettingsDefinition] =
PaymentSheet.BillingDetailsCollectionConfiguration.CollectionMode.Always
settings[CollectAddressSettingsDefinition] =
PaymentSheet.BillingDetailsCollectionConfiguration.AddressCollectionMode.Full
},
populateCustomLpmFields = {
populateCardDetails()
populateEmail()
populateName("Name on card")
populateAddress()
populatePhoneNumber()
},
)
}

@Test
fun testCardWithBillingDetailsCollectionWithDefaultsInCustomerSheet() {
testDriver.savePaymentMethodInCustomerSheet(
TestParameters.create(
paymentMethodCode = "card",
) { settings ->
settings[CustomerSettingsDefinition] = CustomerType.NEW
settings[CountrySettingsDefinition] = Country.US
settings[DefaultBillingAddressSettingsDefinition] = DefaultBillingAddress.On
settings[CollectNameSettingsDefinition] =
PaymentSheet.BillingDetailsCollectionConfiguration.CollectionMode.Always
settings[CollectEmailSettingsDefinition] =
PaymentSheet.BillingDetailsCollectionConfiguration.CollectionMode.Always
settings[CollectPhoneSettingsDefinition] =
PaymentSheet.BillingDetailsCollectionConfiguration.CollectionMode.Always
settings[CollectAddressSettingsDefinition] =
PaymentSheet.BillingDetailsCollectionConfiguration.AddressCollectionMode.Full
},
populateCustomLpmFields = {
populateCardDetails()
},
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import androidx.compose.ui.test.SemanticsNodeInteraction
import androidx.compose.ui.test.assertIsDisplayed
import androidx.compose.ui.test.assertTextEquals
import androidx.compose.ui.test.hasTestTag
import androidx.compose.ui.test.hasText
import androidx.compose.ui.test.junit4.ComposeTestRule
import androidx.compose.ui.test.onAllNodesWithTag
import androidx.compose.ui.test.onAllNodesWithText
Expand Down Expand Up @@ -313,6 +314,54 @@ internal class PlaygroundTestDriver(
teardown()
}

fun savePaymentMethodInCustomerSheet(
testParameters: TestParameters,
values: FieldPopulator.Values = FieldPopulator.Values(),
populateCustomLpmFields: FieldPopulator.() -> Unit = {},
): PlaygroundState? {
setup(
testParameters.copyPlaygroundSettings { settings ->
settings.updateConfigurationData { configurationData ->
configurationData.copy(
integrationType = PlaygroundConfigurationData.IntegrationType.CustomerSheet
)
}
}
)

launchCustomerSheet()

if (isManagePaymentMethodScreen()) {
addPaymentMethodNode().performClick()
}

selectors.paymentSelection.click()

val fieldPopulator = FieldPopulator(
selectors,
testParameters,
populateCustomLpmFields,
{},
values,
)
fieldPopulator.populateFields()

val result = playgroundState

pressCustomerSheetSave()

waitForManageSavedPaymentMethods()

pressCustomerSheetConfirm()

Espresso.onIdle()
composeTestRule.waitForIdle()

teardown()

return result
}

private fun pressMultiStepSelect() {
selectors.multiStepSelect.click()
waitForNotPlaygroundActivity()
Expand All @@ -325,6 +374,20 @@ internal class PlaygroundTestDriver(
}
}

private fun pressCustomerSheetSave() {
Espresso.onIdle()
composeTestRule.waitForIdle()

selectors.customerSheetSaveButton.click()
}

private fun pressCustomerSheetConfirm() {
Espresso.onIdle()
composeTestRule.waitForIdle()

selectors.customerSheetConfirmButton.click()
}

/**
* This will open the payment sheet complete flow from the playground with a new or
* guest user and complete the confirmation including any browser interactions.
Expand Down Expand Up @@ -840,6 +903,17 @@ internal class PlaygroundTestDriver(
}
}

private fun launchCustomerSheet() {
selectors.reload.click()
Espresso.onIdle()
selectors.composeTestRule.waitForIdle()

selectors.multiStepSelect.waitForEnabled()
selectors.multiStepSelect.click()

waitForNotPlaygroundActivity()
}

private fun doAuthorization() {
selectors.apply {
val checkoutMode =
Expand Down Expand Up @@ -1048,6 +1122,12 @@ internal class PlaygroundTestDriver(
}.isSuccess
}

private fun isManagePaymentMethodScreen(): Boolean {
return runCatching {
composeTestRule.onNodeWithText("Manage your payment methods").assertIsDisplayed()
}.isSuccess
}

private fun addPaymentMethodNode(): SemanticsNodeInteraction {
waitForAddPaymentMethodNode()
return composeTestRule.onNodeWithTag(ADD_PAYMENT_METHOD_NODE_TAG)
Expand All @@ -1058,6 +1138,14 @@ internal class PlaygroundTestDriver(
composeTestRule.waitUntilAtLeastOneExists(hasTestTag(ADD_PAYMENT_METHOD_NODE_TAG), 5000L)
}

@OptIn(ExperimentalTestApi::class)
private fun waitForManageSavedPaymentMethods() {
composeTestRule.waitUntilAtLeastOneExists(
hasText("Manage your payment methods"),
DEFAULT_UI_TIMEOUT.inWholeMilliseconds
)
}

private companion object {
const val ADD_PAYMENT_METHOD_NODE_TAG = "${SAVED_PAYMENT_METHOD_CARD_TEST_TAG}_+ Add"
const val FINANCIAL_CONNECTIONS_ACTIVITY =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ import androidx.test.uiautomator.UiObject
import androidx.test.uiautomator.UiSelector
import androidx.test.uiautomator.Until
import com.google.common.truth.Truth.assertThat
import com.stripe.android.customersheet.ui.CUSTOMER_SHEET_CONFIRM_BUTTON_TEST_TAG
import com.stripe.android.customersheet.ui.CUSTOMER_SHEET_SAVE_BUTTON_TEST_TAG
import com.stripe.android.model.PaymentMethod.Type.Blik
import com.stripe.android.model.PaymentMethod.Type.CashAppPay
import com.stripe.android.paymentsheet.example.playground.RELOAD_TEST_TAG
Expand Down Expand Up @@ -74,6 +76,16 @@ internal class Selectors(
}
)

val customerSheetSaveButton = ComposeButton(
composeTestRule,
hasTestTag(CUSTOMER_SHEET_SAVE_BUTTON_TEST_TAG)
)

val customerSheetConfirmButton = ComposeButton(
composeTestRule,
hasTestTag(CUSTOMER_SHEET_CONFIRM_BUTTON_TEST_TAG)
)

val externalPaymentMethodSucceedButton = ComposeButton(
composeTestRule,
hasTestTag(FawryActivity.COMPLETED_BUTTON_TEST_TAG)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.stripe.android.customersheet.ui

import androidx.annotation.RestrictTo
import androidx.compose.animation.animateContentSize
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
Expand Down Expand Up @@ -293,8 +294,11 @@ private fun EditPaymentMethod(
}
}

internal const val CUSTOMER_SHEET_CONFIRM_BUTTON_TEST_TAG = "CustomerSheetConfirmButton"
internal const val CUSTOMER_SHEET_SAVE_BUTTON_TEST_TAG = "CustomerSheetSaveButton"
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
const val CUSTOMER_SHEET_CONFIRM_BUTTON_TEST_TAG = "CustomerSheetConfirmButton"

@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
const val CUSTOMER_SHEET_SAVE_BUTTON_TEST_TAG = "CustomerSheetSaveButton"

private class DefaultCardNumberCompletedEventReporter(
private val viewActionHandler: (CustomerSheetViewAction) -> Unit
Expand Down

0 comments on commit 476b725

Please sign in to comment.