Search code examples
javaxpathappium

Appium Collecting all the text on any screen


I am working on translation automation for an app (iOS and android appium version 1.7.0) . Meaning i am supposed to go through all the pages of the app then I am using gcloud api to identify the language.

I need help finding an effective way to collect all the text displayed on a certain screen.

Currently I am using this approch as in the code below :

  1. I find all the elements on the page
  2. I get the ones with Text attributes

    public void displayText()
    {
    
        System.out.println("i will display all the text and each of their languages");
    
        // I find all the elements on the page as such
        List<MobileElement> list = driver.findElements(By.xpath("//*"));
    
    
        assertTrue(list.size()>0) ;
    
        System.out.println(list.size());
    
        //foreach of the elements detected I determine the language
    
    
    
        for(int i=0;i<list.size();i++)
        { if (list.get(i).getText()!= null) {
            String SeenText = list.get(i).getText();
            System.out.println(SeenText);
    
            //Lang detection
    
        List<Detection> detections 
        =translate.detect(ImmutableList.of(list.get(0).getText()));
        System.out.println("Language(s) detected:");
        for (Detection detection : detections) {
        System.out.printf("\t%s\n", detection);}
    
    
        }}
    
    System.out.println(driver1.getPageSource());
    

However this is only working for pages with few elements. It takes so much time for content heavy paged that the appium session times out.

I have considered manually parsing the outcome of "driver.getPageSource())" But I am not sure if that is reliable.

Any ideas on a better and functional way to get all the text in a screen?

Thans!


Solution

  • Using findElements() to collect the whole UI as MobileElements can be a very heavy process as you've noticed, especially with XPath in use.

    What I would suggest is that you explore what element class types typically (or hopefully only) contain any text contents in the app, and fetch all of those elements via driver.findElements(By.className(""));

    On Android there's a good chance that all the text contents use TextViews: driver.findElements(By.className("android.widget.TextView"));

    On iOS text contents are often found within XCUIElementTypeStaticText driver.findElements(By.className("XCUIElementTypeStaticText"));

    driver.getPageSource() would be the last resort to keep your verification logic efficient. You would in that case send a single request to Appium server and immediately receive all the information you're looking for. Parsing XML isn't heavy to do locally, but does require a bit of effort to implement. To make the driver.getPageSource() call contents reliable, you should probably first assert that the page is fully loaded.