Scrolling inside a menu

I have a drawer that comes up from the bottom of the view.
I would like to scroll inside the drawer.

How can this be done as the swipe option doesn’t seem to work.
Also, tried Scroll to Text and that would keep collapsing the drawer than scroll down.

Thanks

Hi Danny,

I had trouble with getting scrolling to work as well. There seem to be a lot of tricks based on the platform you’re using. If you don’t mind adding an external library .jar to your test project, this open source library I have been working on might help:

https://github.com/detroit-labs/katalon-mobile-util#scrolling

The library itself is available at:

https://github.com/detroit-labs/katalon-mobile-util#installation

For info on how to add an external library to your testing project, see the Katalon docs:

https://www.katalon.com/resources-center/tutorials/import-java-library/

Hope this helps,

Chris

2 Likes

Hi @Chris Trevarthen

The Issue I am having is when I am trying to scroll inside the drawer is, the command to scroll to element will close the drawer and reopen it couple of times instead of scrolling down the list of menu.
I tried the above lib with this in the script in the Katalong Studio GUI:
Scroll.scrollListToElementWithText(‘Debug Options’, 0)

This would not scroll the menu list at all…
Is there something I am missing?

Thanks

Danny

Hi Danny,

Sorry to hear that the katalon-mobile-util library isn’t helping you scroll, either. Are you writing tests for iOS or Android? Are you getting any errors in the Log View or the Console?

If possible, I’d like to know the structure of the screen elements at the time when the drawer is open. Could you log out the XML contents of the screen and share them (strip out anything proprietary/confidential first)? You should be able to do that by putting the following import statements at the top of your test case:

import com.kms.katalon.core.logging.KeywordLogger
import com.kms.katalon.core.mobile.keyword.internal.MobileDriverFactory
import io.appium.java_client.AppiumDriver

Then in the code for your test, add the following right after the drawer opens:

AppiumDriver<?> driver = MobileDriverFactory.getDriver()
KeywordLogger log = new KeywordLogger()
log.logInfo(driver.getPageSource())

When the test runs, you should see an entry in the Log Viewer for “Statement - log.logInfo(driver.getPageSource())” that shows the start of the XML for the screen. If you tap on it, you’ll see all of the XML for the screen on the right-hand pane. If you could copy and share that, I can help troubleshoot why the scrolling isn’t working. (I recommend putting it into a text editor first to remove any sensitive data, like package names, etc.)

Thanks,

Chris

Screen Shot 2018-09-30 at 11.39.43 PM.png

@Chris Trevarthen

When running what you have stated above I am getting this error upon Evaluating:

Test Cases/LogIntoAccount FAILED because (of) (Stack trace: org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
file:/C:/Users/Danny/Katalon%20Studio/xxxxxx/Scripts/LogIntoAccount/Script1537914882499.groovy: 27: unable to resolve class AppiumDriver 
 @ line 27, column 17.
   AppiumDriver<?> driver = MobileDriverFactory.getDriver()
                   ^
1 error
	at org.codehaus.groovy.control.ErrorCollector.failIfErrors(ErrorCollector.java:310)
	at org.codehaus.groovy.control.CompilationUnit.applyToSourceUnits(CompilationUnit.java:946)
	at org.codehaus.groovy.control.CompilationUnit.doPhaseOperation(CompilationUnit.java:593)
	at org.codehaus.groovy.control.CompilationUnit.compile(CompilationUnit.java:542)
	at groovy.lang.GroovyClassLoader.doParseClass(GroovyClassLoader.java:298)
	at groovy.lang.GroovyClassLoader.parseClass(GroovyClassLoader.java:268)
	at com.kms.katalon.core.main.ScriptEngine.getScript(ScriptEngine.java:188)
	at com.kms.katalon.core.main.ScriptEngine.run(ScriptEngine.java:183)
	at com.kms.katalon.core.main.ScriptEngine.runScriptAsRawText(ScriptEngine.java:108)
	at com.kms.katalon.core.main.TestCaseExecutor.runScript(TestCaseExecutor.java:294)
	at com.kms.katalon.core.main.TestCaseExecutor.doExecute(TestCaseExecutor.java:285)
	at com.kms.katalon.core.main.TestCaseExecutor.processExecutionPhase(TestCaseExecutor.java:264)
	at com.kms.katalon.core.main.TestCaseExecutor.accessMainPhase(TestCaseExecutor.java:256)
	at com.kms.katalon.core.main.TestCaseExecutor.execute(TestCaseExecutor.java:200)
	at com.kms.katalon.core.main.TestCaseMain.runTestCase(TestCaseMain.java:99)
	at com.kms.katalon.core.main.TestCaseMain.runTestCase(TestCaseMain.java:90)
	at com.kms.katalon.core.main.TestCaseMain$runTestCase$0.call(Unknown Source)
	at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113)
	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:149)
	at TempTestCase1538407339836.run(TempTestCase1538407339836.groovy:22)
	at groovy.lang.GroovyShell.runScriptOrMainOrTestOrRunnable(GroovyShell.java:263)
	at groovy.lang.GroovyShell.run(GroovyShell.java:518)
	at groovy.lang.GroovyShell.run(GroovyShell.java:507)
	at groovy.ui.GroovyMain.processOnce(GroovyMain.java:653)
	at groovy.ui.GroovyMain.run(GroovyMain.java:384)
	at groovy.ui.GroovyMain.process(GroovyMain.java:370)
	at groovy.ui.GroovyMain.processArgs(GroovyMain.java:129)
	at groovy.ui.GroovyMain.main(GroovyMain.java:109)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.codehaus.groovy.tools.GroovyStarter.rootLoader(GroovyStarter.java:109)
	at org.codehaus.groovy.tools.GroovyStarter.main(GroovyStarter.java:131)
)

Am I missing something?
I strike through part of my file path part that needed to be hidden.
Also, I am working on Android.

Edit: added more info and formatting

Sorry about that Danny, there is another import that I forgot to have you add to the top of your file:

import io.appium.java_client.AppiumDriver

NOTE: There is a keyboard shortcut that will auto-import any libraries for you, which is very handy. On Mac, it’s CMD+SHIFT+O (I’m guessing it’s CTRL+SHIFT+O on Windows).

- Chris

@Chris Trevarthen
Never mind. I found the issue to why I was getting those error. I needed another dependency.

Here is the XML for when I tap to open the drawer right away.
It would not let me upload it as text as it was too long so here is the file so I am uploading it as a txt file.

Also drawer1 is when the drawer opens but it might be too fast and not get the correct xml so I made another one, drawer2, where I put a wait for an element to this might be more accurate.

Thanks

drawer2.txt

Danny, thanks for sharing those XML docs - they are helpful in seeing what you’re trying to do.

Can you tell me which scroll menu you expect the “Debug Options” item to be in (below what existing element would you expect to see it?) I ask because Android dynamically loads scroll lists as the user scrolls; it doesn’t load all the elements at the beginning, so right now, I don’t see “Debug Options” in the XML.

Second, if you look in the Console tab when running your tests, do you see any errors or messages during the scrolling part? The library should print out what it sees when it’s trying to scroll. It should also print out an error when it can’t find anything to scroll.

Thanks, Chris

@Chris Trevarthen

I see why it was not populating on the XML.
The Debug option is at the bottom of the list and does not populate because it is not in the viewport.
Once I get it into the viewport, I can see the Debug Options.

It should be in the “<android.widget.TextView index=…”

Hope that makes sense…
I will check later tonight for any error message in the console and reply back.

Hi Danny,

Any luck on this? Were you able to see any errors?

I think the issue might be that my library doesn’t yet handle multiple ScrollViews on the screen at once. That’s why I was asking which ScrollView the “Debug Options” element is in. For example, if your screen is laid out like:

ScrollView A
- Item A1
- Item A2
- Item A3

ScrollView B
- Item B1
- Item B2
- Item B3
------- End of visible list -------
- Item B4
- Item B5 - YOUR DESIRED ELEMENT

ScrollView C
- Item C1
- Item C2
- Item C3

In this scenario, if you wanted Item B5, the library just knows that B5 isn’t on the screen, so it gets the very last visible item, Item C3 and drags it up to scroll. Obviously, that’s not going to scroll ScrollView B, so you’ll never see Items B4 or B5.

I’m pretty sure that’s the problem, and I will work on a way to specify the ScrollView you want to scroll in a new version of the library.

- Chris

1 Like

@Chris Trevarthen

Sorry took longer than expected to get back to you with the console log.
I have attached it here.

Thanks, and what you mentioned above makes sense.

There is only 1 ScrollView and 1 GroupView and 1 View when the scrolling menu is visible.

Adding image to show you the objects list.

Scroll Open

Scroll Closed

scrollConsole.txt

ScrollAreaOpen.png

ScrollAreaNotOpen.png

Hi Danny,

Thanks for providing those screenshots - they are very helpful. Could you also provide one for when you scroll down in the Mobile Spy and can actually see “Debug Options” - I’d like to see what the page layout looks like then.

Also, I noticed in your log that there are some statements listed as “NOT RUN”:

10-03-2018 01:47:48 PM - [START]  - Start action : tapAtPosition
10-03-2018 01:47:48 PM - [NOT_RUN] - NOT_RUN: tapAtPosition
10-03-2018 01:47:48 PM - [END]    - End action : tapAtPosition
10-03-2018 01:47:48 PM - [START]  - Start action : Statement - com.detroitlabs.katalonmobileutil.touch.Scroll.scrollListToElementWithText("Debug Options", 0)
10-03-2018 01:47:48 PM - [NOT_RUN] - NOT_RUN: Statement - com.detroitlabs.katalonmobileutil.touch.Scroll.scrollListToElementWithText("Debug Options", 0)
10-03-2018 01:47:48 PM - [END]    - End action : Statement - com.detroitlabs.katalonmobileutil.touch.Scroll.scrollListToElementWithText("Debug Options", 0)

Are you skipping those statements? If so, could you try reactivating them? Could you also send the log and errors when you run the “Scroll.scrollListToElementWithText()” commands?

Thanks,

Chris

@Chris Trevarthen
Thanks for the replies.
I am trying to get the logs but I changed it up a little.
Also, I got the devs to make it where I do not need to scroll down the menu and made the debug on all the time.

But now I am having another issue with scroll to text.
I tried your suggestion out but still not working.

Can you take a look at it if I get you the logs?

Thanks

Danny,

Glad you were able to find a workaround. If you send the logs I will sure take a look!

- Chris

Hi @Chris_Trevarthen, I have the same problem as Danny that I can’t scroll down inside a menu, I tried the log that you provide, but it can only go through the log viewer. I want to scroll down to android.view.View32, but the device won’t work. The following is my log and a

picture of my recorder:

class swiping {
AppiumDriver driver;

swiping() {
	this.driver = MobileDriverFactory.getDriver()
}

private scrollEntireList() {		// very specific to android and the type of element that makes up your dropdowns
	ArrayList listElement = driver.findElementsByClassName("android.view.View")
	TouchAction touchAction = new TouchAction(driver)
	def bottomElement = listElement[listElement.size() - 1]
	def topElement = listElement[0]		// Press and scroll from the last element in the list all the way to the top
	touchAction.press(bottomElement).moveTo(topElement).release().perform();
}

@Keyword
def boolean scrollListToElementWithText(String elementText)
{
boolean isElementFound = false;
while (isElementFound == false) { // very specific to android and the type of element that makes up your dropdowns

	ArrayList listElement = driver.findElementsByClassName("android.view.View")
	for (int i = 0; i<listElement.size(); i++) {
		String textItem = listElement[i].getText()
		if (textItem == elementText) {
			isElementFound = true;
			return true;
			}
	}
	
	scrollEntireList()
}

}}

Thank you

Hi @daniel861225,

I wrote a library that might help with your scrolling issues, if you’d like to give it a try. You can download the .jar file from here and place it in your project’s /Drivers directory.

You can then follow instructions for scrolling here to write some code in your test file that scrolls the list to a particular text value.

If that doesn’t work for you, or if you have questions, please let me know. Also, if it’s possible to share a screenshot of the menu you’re trying to scroll, that would be helpful, too.

Hope this helps,

Chris

hi chris, i got this issue when i already inserted the .jar into the eksternal katalon library, and already inserted the
import com.detroitlabs.katalonmobileutil.touch.Scroll
import com.detroitlabs.katalonmobileutil.touch.Scroll.ScrollFactor
import com.kms.katalon.core.logging.KeywordLogger
import com.kms.katalon.core.mobile.keyword.internal.MobileDriverFactory
import io.appium.java_client.AppiumDriver

i want to scroll the listview to find the label on the bottom of the listview, but when i run i got those error. so i can’t continue the Button.tap to tap the button element next

this is the script >> Scroll.scrollListToElementWithText(‘Success1562732204114’, 30)

im using your library, and its working perfectly.
recently i have trouble with calendar on my mobile apps. I need to scroll to specific year. e.g 2010.
is there a way that i can scroll up-to-down or down-to-up ? because in your library i can only scroll down-to-up. thanks in advance

Hi @fransiskamayalestari,

Glad the library is working out for you!

You’re right, the scrolling was made with going down a list in mind. I will look at adding a way to control the direction. In the meantime, you could try the addition of the Swipe class, which does let you control the direction. You could perform a swipe from top to bottom and then do a find for your desired element.

Here’s some info on the Swipe class:

Hope this helps,

Chris

1 Like

Hi.

thanks so much Chris. hope to see the enhancement .

FML