takahirom / roborazzi

Make JVM Android integration test visible 🤖📸
https://takahirom.github.io/roborazzi/
Apache License 2.0
709 stars 34 forks source link

Add examples using robolectric @Config #47

Closed yschimke closed 1 year ago

yschimke commented 1 year ago

Useful to show configuring the screen for different devices. Round vs Square watch.

These qualifiers should also affect which resources are loaded

@Config(
    sdk = [30],
    qualifiers = "w221dp-h221dp-small-notlong-notround-watch-xhdpi-keyshidden-nonav"
)
@Config(
    sdk = [30],
    qualifiers = "w221dp-h221dp-small-notlong-round-watch-xhdpi-keyshidden-nonav"
)
yschimke commented 1 year ago

We could provide constants for known devices, similar to Paparazzi, and Android Studio.

@Preview(device = Devices.NEXUS_5X)

And config in https://cs.android.com/android-studio/platform/tools/adt/idea/+/mirror-goog-studio-main:artwork/resources/device-art-resources/wearos_small_round/layout

https://github.com/cashapp/paparazzi/blob/c10c435bd30025f3b5da64f846c6ecbd66d54515/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/DeviceConfig.kt#L475

https://android.googlesource.com/platform/tools/base/+/mirror-goog-studio-master-dev/sdklib/src/main/java/com/android/sdklib/devices/wear.xml

sergio-sastre commented 1 year ago

We could provide constants for known devices, similar to Paparazzi, and Android Studio.

@Preview(device = Devices.NEXUS_5X)

And config in https://cs.android.com/android-studio/platform/tools/adt/idea/+/mirror-goog-studio-main:artwork/resources/device-art-resources/wearos_small_round/layout

https://github.com/cashapp/paparazzi/blob/c10c435bd30025f3b5da64f846c6ecbd66d54515/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/DeviceConfig.kt#L475

https://android.googlesource.com/platform/tools/base/+/mirror-goog-studio-master-dev/sdklib/src/main/java/com/android/sdklib/devices/wear.xml

That is actually sth I’m releasing next week: https://twitter.com/gio_sastre/status/1649073964617019400?s=46&t=ljy1XQW5SI3KUXpinEKEow

in this library: https://github.com/sergio-sastre/AndroidUiTestingUtils

However, that is sth that would depend on ActivityScenario. So I believe, it might make sense to have this directly in Roborazzi?

It’s indeed very straightforward to implement.

takahirom commented 1 year ago

Is this what you mean? I think it would be very useful to have.

object RobolectricDeviceQualifiers {
  const val NEXUS_5X = "w320dp-h540dp-xxxhdpi..."
...
}
yschimke commented 1 year ago

Yep.

I don't know whether you need some data model for devices with different properties, but this is what I was asking for.

A data model might be useful for non robolectric running, or to copy and adjust. But robolectric has those APIs.

takahirom commented 1 year ago

If we use the annotations provided by Robolectric, they don't allow us to implement methods similar to a builder. Consequently, we have no choice but to use constants. We can also use RuntimeEnvironment.setQualifiers("+land"). However, if the test is initiated by a Rule, the activity might already be started. https://robolectric.org/device-configuration/ Nevertheless, we sometimes wish to conduct tests with variations, such as for smartphones and tablets. This is indeed a challenging issue, but for now, I think it's acceptable to have some constants in place.

takahirom commented 1 year ago

We can implement something similar to the example below. However, I believe it may not be the best solution.

fun test() {
...
}

@Config(
    sdk = [30],
    qualifiers = "w221dp-h221dp-small-notlong-notround-watch-xhdpi-keyshidden-nonav"
)
@Test
fun testRound() = test()

@Config(
    sdk = [30],
    qualifiers = "w221dp-h221dp-small-notlong-round-watch-xhdpi-keyshidden-nonav"
)
@Test
fun testNotRound() = test()
takahirom commented 1 year ago

I think this is useful 👀 https://android.googlesource.com/platform/tools/base/+/mirror-goog-studio-master-dev/sdklib/src/main/java/com/android/sdklib/devices/nexus.xml#2837

sergio-sastre commented 1 year ago

It seems that the x and y dimensions (width and height) are in pixels, and you need them in dp, that’s what Robolectric supports).

Moreover, only a few device characteristics are configurable via qualifiers.

I got most of them translated via ChatGPT for the library I’m implementing this 😅

sergio-sastre commented 1 year ago

If we use the annotations provided by Robolectric, they don't allow us to implement methods similar to a builder. Consequently, we have no choice but to use constants. We can also use RuntimeEnvironment.setQualifiers("+land"). However, if the test is initiated by a Rule, the activity might already be started. https://robolectric.org/device-configuration/ Nevertheless, we sometimes wish to conduct tests with variations, such as for smartphones and tablets. This is indeed a challenging issue, but for now, I think it's acceptable to have some constants in place.

That’s true, that’s why to do it dynamically, it better to link it somehow to a custom ActivityScenarioTestRule where that code runs before launching it.

but the solution with the constants is already a good improvement over the standard Robolectric solution imho 😊

takahirom commented 1 year ago

I have implemented the feature. Please let me know if there's anything wrong with what I've done. https://github.com/takahirom/roborazzi/pull/49

yschimke commented 1 year ago

I suspect these are the configs we want for Wear, and probably other devices. Sorry for the bad link before. I can put up a PR.

https://cs.android.com/android-studio/platform/tools/base/+/mirror-goog-studio-main:sdklib/src/main/resources/com/android/sdklib/devices/

Wear OS Large Round Wear OS Small Round Wear OS Rectangular Wear OS Square

Instead of the current

  const val WearOSSquare = "w187dp-h187dp-small-long-round-watch-hdpi-keyshidden-nonav"
  const val WearOSRound = "w213dp-h213dp-small-long-round-watch-hdpi-keyshidden-nonav"
  const val WearOSRoundChin = "w240dp-h218dp-small-notlong-notround-watch-tvdpi-keyshidden-nonav"