KasperskyLab / Kaspresso

Android UI test framework
https://kasperskylab.github.io/Kaspresso/
Apache License 2.0
1.81k stars 153 forks source link

[Kautomator] auto-scrolling not working properly in screens with several Scrollables #342

Open sergio-sastre opened 2 years ago

sergio-sastre commented 2 years ago

This happens for example in screens containing several Scrollable views like one "CollapsingToolbarLayout" and a "ScrollView/NestedScrollView/RecyclerView..." e.g. the layout I was using to fix ScrollView with padding: Layout with CollapsingToolbarLayout, HorizontalScrollableView and NestedScrollView

Removing the CollapsingToolbarLayout fixes the issue indeed.

That happens because ObjectAutoScrollProvider uses

val scrollable = UiScrollable(UiSelector().scrollable(true))

That scrolls the first scrollable View, in this cases the CollapsingToolbarLayout!

Possible solution: Enable through Kaspresso builder to pass a UiSelector() for the View we want to autoscroll e.g.

class ObjectAutoScrollProviderImpl(
    private val logger: UiTestLogger,
    private val autoScrollParams: AutoScrollParams,
    private val uiScrollSelector: UiSelector = UiSelector().scrollable(true)
) : AutoScrollProvider<UiObjectInteraction> {
...
   val scrollable = UiScrollable(uiScrollSelector)
...

This would give the developer the flexibility for such cases.

Any other suggestion to a better solution is welcome :)

NOTE: I tested a draft of the proposed solution and it works. I can take this also for 1.4.1 :)

Solution checklist:

matzuk commented 2 years ago

Hi @sergio-sastre! Interesting point. Maybe, it would be better to create an additional special function like scroll that is available in a test like flakySafety and continuously. So, this scroll function can take an argument uiScrollSelector: UiSelector.

sergio-sastre commented 2 years ago

Sure, I'll try that :)

sergio-sastre commented 2 years ago

I've been evaluating how to better solve this. So there are 2 solutions: First, implement sth like scrollSafely

scrollSafely(UiSelector().withId("scroll_View")){
   // action on targetView
}

Second

scrollView.scrollToView(targetView)
// action on targetView

Looks like the first one has no real advantage over the second one, since you still need to identify the view that needs to do the scroll. That was the main advantage of AutoScroll: you do not need to know anything about the scrolling containers.

Suggestion I believe the best is to document in the readme that Kautomator autoscroll might not work fine if there are several scrollable views on the target screen, and the user must explicitly tell the desired scrollable view to scroll in such cases.

However, I've realised that horizontal scrollable Views do not scroll properly when using Kautomator. That is because one needs to do that by calling .setAsHorizontalList()

I'll open a PR shortly that adds a UiHorizontalScrollView that does exactly that :)

matzuk commented 2 years ago

@sergio-sastre Hi Sergio! Sorry, a lot of work now. Let me check and help you next year (January 5th, 6th) =)

sergio-sastre commented 2 years ago

@sergio-sastre Hi Sergio! Sorry, a lot of work now. Let me check and help you next year (January 5th, 6th) =)

Here is the PR: https://github.com/KasperskyLab/Kaspresso/pull/344

I believe, if that solution is fine, we should add some remark in the docu to make Kautomator users aware of the possible misbehaviour if the screen contains several scrolling views (e.g. scrollable layouts, CollapsingToolbarLayout, HorizontalScrollableView and NestedScrollView etc.) and how to solve it :)

matzuk commented 2 years ago

@sergio-sastre Hi! Too busy, sorry. I asked @RuslanMingaliev and @eakurnikov to help you. Thank you again for your contribution!

sergio-sastre commented 2 years ago

@matzuk You can assign this to me. I've worked on this already, but closed the PR because I made it dependent to another one that had nothing to do with this.

I'll continue working on this on the 22nd August week, if I do not find time before

AzamatCherchesov commented 2 years ago

@sergio-sastre Hi! Thanks for your help! Are there any updates?

sergio-sastre commented 2 years ago

@sergio-sastre Hi! Thanks for your help! Are there any updates?

So here my insights on this when dealing with nested ScrollableViews:

  1. The first and easiest solution is that the user sets ScrollableViews and make them scroll instead of relying on the autoscroll view. We could add a Kaspresso HorizontalScrollableView for letting users also handle horizontal scrolling.

  2. The second would be to iterate through all the nested scrollable views. Due to the way UiAutomator works, meaning, it can only interact with the elements visible on the screen (opposite to Espresso),. This means:

Nikitae57 commented 2 years ago

Hi, @sergio-sastre! Could you tell if you're working on this, please?

sergio-sastre commented 2 years ago

Hi, @sergio-sastre! Could you tell if you're working on this, please?

I'm planning to work on the first point this week, which would be easy. The second one is more complex and will require more time, not sure when I'll find time for it