KakaoCup / Kakao

Nice and simple DSL for Espresso in Kotlin
https://kakaocup.github.io/Kakao/
Apache License 2.0
330 stars 28 forks source link

KImageView -> hasDrawable doesn't work with SVG images #48

Open filnik opened 3 years ago

filnik commented 3 years ago

Steps to reproduce:

  1. Import a SVG image in Android Studio
  2. Try to use hasDrawable with the SVG set.

Observed Results:

The images are considered different although they are the same

Expected Results:

The images should be the same

Relevant Code:

withId<KImageView>(R.id.criticalErrorImage) {
    hasDrawable(R.drawable.error_graphic)
}

I've tried also to create a CustomMatcher trying to compare the constantState but it fails anyway unfortunately.

Vacxe commented 3 years ago

@filnik could you please create a reproducible PR with this issue? That's a long story but hasDrawable. using Bitmap.sameAs() method under the hood with some adjusting for API versioning. That's a most common issue in Kakao library.

Vacxe commented 3 years ago

See: #32

filnik commented 3 years ago

I've created a POC here: https://github.com/filnik/proof_of_concept

In particular, here is the test: https://github.com/filnik/proof_of_concept/blob/master/app/src/androidTest/java/com/neato/test/POCInstrumentationTest.kt

While here I dynamically set the image: https://github.com/filnik/proof_of_concept/blob/master/app/src/main/java/com/neato/test/FirstFragment.kt

Creating the POC I realized that if I set the image like this:

binding.root.findViewById<ImageView>(R.id.image)?.setImageResource(R.drawable.error_image)

It works. In any other ways, it doesn't. Unfortunately in my project we are not using viewBinding but dataBinding (I created this project using the default one from Android Studio) so I cannot this solution to fix the problem :(

No idea why there is a difference in the two instances.

Thank you however for the help!

filnik commented 3 years ago

I've found the reason of the issue. Using databinding in the POC is fine, but in my project the image has a "scaleType" thus it seems different to the ui test than the one provided. Is there a way to "restore" the image after it has been scaled?

The only way I found was putting the second image in the same ImageView and extract from there and to the comparison. Actually not so "clean" but it worked.

filnik commented 3 years ago

I've used this to make it work: https://pastebin.com/exPRirCU although probably it could be done better.

bitvale commented 2 years ago

I found, that hasDrawable works fine with vector drawables, but with at least one exception. It doesn't work in recycler view view holder if image view size is not specified.

Works fine on view holder with this layout:

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <androidx.appcompat.widget.AppCompatImageView
        android:id="@+id/img_background"
        android:layout_width="@dimen/space_100"
        android:layout_height="@dimen/space_100"
        android:scaleType="centerCrop"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        tools:src="@drawable/img_pattern_1" />

</androidx.constraintlayout.widget.ConstraintLayout>

// in code
binding.imgBackground.setImageResource(R.drawable.img_pattern_1)

And doesn't work with this:

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <androidx.appcompat.widget.AppCompatImageView
        android:id="@+id/img_background"
        android:layout_width="0dp"                                            // no size
        android:layout_height="0dp"                                           // no size
        android:scaleType="centerCrop"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        tools:src="@drawable/img_pattern_1" />

</androidx.constraintlayout.widget.ConstraintLayout>

PS: This is a sample of a portion of a complete layout where the root container has other content and the height of the root container depends on it. The image is stretched to the full height of the parent.

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android">

    <androidx.appcompat.widget.AppCompatImageView
        android:id="@+id/img_background"
        android:layout_width="@dimen/space_100"
        android:layout_height="@dimen/space_100"
        android:scaleType="centerCrop"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        tools:src="@drawable/img_pattern_1" />

    <androidx.appcompat.widget.AppCompatTextView />

    <androidx.appcompat.widget.AppCompatTextView />

    <androidx.appcompat.widget.AppCompatTextView />

    <androidx.appcompat.widget.AppCompatTextView/>

    <androidx.appcompat.widget.AppCompatTextView />

</androidx.constraintlayout.widget.ConstraintLayout>