-
Notifications
You must be signed in to change notification settings - Fork 12
Listeners
The framework has 2 types of listeners: UltronLifecycleListener & UltronRunListener
This one allows you to listen all stages of Operation execution.
abstract class UltronLifecycleListener {
/**
* executed before any action or assertion
*/
override fun before(operation: Operation) = Unit
/**
* called when action or assertion failed
*/
override fun afterFailure(operationResult: OperationResult<Operation>) = Unit
/**
* called when action or assertion has been executed successfully
*/
override fun afterSuccess(operationResult: OperationResult<Operation>) = Unit
/**
* called in any case of action or assertion result
*/
override fun after(operationResult: OperationResult<Operation>) = Unit
}
Operation
object contains all info about operation (name, description, type, timeout)
OperationResult
object contains all info about operation result (success, all exceptions that occured and exception that was thrown, description etc) and also has a reference to Operation
.
All listener methods will be executed before an exception will be thrown. It gives you a guarantee that all exceptions in your tests will be processed as you want.
For instance, here is a listener that logs everything to Ultron log.
class LogLifecycleListener : UltronLifecycleListener() {
override fun before(operation: Operation) {
UltronLog.info("Start execution of ${operation.name}")
}
override fun afterSuccess(operationResult: OperationResult<Operation>) {
UltronLog.info("Successfully executed ${operationResult.operation.name}")
}
override fun afterFailure(operationResult: OperationResult<Operation>) {
UltronLog.error("Failed ${operationResult.operation.name} with description: \n" +
"${operationResult.description} ")
}
}
You can create you own custom listener in the same way.
class CustomLifecycleListener : UltronLifecycleListener() {...}
Add new listener for Espresso, EspressoWeb and UI Automator Ultron operations using UltronConfig.addGlobalListener()
.
For Compose use another one - UltronComposeConfig.addListener()
abstract class BaseTest {
companion object {
@BeforeClass @JvmStatic
fun configureUltron() {
UltronConfig.addGlobalListener(CustomLifecycleListener())
UltronComposeConfig.addListener(CustomLifecycleListener())
}
}
}
Basically we already know how to add new listener. But there are other options to configure Ultron listeners.
First of all Ultron by default already has LogLifecycleListener that writes some usable info to logcat.
Ultron has 4 different lifecycles that watch for different operations.
- UltronEspressoOperationLifecycle
- UltronWebLifecycle (WebView operations)
- UltronUiAutomatorLifecycle
- UltronComposeOperationLifecycle
It is possible to add listener for any of these lifecycles.
UltronUiAutomatorLifecycle.addListener(CustomLifecycleListener())
In this case CustomLifecycleListener
will be applied only for UI Automator operations.
It possible to add or delete global listener. The changes will be applied for Espresso, EspressoWeb and UI Automator lifecycles.
abstract class BaseTest {
companion object {
@BeforeClass @JvmStatic
fun configureUltron() {
UltronConfig.addGlobalListener(CustomLifecycleListener())
UltronConfig.removeGlobalListener(CustomLifecycleListener::class.java)
}
}
}
Ultron allows it to exclude operation from all listeners. This option is based on operation type.
For example, you've created a new operation
enum class CustomUltronOperations : UltronOperationType {
ASSERT_HAS_ANY_CHILD
}
fun UltronUiObject2.assertHasAnyChild() = apply {
executeAssertion(
assertionBlock = { uiObject2ProviderBlock()!!.childCount > 0 },
name = "Assert $selectorDesc has any child",
type = CustomUltronOperations.ASSERT_HAS_ANY_CHILD,
description = "UiObject2 assertion '${CustomUltronOperations.ASSERT_HAS_ANY_CHILD}' of $selectorDesc during $timeoutMs ms",
timeoutMs = timeoutMs,
resultHandler = resultHandler
)
}
And you would like to exclude it from listeners for any reason no matter why.
Add single line to Ultron configuration function.
abstract class BaseTest {
companion object {
@BeforeClass @JvmStatic
fun configureUltron() {
...
UltronConfig.operationsExcludedFromListeners.add(CustomUltronOperations.ASSERT_HAS_ANY_CHILD)
}
}
}
Allows you to add listener for Test Lifecycle. See RunListener.
It is available in case you use ultron-allure
and set testInstrumentationRunner
.
testInstrumentationRunner = "com.atiurin.ultron.allure.UltronAllureTestRunner"
It could be used, for instance, to attach your custom application log to Allure Report.
class AppLogAttachRunListener() : UltronRunListener() {
override fun testFailure(failure: Failure) {
val logFile: File = AppLogProvider.provide()
val fileName = AttachUtil.attachFile(
name = "app_log_file",
file = logFile,
mimeType = MimeType.PLAIN_TEXT
)
}
}
Add custom RunListener to Allure config.
@BeforeClass @JvmStatic
fun configureUltron() {
...
UltronAllureConfig.addRunListener(AppLogAttachRunListener())
}