Closed Chesteer89 closed 7 years ago
Hey there! Thanks a lot for your interest in our project.
Regarding your question: it can be done via KView
and KListView
. We have inRoot()
function located at BaseAssertions
.
And we have RootBuilder
class which helps you to perform this kind of checks.
Take a look at the example:
fun test() {
screen { list {
inRoot { isPlatformPopup() }
childAt(0) { hasText("TEST") }
} }
}
fun testToast() {
screen { toast {
inRoot { withMatcher(ToastMatcher()) }
hasText("TOAST")
} }
}
Are you sure we're able to get list in popup? What kind of matcher should i pass in Screen? (id is not set, withClassName doesnt work, withAnyText matches multiple views)
You can try using isInstanceOf
matcher for your list. And are you sure that list doesn't have an id?
Also you can match the list by matching it's items with use of withDescendant
Well, yes. We're using ListPopupWindow which doesnt have an id on list (contains DropDownListView). So the idea is to find a popup first (the real diff is inAdapterView(matcher)
changed to inRoot(RootMatchers.isPlatformPopup())
).
Toast is similiar story. That's why I've changed view to:
override val view = this.builder.getViewInteraction().inRoot(ToastMatcher())
For toast, as I said previously, you can declare a view with text matcher, for example, and then immediately apply root matcher:
val toast = KView {
withText("TOAST")
} perform {
inRoot { withMatcher(ToastMatcher()) }
}
This will return you the KView with view interaction inside, which already has root matcher.
Regarding ListView situation, I think we should ask someone else. @cdsap @VerachadW what do you guys think on this?
@Chesteer89 You may try to send the matcher for list
with the parent matcher. The popup needs to anchor with the view or the screen window. So, I think we can create a matcher for the parent view and pass it to withParent()
for list
. This is my idea.
Thanks guys! Optional parameter or withParent()
sounds good.
I'll migrate to new version after update :)
Did you think about Snackbar tests? Is it possible right now or should i write my custom view + actions?
No, right now we don't have prebuilt view classes for that, but this is good idea, to make KSnackBar
and KToast
. Is this issue resolved?
I'm currently trying to achieve the same thing here with an AutoCompleteTextView
suggestion matcher (PopupWindow
/DropDownListView
), did you manage to find a resolve using withParent()
?
Hi there!
The thing is, right now this behavior is not achievable due to specifics of these classes. PopupWindow
and Toast
actually create new Window
instance when they show up. And espresso is explicitly bound to your activity's window with ViewRootImpl
inside. It cannot access other windows through instrumentation.
We added KSnackBar
support though.
My understanding is that you could use:
onData(equalTo("ITEM"))
.inRoot(RootMatchers.isPlatformPopup())
.perform(click())
for an autocomplete item?
I'm just not quite sure how to integrate that with a KListView
, or if at all it's possible to do so at the moment.
As I recall, we have root matching.
So you can match your KListView
by any means comfortable to you (by id, by class name, by searching through parent class name, etc.) and then apply root matcher during your actions/assertions:
screen {
list {
inRoot { isPlatformPopup() }
// Do your stuff here
}
}
Yep, but the difficulty is creating list
in our Screen<T>
class, the suggestion was to use withParent
and isRoot
, but I've not had much success, what might be a way of selecting it?
val list = KListView(...) {
isInstanceOf(ListView::class.java)
}
...
screen {
list {
inRoot { isPlatformPopup() }
// Do your stuff here
}
}
That's what I've tried, but I'm getting a NoMatchingViewException
😞
Can you provide the dumps of layouts when you open your popup and the results of adb shell dumpsys window windows
and adb shell dumpsys activity
?
Also, what exact class do you use to spawn your popups?
I'm using a custom view extending from AppCompatAutocompleteTextView
Dumps https://gist.github.com/ashdavies/4cfca8f5ff8697a8f53f566141480f73 https://gist.github.com/ashdavies/829645d64238115db33272af7c21d23f
I looked through the source code, and your view uses ListPopupWindow
class inside, which uses DropDownListView
class (not appcompat). So I would try to match by exact class name, not by parent class name.
Tried by class name also, the issue seems to be that the view hierarchy dumped with NoMatchingViewException
is that of the activity window, which doesn't display the DropDownListView
or the popup decor view, I've tried tweaking with withParent
, inRoot
to no avail 😞
Can you provide your screen class and test code where you try to access your list?
Sorry for the delay, I didn't see the notification
Screen
val list = KListView(
builder = {
isInstanceOf<ListView>()
withParent {
isRoot()
}
},
itemTypeBuilder = {
itemType(::Item)
}
)
class Item(interaction: DataInteraction) : KAdapterItem<Item>(interaction) {
val text = KTextView(interaction) {
withId(android.R.id.text1)
}
}
Test
screen {
list {
inRoot {
isPlatformPopup()
}
firstChild<FinanceCalculatorScreen.Item> {
perform {
click()
}
}
}
}
Hey there! Try removing this:
withParent {
isRoot()
}
I'm not sure that your list view is a direct descendant of platform popup view.
Still get a NoMatchingViewException
, would it help if I submitted a PR to the samples with the problem I'm trying to solve?
I just noticed. isInstanceOf<ListView>()
is very weird. Kakao doesn't have that function. Kakao's function signature is isInstanceOf(clazz: Class<*>)
. It's not templated.
@Unlimity yep sorry this was an extension function in our code base, just an inline reified alias to Kakao's method
inline fun <reified T> ViewBuilder.isInstanceOf(): Unit = isInstanceOf(T::class.java)
Hm, I don't actually know how to help you now :( Could you make a public repo with simple activity and test that reproduces your problem?
I'll create a PR for the samples directory with what I'm trying to achieve
@Unlimity Hey! I've created a sample so you can see what I'm trying to achieve
Sure, I'll take a look as soon as I have free time
Hi guys!
First of all - thanks for your work! Can you take a look on KToast and KListPopupWindow and give me some hints (maybe it's just an overkill and it could be done with KView and KListView?
https://gist.github.com/Chesteer89/767ad1b1584e2920a9758bd1dfe95b36 https://gist.github.com/Chesteer89/d6bfe7383c287935ce938e9dfa98c0a1