11package io.sentry.uitest.android
22
3+ import android.graphics.Color
4+ import android.util.TypedValue
35import android.view.View
46import android.widget.EditText
7+ import android.widget.LinearLayout
58import androidx.test.core.app.launchActivity
69import androidx.test.espresso.Espresso.onView
710import androidx.test.espresso.action.ViewActions.click
@@ -23,9 +26,11 @@ import io.sentry.SentryFeedbackOptions.SentryFeedbackCallback
2326import io.sentry.SentryOptions
2427import io.sentry.android.core.AndroidLogger
2528import io.sentry.android.core.R
29+ import io.sentry.android.core.SentryUserFeedbackButton
2630import io.sentry.android.core.SentryUserFeedbackDialog
2731import io.sentry.assertEnvelopeFeedback
2832import io.sentry.protocol.User
33+ import io.sentry.test.getProperty
2934import org.hamcrest.Description
3035import org.hamcrest.Matcher
3136import org.hamcrest.Matchers.allOf
@@ -34,6 +39,7 @@ import kotlin.test.Test
3439import kotlin.test.assertEquals
3540import kotlin.test.assertFalse
3641import kotlin.test.assertNotNull
42+ import kotlin.test.assertNull
3743import kotlin.test.assertTrue
3844
3945@RunWith(AndroidJUnit4 ::class )
@@ -517,6 +523,95 @@ class UserFeedbackUiTest : BaseUiTest() {
517523 }
518524 }
519525
526+ @Test
527+ fun userFeedbackWidgetDefaults () {
528+ initSentry()
529+ var widgetId = 0
530+ showWidgetAndCheck { widget ->
531+ widgetId = widget.id
532+ val densityScale = context.resources.displayMetrics.density
533+ assertEquals((densityScale * 4 ).toInt(), widget.compoundDrawablePadding)
534+
535+ assertNotNull(widget.compoundDrawables[0 ]) // Drawable left
536+ assertNull(widget.compoundDrawables[1 ]) // Drawable top
537+ assertNull(widget.compoundDrawables[2 ]) // Drawable right
538+ assertNull(widget.compoundDrawables[3 ]) // Drawable bottom
539+
540+ // Couldn't find a reliable way to check the drawable, so i'll skip it
541+
542+ assertFalse(widget.isAllCaps)
543+
544+ assertEquals(R .drawable.sentry_oval_button_ripple_background, widget.getProperty<Int >(" mBackgroundResource" ))
545+
546+ assertEquals((densityScale * 12 ).toInt(), widget.paddingStart)
547+ assertEquals((densityScale * 12 ).toInt(), widget.paddingEnd)
548+ assertEquals((densityScale * 12 ).toInt(), widget.paddingTop)
549+ assertEquals((densityScale * 12 ).toInt(), widget.paddingBottom)
550+
551+ val typedValue = TypedValue ()
552+ widget.context.theme.resolveAttribute(android.R .attr.colorForeground, typedValue, true )
553+ assertEquals(typedValue.data, widget.currentTextColor)
554+
555+ assertEquals(" Report a Bug" , widget.text)
556+ }
557+
558+ onView(withId(widgetId)).perform(click())
559+ // Check that the user feedback dialog is shown
560+ checkViewVisibility(R .id.sentry_dialog_user_feedback_layout)
561+ }
562+
563+ @Test
564+ fun userFeedbackWidgetDefaultsOverridden () {
565+ initSentry()
566+ showWidgetAndCheck({ widget ->
567+ widget.compoundDrawablePadding = 1
568+ widget.setCompoundDrawables(null , null , null , null )
569+ widget.isAllCaps = true
570+ widget.setBackgroundResource(R .drawable.sentry_edit_text_border)
571+ widget.setTextColor(Color .RED )
572+ widget.text = " My custom text"
573+ widget.setPadding(0 , 0 , 0 , 0 )
574+ }) { widget ->
575+ val densityScale = context.resources.displayMetrics.density
576+ assertEquals(1 , widget.compoundDrawablePadding)
577+
578+ assertNull(widget.compoundDrawables[0 ]) // Drawable left
579+ assertNull(widget.compoundDrawables[1 ]) // Drawable top
580+ assertNull(widget.compoundDrawables[2 ]) // Drawable right
581+ assertNull(widget.compoundDrawables[3 ]) // Drawable bottom
582+
583+ assertTrue(widget.isAllCaps)
584+
585+ assertEquals(R .drawable.sentry_edit_text_border, widget.getProperty<Int >(" mBackgroundResource" ))
586+
587+ assertEquals((densityScale * 0 ).toInt(), widget.paddingStart)
588+ assertEquals((densityScale * 0 ).toInt(), widget.paddingEnd)
589+ assertEquals((densityScale * 0 ).toInt(), widget.paddingTop)
590+ assertEquals((densityScale * 0 ).toInt(), widget.paddingBottom)
591+
592+ assertEquals(Color .RED , widget.currentTextColor)
593+
594+ assertEquals(" My custom text" , widget.text)
595+ }
596+ }
597+
598+ @Test
599+ fun userFeedbackWidgetShowsDialogOnClickOverridden () {
600+ initSentry()
601+ var widgetId = 0
602+ var customListenerCalled = false
603+ showWidgetAndCheck { widget ->
604+ widgetId = widget.id
605+ widget.setOnClickListener { customListenerCalled = true }
606+ }
607+
608+ onView(withId(widgetId)).perform(click())
609+ // Check that the user feedback dialog is shown
610+ checkViewVisibility(R .id.sentry_dialog_user_feedback_layout)
611+ // And the custom listener is called, too
612+ assertTrue(customListenerCalled)
613+ }
614+
520615 private fun checkViewVisibility (viewId : Int , isGone : Boolean = false) {
521616 onView(withId(viewId))
522617 .check(matches(withEffectiveVisibility(if (isGone) Visibility .GONE else Visibility .VISIBLE )))
@@ -558,6 +653,29 @@ class UserFeedbackUiTest : BaseUiTest() {
558653 checker(dialog)
559654 }
560655
656+ private fun showWidgetAndCheck (widgetConfig : ((widget: SentryUserFeedbackButton ) -> Unit )? = null, checker : (widget: SentryUserFeedbackButton ) -> Unit = {}) {
657+ val buttonId = Int .MAX_VALUE - 1
658+ val feedbackScenario = launchActivity<EmptyActivity >()
659+ feedbackScenario.onActivity {
660+ val view = LinearLayout (it).apply {
661+ orientation = LinearLayout .VERTICAL
662+ addView(
663+ SentryUserFeedbackButton (it).apply {
664+ id = buttonId
665+ widgetConfig?.invoke(this )
666+ }
667+ )
668+ }
669+ it.setContentView(view)
670+ }
671+ checkViewVisibility(buttonId)
672+ onView(withId(buttonId))
673+ .check(matches(isDisplayed()))
674+ .check { view, _ ->
675+ checker(view as SentryUserFeedbackButton )
676+ }
677+ }
678+
561679 fun withError (expectedError : String ): Matcher <View > {
562680 return object : BoundedMatcher <View , EditText >(EditText ::class .java) {
563681 override fun describeTo (description : Description ) {
0 commit comments