Kaspresso icon indicating copy to clipboard operation
Kaspresso copied to clipboard

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

Open sergio-sastre opened this issue 4 years ago • 11 comments

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:

  • [x] Works with HorizontalScrollView
  • [x] Works with any "vertical" scrollable view like NestedScrollView

sergio-sastre avatar Dec 08 '21 21:12 sergio-sastre

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.

matzuk avatar Dec 12 '21 04:12 matzuk

Sure, I'll try that :)

sergio-sastre avatar Dec 19 '21 19:12 sergio-sastre

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

sergio-sastre avatar Dec 23 '21 11:12 sergio-sastre

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

matzuk avatar Dec 29 '21 07:12 matzuk

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

sergio-sastre avatar Jan 14 '22 15:01 sergio-sastre

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

matzuk avatar Jan 14 '22 15:01 matzuk

@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

sergio-sastre avatar Aug 09 '22 06:08 sergio-sastre

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

AzamatCherchesov avatar Oct 24 '22 16:10 AzamatCherchesov

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

  •  1. Forward scroll the top ScrollableView.
         1.1 If element not found, scroll forward first nested ScrollViews on the screen
           1.1.1  If still element not found -> scroll backwards
               1.1.1.1 If still not found -> repeat 1.1 and 1.1.1 with next scrollableView on the screen
               1.1.1.2 If no more ScrollableViews in the Screen, repeat 1
               1.1.1.3 If cannot scroll forwards, back to 1 but scrolling backwards instead of forwards, till it cannot scroll    anymore             
    

It seems a bit complex, but I can try to go with it. However it will take some time...

sergio-sastre avatar Oct 25 '22 14:10 sergio-sastre

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

Nikitae57 avatar Nov 07 '22 07:11 Nikitae57

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

sergio-sastre avatar Nov 08 '22 07:11 sergio-sastre