Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for heightDp, widthDp, showBackground, backgroundColor #576

Original file line number Diff line number Diff line change
@@ -1,26 +1,16 @@
package com.github.takahirom.roborazzi

import android.app.Activity
import android.app.Application
import android.content.ComponentName
import android.view.ViewGroup
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.ComposeView
import androidx.compose.ui.platform.ViewRootForTest
import androidx.compose.ui.unit.dp
import androidx.test.core.app.ActivityScenario
import androidx.test.core.app.ApplicationProvider
import org.robolectric.Shadows
import org.robolectric.shadows.ShadowDisplay
import java.io.File
import kotlin.math.roundToInt

fun captureRoboImage(
filePath: String = DefaultFileNameGenerator.generateFilePath(),
Expand All @@ -40,7 +30,7 @@ fun captureRoboImage(
content: @Composable () -> Unit,
) {
if (!roborazziOptions.taskType.isEnabled()) return
registerRoborazziActivityToRobolectricIfNeeded(RoborazziTransparentActivity::class.java)
registerRoborazziTransparentActivityToRobolectricIfNeeded()
val activityScenario = ActivityScenario.launch(RoborazziTransparentActivity::class.java)
activityScenario.use {
activityScenario.onActivity { activity ->
Expand All @@ -61,15 +51,13 @@ fun captureRoboImage(
/**
* Workaround for https://github.com/takahirom/roborazzi/issues/100
*/
internal fun registerRoborazziActivityToRobolectricIfNeeded(
activityClass: Class<out Activity>
) {
private fun registerRoborazziTransparentActivityToRobolectricIfNeeded() {
try {
val appContext: Application = ApplicationProvider.getApplicationContext()
Shadows.shadowOf(appContext.packageManager).addActivityIfNotPresent(
ComponentName(
appContext.packageName,
activityClass::class.java.name,
RoborazziTransparentActivity::class.java.name,
)
)
} catch (e: ClassNotFoundException) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
package com.github.takahirom.roborazzi

import android.app.Activity
import android.app.Application
import android.app.Instrumentation
import android.content.ComponentName
import android.graphics.Color
import android.view.ViewGroup
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.requiredSize
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.runtime.Composable
Expand All @@ -15,9 +21,9 @@ import androidx.compose.ui.platform.ComposeView
import androidx.compose.ui.platform.ViewRootForTest
import androidx.compose.ui.unit.dp
import androidx.test.core.app.ActivityScenario
import androidx.test.core.app.ApplicationProvider
import org.robolectric.Shadows
import org.robolectric.shadows.ShadowDisplay
import java.io.File
import kotlin.math.roundToInt

fun captureSizedRoboImage(
Expand All @@ -30,12 +36,13 @@ fun captureSizedRoboImage(
content: @Composable () -> Unit,
) {
if (!roborazziOptions.taskType.isEnabled()) return
registerRoborazziActivityToRobolectricIfNeeded(ComponentActivity::class.java)
registerRoborazziComposePreviewsActivityToRobolectricIfNeeded()

val activityScenario = ActivityScenario.launch(ComponentActivity::class.java)

activityScenario.onActivity {
it.setShadowDisplay(
activityScenario.onActivity { activity ->

activity.setDisplaySize(
widthDp = widthDp,
heightDp = heightDp
)
Expand Down Expand Up @@ -79,7 +86,7 @@ fun Activity.setBackgroundColor(
}
}

fun Activity.setShadowDisplay(
fun Activity.setDisplaySize(
widthDp: Int,
heightDp: Int
) {
Expand Down Expand Up @@ -117,7 +124,24 @@ private fun (@Composable () -> Unit).withSize(
heightDp > 0 -> Modifier.height(heightDp.dp)
else -> Modifier
}
Box(modifier = modifier) { this@withSize() }
Box(modifier = modifier) {
this@withSize()
}
}
return resizedPreview
}

private fun registerRoborazziComposePreviewsActivityToRobolectricIfNeeded() {
try {
val appContext: Application = ApplicationProvider.getApplicationContext()
Shadows.shadowOf(appContext.packageManager).addActivityIfNotPresent(
ComponentName(
appContext.packageName,
ComponentActivity::class.java.name,
)
)
} catch (e: ClassNotFoundException) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm curious about this.

You are directly calling both robolectric and ComponentActivity. Wouldn't it fail with an error (NoClassDefFoundError , or similar) rather than a ClassNotFoundException? I normally assume ClassNotFoundException is for reflection usage with a checked exception.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree and haven’t realised that since I copy pasted it from the analogue method in RoborazziCompose.kt file.

worth checking 👍

// Configured to run even without Robolectric
e.printStackTrace()
}
}
1 change: 1 addition & 0 deletions roborazzi/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@
<application>
<activity android:name=".RoborazziTransparentActivity"
android:theme="@style/RoborazziTransparentTheme"/>
<activity android:name=".RoborazziComposePreviewsActivity"/>
</application>
</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.github.takahirom.roborazzi

import android.os.Bundle
import android.os.PersistableBundle
import androidx.activity.ComponentActivity

class RoborazziComposePreviewsActivity: ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?, persistentState: PersistableBundle?) {
super.onCreate(savedInstanceState, persistentState)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package com.github.takahirom.preview.tests

import android.content.res.Configuration
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.material3.Card
Expand Down Expand Up @@ -59,19 +61,18 @@ fun PreviewDarkMode() {

@Preview(
name = "Preview Name",
// These properties are not supported by Roborazzi yet.
group = "Preview Group",
apiLevel = 30,
widthDp = 320,
heightDp = 640,
locale = "ja-rJP",
fontScale = 1.5f,
widthDp = 320,
heightDp = 640,
// These properties are not supported by Roborazzi yet.
apiLevel = 30
)
@Composable
fun PreviewWithProperties1() {
Card(
Modifier
.width(100.dp)
Modifier.width(100.dp)
) {
Text(
modifier = Modifier.padding(8.dp),
Expand Down Expand Up @@ -99,4 +100,76 @@ fun PreviewWithProperties2() {
text = "Hello, World!"
)
}
}

@Preview(
name = "Preview width & height large",
group = "Preview Group",
widthDp = 2000,
heightDp = 1000,
)
@Composable
fun PreviewWithWidthAndHeight() {
Card(
Modifier.fillMaxSize()
) {
Text(
modifier = Modifier.padding(8.dp),
text = "Hello, World!"
)
}
}

@Preview(
name = "Preview width & height",
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Preview width & height small"?

group = "Preview Group",
widthDp = 30,
heightDp = 30,
)
@Composable
fun PreviewWithWidthAndHeightSmall() {
Card(
Modifier.fillMaxSize()
) {
Text(
modifier = Modifier.padding(8.dp),
text = "Hello, World!"
)
}
}

@Preview(
name = "Preview width",
group = "Preview Group",
widthDp = 500,
// These properties are not supported by Roborazzi yet.
apiLevel = 30
)
@Composable
fun PreviewWithWidth() {
Card(
Modifier.fillMaxSize()
) {
Text(
modifier = Modifier.padding(8.dp),
text = "Hello, World!"
)
}
}

@Preview(
name = "Preview height",
group = "Preview Group",
heightDp = 500,
)
@Composable
fun PreviewWithHeight() {
Card(
Modifier.fillMaxSize()
) {
Text(
modifier = Modifier.padding(8.dp),
text = "Hello, World!"
)
}
}
Loading