Search code examples
javaandroidautomationappium-androidappium-java

How to display all elements not just the visible elements with java


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

Solution

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