Skip to content

Releases: open-tool/ultron

2.3.3

07 Mar 07:54
Compare
Choose a tag to compare

Compose List & RecyclerView Item Child improvements in #60

  • ComposeListItem child

old syntax:

class CustomListItem : UltronComposeListItem() {
    val status by lazy { getChild(hasTestTag(contactStatusTestTag)) }
}

new:

class CustomListItem : UltronComposeListItem() {
    val name by child { hasTestTag(contactNameTestTag) }
}

You can use both ways at the same time:

class CustomListItem : UltronComposeListItem() {
    val name by child { hasTestTag(contactNameTestTag) }
    val status by lazy { getChild(hasTestTag(contactStatusTestTag)) }
}
  • RecyclerViewItem child

Old syntax:

class CustomRecyclerItem : UltronRecyclerViewItem() {
    val name by lazy { getChild(withId(R.id.tv_name)) }
}

New:

class CustomRecyclerItem : UltronRecyclerViewItem() {
    val name by child { withId(R.id.tv_name) }
}

You can use both ways at the same time:

class CustomRecyclerItem : UltronRecyclerViewItem() {
    val name by child { withId(R.id.tv_name) }
    val status by lazy { getChild(withId(R.id.tv_status)) }
}

Full Changelog: 2.3.2...2.3.3

2.3.2

25 Feb 11:47
dd15bc8
Compare
Choose a tag to compare

What's Changed

Compose LazyList improvements in #59

Add

  • new methods to interact with LazyList item by position:
firstItem() 
item(position: Int)
getItem(position: Int): T  
getFirstItem(): T 

to use these methods you have to configure positionPropertyKey in application code and specify it in composeList declaration.

composeList(marcher =..., positionPropertyKey = ListItemPositionPropertyKey)

Read new wiki page for details - Efficient Strategies for Locating Items in Compose LazyList

  • new method for UltronComposeList
fun assertItemDoesNotExist(itemMatcher: SemanticsMatcher)

Removed

method UltronComposeListItem().assertDoesNotExist()

Full Changelog: 2.3.1...2.3.2

2.3.1

02 Dec 08:13
Compare
Choose a tag to compare

What's Changed

There are 2 new general methods:

withName(name: String)
withMetaInfo(meta: Any)

By default name is used in exceptions messages.

These data also could be used in listeners and result analyzers:

 class MetaListener: UltronLifecycleListener(){
     override fun afterFailure(operationResult: OperationResult<Operation>) {
         val name = operationResult.operation.elementInfo.name
         val metaInfo = operationResult.operation.elementInfo.meta
     }
 }

Full Changelog: 2.3.0...2.3.1

2.3.0

20 Aug 12:01
1c81014
Compare
Choose a tag to compare

What's Changed

Enhanced framework extension for Espresso and Compose.

Here is a new wiki page

New features

Add new Compose methods to getNode and getNodeConfigProperty:

val semanticsNode = hasTestTag("Button").getNode()
val testTag = hasText("Some text").getNodeConfigProperty(SemanticsProperties.TestTag)

Simplified Compose extension

Introducing new perform and execute methods.

Use perform if you wish to evaluate an operation and return an updated UltronComposeSemanticsNodeInteraction object.

fun UltronComposeSemanticsNodeInteraction.hasAnyChildren() = perform {
    Assert.assertTrue(it.fetchSemanticsNode().children.isNotEmpty())
}

fun SemanticsMatcher.hasAnyChildren() = UltronComposeSemanticsNodeInteraction(this).hasAnyChildren()

Use execute to evaluate operation and return the result.

fun UltronComposeSemanticsNodeInteraction.getWidth(): Int = execute {
    it.fetchSemanticsNode().size.width
}

fun SemanticsMatcher.getWidth(): Int = UltronComposeSemanticsNodeInteraction(this).getWidth()

Simplified Espresso operations extenstion

Use perform if you intend to evaluate an operation and return an updated UltronEspressoInteraction

fun <T> UltronEspressoInteraction<T>.appendText(value: String) = perform { _, view ->
    val textView = (view as TextView)
    textView.text = "${textView.text}$value"
}

Use execute to evaluate operation and return the result.

fun <T> UltronEspressoInteraction<T>.getText(): String = execute { _, view ->
    (view as TextView).text.toString()
}

Customize your action using UltronEspressoActionParams for both pefrorm and execute methods.

fun <T> UltronEspressoInteraction<T>.getDrawable(): Drawable? = execute(
    UltronEspressoActionParams(
        operationName = "GetDrawable from TextView with '${getInteractionMatcher()}'",
        operationDescription = "description...",
        operationType = CustomEspressoActionType.GET_DRAWABLE,
        viewActionConstraints = isAssignableFrom(ImageView::class.java),
        viewActionDescription = "getting Drawable from ImageView"
    )
){ _, view ->
    (view as ImageView).drawable
}

Use new assertMatches method to extend framework with new assertion.

fun <T> UltronEspressoInteraction<T>.assertChecked(expectedState: Boolean) = assertMatches { view ->
    (view as CheckBox).isChecked == expectedState
}

Breaking changes:

The signature of UltronComposeSemanticsNodeInteraction old perform method has been modified.

If you are using the old perform method to obtain the result of an operation, you should replace it with execute.

For instance, in the following cases, replace pefrorm to execute

// in extension function
fun UltronComposeSemanticsNodeInteraction.getWidth(): Int = pefrorm {
    it.fetchSemanticsNode().size.width
}
// direct usage
val width: Int = hasTestTag("button").pefrorm {
	it.fetchSemanticsNode().size.width
}

Deprecated

Matcher<View>.performOnView() - Use new Matcher<View>.perform { view -> } instead.

Full Changelog: 2.2.6...2.3.0

2.2.6

31 Jul 20:36
Compare
Choose a tag to compare

What's Changed

Note: To add window hierarchy for Compose you have to call

UltronComposeConfig.addListener(WindowHierarchyAttachListener())

See updated Allure doc

New Contributors

Full Changelog: 2.2.4...2.2.6

2.2.4

17 Jun 15:45
Compare
Choose a tag to compare

#45 - Fix method name for parametrized tests

2.2.3

13 Jun 20:01
Compare
Choose a tag to compare

Fix:

  • getViewForcibly()
  • performOnViewForcibly()

2.2.2

31 May 20:29
Compare
Choose a tag to compare

Inhencments

  1. New extension methods for Matcher<View>, ViewInteraction, DataInteraction :
doesNotExistInAnyVisibleRoot() 
getView(): View 
getViewForcibly(): View  //bypass Espresso idling state mechanism
performOnView(action: View.() -> Unit)
performOnViewForcibly(action: View.() -> Unit)  //bypass Espresso idling state mechanism
  1. Add method to perform action on view on Ui Thread.
View.performOnView(action: View.() -> Unit)
  1. Improved ResourceDrawableMatcher, affected methods:
hasDrawable(@DrawableRes resourceId: Int)
hasAnyDrawable()

Thanks @itsergpot

ultron-allure

20 Apr 10:23
c2e05ff
Compare
Choose a tag to compare

Allure report artifacts generation is supported.

There is a new dependency com.atiurin:ultron-allure:<latest_version>.

Ultron provides all required allure libs. You don't need to add them.

Please read Allure wiki carefully.

Recommended configs

Ultron has recommendations about it's configuration. Basically you just need to add few lines of code to receive full power of framework:

@BeforeClass @JvmStatic
fun configuration() {
    UltronConfig.applyRecommended()
    UltronAllureConfig.applyRecommended()
    UltronComposeConfig.applyRecommended()
    UltronComposeConfig.addListener(ScreenshotAttachListener())
    UltronComposeConfig.addListener(DetailedOperationAllureListener())
}

Breaking changes

UltronComposeConfig import changed from import com.atiurin.ultron.core.compose.UltronComposeConfig to
import com.atiurin.ultron.core.compose.config.UltronComposeConfig

ultron-compose

24 Mar 15:22
3a36845
Compare
Choose a tag to compare

Compose part is separated into another library ultron-compose

From 2.1.0 you need to add 2 dependencies.

dependencies {
    androidTestImplementation 'com.atiurin:ultron:<latest_version>'
    androidTestImplementation 'com.atiurin:ultron-compose:<latest_version>'
}

com.atiurin:ultron:2.1.0 provides required libs, so you don't need to add them to dependencies.

The list of provided libs:

  • "androidx.test.espresso:espresso-core:3.4.0"
  • "androidx.test.espresso:espresso-contrib:3.4.0"
  • "androidx.test.espresso:espresso-web:3.4.0"
  • "androidx.test.uiautomator:uiautomator:2.2.0"
  • "com.google.android.apps.common.testing.accessibility.framework:accessibility-test-framework:4.0.0"
  • "org.hamcrest:hamcrest-core:2.2"

You can exclude them from androidTestImplementation section

com.atiurin:ultron-compose:2.1.0 provides "androidx.compose.ui:ui-test-junit4:1.1.1"

Breaking changes

UltronConfig.Compose moved to UltronComposeConfig

Internal changes

Move from gradle to kts