Skip to content
This repository has been archived by the owner on May 26, 2021. It is now read-only.

ListPopupWindow and Toast intergation #42

Closed
Chesteer89 opened this issue Oct 19, 2017 · 32 comments
Closed

ListPopupWindow and Toast intergation #42

Chesteer89 opened this issue Oct 19, 2017 · 32 comments

Comments

@Chesteer89
Copy link

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

@Unlimity
Copy link
Member

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")
    } }
}

@Chesteer89
Copy link
Author

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)

@Unlimity
Copy link
Member

You can try using isInstanceOf matcher for your list. And are you sure that list doesn't have an id?

@Unlimity
Copy link
Member

Also you can match the list by matching it's items with use of withDescendant

@Chesteer89
Copy link
Author

Chesteer89 commented Oct 19, 2017

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())

@Unlimity
Copy link
Member

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?

@VerachadW
Copy link
Contributor

@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.

@Chesteer89
Copy link
Author

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?

@Unlimity
Copy link
Member

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?

@ashdavies
Copy link
Contributor

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()?

@Unlimity
Copy link
Member

Unlimity commented Aug 1, 2018

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.

@Unlimity
Copy link
Member

Unlimity commented Aug 1, 2018

We added KSnackBar support though.

@ashdavies
Copy link
Contributor

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.

@Unlimity
Copy link
Member

Unlimity commented Aug 3, 2018

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
  }
}

@ashdavies
Copy link
Contributor

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?

@Unlimity
Copy link
Member

Unlimity commented Aug 3, 2018

  val list = KListView(...) {
    isInstanceOf(ListView::class.java)
  }

  ...

  screen {
    list {
      inRoot { isPlatformPopup() }
      // Do your stuff here
    }
  }

@ashdavies
Copy link
Contributor

That's what I've tried, but I'm getting a NoMatchingViewException 😞

@Unlimity
Copy link
Member

Unlimity commented Aug 4, 2018

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?

@Unlimity
Copy link
Member

Unlimity commented Aug 4, 2018

Also, what exact class do you use to spawn your popups?

@ashdavies
Copy link
Contributor

I'm using a custom view extending from AppCompatAutocompleteTextView

Dumps
https://gist.github.com/ashdavies/4cfca8f5ff8697a8f53f566141480f73
https://gist.github.com/ashdavies/829645d64238115db33272af7c21d23f

@Unlimity
Copy link
Member

Unlimity commented Aug 7, 2018

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.

@ashdavies
Copy link
Contributor

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 😞

@Unlimity
Copy link
Member

Unlimity commented Aug 7, 2018

Can you provide your screen class and test code where you try to access your list?

@ashdavies
Copy link
Contributor

ashdavies commented Aug 21, 2018

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()
      }
    }
  }
}

@Unlimity
Copy link
Member

Hey there!
Try removing this:

withParent {
  isRoot()
}

I'm not sure that your list view is a direct descendant of platform popup view.

@ashdavies
Copy link
Contributor

Still get a NoMatchingViewException, would it help if I submitted a PR to the samples with the problem I'm trying to solve?

@Unlimity
Copy link
Member

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.

@ashdavies
Copy link
Contributor

@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)

@Unlimity
Copy link
Member

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?

@ashdavies
Copy link
Contributor

I'll create a PR for the samples directory with what I'm trying to achieve

@ashdavies
Copy link
Contributor

@Unlimity Hey! I've created a sample so you can see what I'm trying to achieve

@Unlimity
Copy link
Member

Unlimity commented Sep 6, 2018

Sure, I'll take a look as soon as I have free time

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants