1

I want to get all names from settings menu: https://app.screencast.com/AdssamooNLZbm?conversation=QUFAp0MrtNKXgm68k42Gfy&tab=Details

https://app.screencast.com/J4VoylbceDuca?conversation=Fodt4TO4fN1IVYW4zb9MKH&tab=Details

https://app.screencast.com/U0fnubCAhMjfW?conversation=wluK8dBoc2UkS6YRDqta1u&tab=Details

   
   public static void main(String[] args) throws MalformedURLException, InterruptedException {
               
       DesiredCapabilities dc = new DesiredCapabilities();
       dc.setCapability(MobileCapabilityType.AUTOMATION_NAME, "Appium");   
       dc.setCapability(MobileCapabilityType.DEVICE_NAME, "Redmi Note 9 Pro");     
       dc.setCapability(MobileCapabilityType.PLATFORM_NAME, "Android");    
       dc.setCapability(MobileCapabilityType.PLATFORM_VERSION, "12.0");    
       dc.setCapability("appPackage", "com.android.settings");
       dc.setCapability("appActivity", "com.android.settings.Settings");
               
       URL url = new URL("http://127.0.0.1:4723/wd/hub");      
       AndroidDriver<WebElement> driver = new AndroidDriver<WebElement>(url, dc);

       MobileElement list = (MobileElement) driver.findElement(MobileBy.AndroidUIAutomator("new UiScrollable(new UiSelector()).scrollIntoView("+ "new UiSelector().text(\"Services & feedback\"));"));
       Thread.sleep(5000);
       List <WebElement> list2 = driver.findElementsById("android:id/title");
       System.out.println(list2.size());
       
       for (WebElement i : list2) {
           System.out.println(i.getText());
       }
       }
   }
But my Output: 
10 
Apps
Additional settings
Digital Wellbeing & parental controls
Special features
Mi Account
Google
Accounts & sync
Privacy
Location
Services & feedback
  • 2
    Why did you delete [your previous question](https://stackoverflow.com/questions/75133504) which was virtually the same? Please *don't* do that. It's fine - and encouraged - to edit a question to make it clearer, but deleting and reposting is *not* fine. – Jon Skeet Jan 17 '23 at 08:18
  • That question was not formatted good and I created a new one better written –  Jan 17 '23 at 08:23
  • do you wanna print sub-menu? – Shila Mosammami Jan 17 '23 at 08:43
  • @ShilaMosammami no –  Jan 17 '23 at 08:44
  • 1
    "That question was not formatted good" - so all you needed to do was edit it. It's absolutely fine to edit a question; it's *not* fine to go into a delete/repost spiral. Please note that if you build up a large collection of deleted questions, you're more likely to be automatically banned from asking further questions. – Jon Skeet Jan 17 '23 at 09:14

1 Answers1

0

From what you have provided, it only logs the last 10 records shown on the phone.

So firstly a little explanation on this piece of code:

MobileElement list = (MobileElement) driver.findElement(MobileBy.AndroidUIAutomator("new UiScrollable(new UiSelector()).scrollIntoView("+ "new UiSelector().text(\"Services & feedback\"));"));
Thread.sleep(5000);
List<WebElement> list2 = driver.findElementsById("android:id/title");
System.out.println(list2.size());

It scrolls until you reach Services & feedback, waits for 5 seconds, and capture all the elements displaying with the corresponding IDs to your List.

So in order to capture all the elements with your provided ID, you probably need to repeat the following processes until you reach your destination:

  • Capture current display elements' name
  • Perform scrolling
// Create a big ArrayList to store all the Elements display name
ArrayList<String> settingNameList = new ArrayList<>();

// Capture the element displayed on screen first
List<WebElement> list1 = driver.findElementsById("android:id/title");
// Add the captured element's title to big List
for (WebElement item : list1) {
  settingNameList.add(item.getText());
}

// Perform the scrolling after first capturing
MobileElement scrollElement = (MobileElement) driver.findElement(MobileBy.AndroidUIAutomator("new UiScrollable(new UiSelector()).scrollIntoView("+ "new UiSelector().text(\"Services & feedback\"));"));
Thread.sleep(5000);

// Capture again on the current displaying screen
List<WebElement> list2 = driver.findElementsById("android:id/title");
// Add the captured element's title to big List
for (WebElement item : list2) {
  settingNameList.add(item.getText());
}

// Then display the Name one by one
for (String settingName : settingNameList) {
  System.out.println(settingName);
}

Please note that you have to directly process the captured WebElement. If you add WebElement into a List for later processing, you will very likely to encounter StaleElementReferenceException.

Enowneb
  • 943
  • 1
  • 2
  • 11
  • Hello. I've tried your solution but it gives this error: Exception in thread "main" org.openqa.selenium.StaleElementReferenceException: Cached elements 'By.id: android:id/title' do not exist in DOM anymore –  Jan 17 '23 at 08:54
  • I have modified the code a bit. Please try again if it works. In the previous case, ```StaleElementReferenceException``` should be thrown if the Element DOM does not exist in current showing page. So the above code tries to capture all the setting names in advance. – Enowneb Jan 17 '23 at 09:06
  • Please note for this line: ```ArrayList settingNameList = new ArrayList<>();``` – Enowneb Jan 17 '23 at 09:21
  • Yes, it works. One more question: is there a way not to repeat each step after scrolling? Thank you for helping :) –  Jan 17 '23 at 09:23
  • 1
    AFAIK, you can only get the visible items in Appium. So you have to implement your own loop, retrieve all the necessary data from the current visible ```WebElements```, until you reach the bottom of the List. – Enowneb Jan 17 '23 at 12:25