| name | verifying_compose_ui |
| description | Visually verifies Compose UI components by rendering @Composable/@Preview functions to images from the project's JVM runtime; STRONGLY PREFERRED for rapid UI iteration and visual feedback on any composable. Do NOT use for build lifecycle tasks or dependency auditing.
|
| license | Apache-2.0 |
| metadata | {"author":"https://github.com/rnett/gradle-mcp","version":"2.2"} |
⚠️ FUNDAMENTAL ANDROID LIMITATION
IMPORTANT: runComposeUiTest and image capture methods (node.captureToImage()) are NOT supported on Android and CANNOT work.
Why This Cannot Work
The runComposeUiTest function requires a JVM-based test runtime with desktop Compose rendering (via Skiko on JVM/Desktop). Android's ART (Android Runtime) does not support the desktop Compose testing APIs, and image capture via
captureToImage() relies on desktop-specific rendering pipelines that are fundamentally incompatible with Android.
The Solution: Use a JVM Target
For visual verification of Composables, you MUST use a JVM or Desktop target source set. This is not a workaround—it is the only supported method.
Recommended approach:
- Put your Composables in a common source set (
commonMain) that is shared across all targets
- Create or use a JVM target (e.g.,
jvmMain, desktopMain) that depends on commonMain
- Run the REPL on the JVM target (
sourceSet: "jvmMain" or sourceSet: "jvmTest")
This is the standard KMP pattern and allows you to verify your UI code without needing an Android device or emulator.
What WILL NOT Work
- ❌ Running the REPL with
sourceSet: "androidMain"
- ❌ Running the REPL with
sourceSet: "androidTest"
- ❌ Any attempt to use
runComposeUiTest on Android
- ❌ Any attempt to use
captureToImage() on Android
What WILL Work
- ✅ Running the REPL with
sourceSet: "jvmMain" or sourceSet: "jvmTest"
- ✅ Running the REPL with
sourceSet: "desktopMain" or sourceSet: "desktopTest"
- ✅ Using
runComposeUiTest with captureToImage() on JVM/Desktop targets
Authoritative Compose UI Preview & Visual Verification
Visually verifies and renders any @Composable or @Preview directly to high-quality images from the project-aware REPL for instant, authoritative visual feedback.
Constitution
- ALWAYS use
kotlin_repl to render Compose components instead of running the full application for visual checks.
- ALWAYS provide absolute paths for
projectRoot.
- ALWAYS use
node.captureToImage() and responder.render(bitmap) to return the visual output.
- ALWAYS ensure the correct Compose UI testing dependencies are on the classpath, using
additionalDependencies if necessary.
- NEVER assume a UI component renders correctly without visual verification.
- ALWAYS search for existing
@Preview functions in the project source code before creating new ones.
Directives
- ALWAYS provide absolute
projectRoot: Ensure projectRoot is an absolute file system path for all kotlin_repl calls.
- Ensure dependencies: ALWAYS ensure Compose UI testing dependencies (e.g.,
androidx.compose.ui:ui-test-junit4) are on the classpath.
- Note on versions: ALWAYS check your project's version catalog and existing tests for the correct imports for
runComposeUiTest.
- Render as image: ALWAYS use
node.captureToImage() and responder.render(bitmap) to return the visual output.
- Kotlin Multiplatform (KMP) Note: The
kotlin_repl currently only supports JVM-based source sets. ALWAYS select a JVM or Desktop target source set for visual checks.
- Use
envSource: SHELL if environment variables are missing: Set env: { envSource: "SHELL" } (REPL start) or invocationArguments: { envSource: "SHELL" } (Gradle tasks) if expected env vars (e.g., JAVA_HOME) are not found.
When to Use
- Rapid UI Prototyping & Iteration: When you need to see the visual result of a Composable change instantly without the latency of a full application launch.
- Authoritative @Preview Verification: When you want to verify the visual correctness of existing
@Preview functions.
- Complex UI State & Interaction Testing: When you need to capture visual state before and after interactions (like clicks or state changes).
- Multi-Configuration Visual Auditing: When checking how a component renders across different data states or configurations (e.g., different view models or mock data).
Workflows
1. Identifying the Component
- Find the fully qualified name of the
@Composable or @Preview function.
- Search for existing previews in the source code via
grep_search(pattern="@Preview").
2. Orchestrating the Session
- Start the REPL with the
test source set (preferred) or main with additionalDependencies.
- Use
kotlin_repl(command="start").
- Use
kotlin_repl(command="run") to execute the rendering script.
3. Rendering & Verifying
- Execute a script that uses
runComposeUiTest to render and capture the component.
- Inspect the returned image for visual correctness.
Examples
Viewing a simple Composable
import androidx.compose.ui.test.*
import com.example.ui.MyButton
runComposeUiTest {
setContent {
MyButton(text = "Click Me")
}
val node = onRoot()
responder.render(node.captureToImage())
}
Viewing an existing @Preview
import androidx.compose.ui.test.*
import com.example.ui.MyButtonPreview
runComposeUiTest {
setContent {
MyButtonPreview()
}
val node = onRoot()
responder.render(node.captureToImage())
}
Capturing State Transitions
import androidx.compose.ui.test.*
import com.example.ui.MyCounter
import com.example.viewmodel.MyViewModel
runComposeUiTest {
val viewModel = MyViewModel()
setContent {
MyCounter(viewModel)
}
responder.render("State before: ${viewModel.count}")
responder.render(onRoot().captureToImage())
onNodeWithText("Increment").performClick()
responder.render("State after: ${viewModel.count}")
responder.render(onRoot().captureToImage())
}
Troubleshooting
- No Image Returned: Ensure you are calling
responder.render(bitmap).
- ClassNotFoundException: Check if you have the correct imports and that the required testing dependencies are on the classpath.
- Empty Image: If the Composable is empty or has zero size, the image will be empty. Verify your Composable's modifiers.
Resources