Skip to main content
Version: 6.0.0

Capturing dialogs, menus and popups

Dialogs, menus, popups and dropdowns are drawn in their own window, on top of your activity. Testify's standard capture methods only capture the activity's own view hierarchy, so these elements are missing from the screenshot.

To include them, use the Fullscreen Capture Method. It captures the whole device screen, including every window. This includes:

  • AlertDialog, Dialog and DialogFragment
  • Options and overflow menus, PopupMenu and PopupWindow
  • Bottom sheet dialogs
  • In Compose, AlertDialog, Dialog, DropdownMenu, ModalBottomSheet and Popup

Set up

The Fullscreen Capture Method is a separate artifact. Add it to your androidTest dependencies as described in Set up testify-fullscreen.

A full-screen capture includes the status bar and the navigation bar, which change between runs. Exclude them from the comparison with excludeSystemUi(), and allow a small color tolerance with exactness.

Views

Open the dialog, menu or popup before assertSame() runs. Show a dialog from setViewModifications, or open a menu with an Espresso action.

class DialogScreenshotTest {

@get:Rule
val rule = ScreenshotRule(
activityClass = MainActivity::class.java,
configuration = TestifyConfiguration(exactness = 0.95f)
)

@ScreenshotInstrumentation
@Test
fun withDialog() {
rule
.captureFullscreen()
.configure {
excludeSystemUi()
}
.setViewModifications {
MaterialAlertDialogBuilder(it.context)
.setMessage("Hello, world!")
.show()
}
.assertSame()
}
}

For a PopupWindow or PopupMenu, open it the same way your app does, for example by clicking the view that shows it in setEspressoActions.

Jetpack Compose

With the Compose extension, you can open a menu with a Compose action, or put a dialog directly in the composition.

@ScreenshotInstrumentation
@Test
fun dropdownMenu() {
rule
.setCompose {
var expanded by remember { mutableStateOf(false) }
Box(modifier = Modifier.fillMaxSize().safeDrawingPadding()) {
Box {
Button(onClick = { expanded = true }, modifier = Modifier.testTag("menuButton")) {
Text("Options")
}
DropdownMenu(expanded = expanded, onDismissRequest = { expanded = false }) {
DropdownMenuItem(text = { Text("Edit") }, onClick = {})
DropdownMenuItem(text = { Text("Delete") }, onClick = {})
}
}
}
}
.setComposeActions { composeTestRule ->
composeTestRule.onNodeWithTag("menuButton").performClick()
}
.captureFullscreen()
.configure {
excludeSystemUi()
}
.assertSame()
}

The Compose rules already use an exactness of 0.9 by default. These examples use Material 3.

More examples are in the sample project's FullscreenCaptureExampleTests.kt and ComposableScreenshotTest.kt.