You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I've tried to use the RoborazziRule that comes with this project, but failed, because naturally JUnit rules must be instantiated before a test runs and if the test sets up an Activity at a later stage (e.g. because of test stubbing) or if the Activity is no longer there because the respective ActivityScenario is already closed, screenshot recording fails as Espresso cannot (yet/no longer) work on the ViewInteraction. Maybe this could be changed by providing the CaptureRoot as Lambda instead of the "actual thing" as constructor parameter, like so:
@get:Rule var screenshotRule =RoborazziRule { onView(isRoot()) }
Anyways, this is what I came up with (prettry much restrained to Espresso, no Compose):
classEspressoScreenshotRule : TestWatcher() {
privatelateinitvar description:Descriptionprivateval callbacks = mutableListOf<() ->Unit>()
privateval viewInteractions = mutableListOf<ViewInteraction>()
/** * Capture a specific view's state as of now (e.g. `onView(withId(...))`) or * the complete screen (e.g. `onView(isRoot())`)*/funcapture(viewInteraction:ViewInteraction, tag:String) {
viewInteraction.captureRoboImage(
filePath = description.createFileName(tag),
roborazziOptions =RoborazziOptions(
taskType =RoborazziTaskType.Record,
contextData =mapOf(
"Classes" to description.className.shortenClasspath(),
"Tests" to "${description.methodName} (${description.className.shortenClasspath()})"
)
)
)
}
/** * Capture the state of a specific view at the point when a test fails*/funcaptureOnFailure(viewInteraction:ViewInteraction) {
viewInteractions.add(viewInteraction)
}
/** * Run code after all screenshots have been taken, at the end of a test, useful for cleaning up resources*/funrunAfterTest(callback: () ->Unit) {
callbacks.add(callback)
}
overridefunstarting(description:Description) {
this.description = description
}
overridefunfailed(e:Throwable, description:Description) {
if (!isAnyActivityResumed() && viewInteractions.isNotEmpty()) {
println(
"WARNING: Can't screenshot ViewInteraction(s) because no Activity is resumed; "+"consider tearing down the activity via `runAfterTest {}`"
)
return
}
viewInteractions.forEachIndexed { index, interaction ->
capture(interaction, "failure$index")
}
}
privatefunisAnyActivityResumed(): Boolean=try {
viewInteractions.firstOrNull()?.check { _, _ -> }
true
} catch (e:NoActivityResumedException) {
false
}
overridefunfinished(description:Description) {
callbacks.forEach { it() }
}
}
privatefun Description.createFileName(tag:String): String="build/reports/roborazzi/screenshots/${classMethod()}.$tag.png"privatefun Description.classMethod(): String="${this.className.shortenClasspath()}.${this.methodName.replace("", "_")}"privatefun String.shortenClasspath(): String= replace(Regex("\\B\\w+(\\.[a-z])"), "$1")
Yes, but the thing is, again for stubbing, I need to have the Activity / Fragment state under control. The usual workflow for me is:
in @Before, setup Activity / Fragment scenario and launch in CREATED state
in the test method, stub data (e.g. that are needed for initial loading of the screen)
in the test method, move the lifecycle to RESUMED state
verify things
So, unless the Activity / Fragment is in RESUMED state, I can nowhere use a ViewInteraction, because Espresso will throw the NoActivityResumedException.
I've tried to use the
RoborazziRule
that comes with this project, but failed, because naturally JUnit rules must be instantiated before a test runs and if the test sets up an Activity at a later stage (e.g. because of test stubbing) or if theActivity
is no longer there because the respectiveActivityScenario
is already closed, screenshot recording fails as Espresso cannot (yet/no longer) work on theViewInteraction
. Maybe this could be changed by providing theCaptureRoot
as Lambda instead of the "actual thing" as constructor parameter, like so:Anyways, this is what I came up with (prettry much restrained to Espresso, no Compose):
And the usage is the following:
The text was updated successfully, but these errors were encountered: