Question

I am trying to verify TextView of an app which shows the price of the products listed when a category is searched.

I am using Robotium for automation.

The hierarchy when i get the current view (solo.getCurrentViews(ListView.class)) is something like:

ListView
--> (0)FrameLayout
--> (1)RelativeLayout
         --> (0)ImageView
         --> (1)RelativeLayout
                -->(0)ImageView
                -->(1)TextView    //id - name
                -->(2)TextView    //id - price
                -->(3)TextView    //id - other
--> (2)RelativeLayout
         --> (0)ImageView
         --> (1)RelativeLayout
                -->(0)ImageView
                -->(1)TextView    //id - name
                -->(2)TextView    //id - price
                -->(3)TextView    //id - other

--> (3)RelativeLayout
         --> (0)ImageView
         --> (1)RelativeLayout
                -->(0)ImageView
                -->(1)TextView    //id - name
                -->(2)TextView    //id - price
                -->(3)TextView    //id - other

--> (4)RelativeLayout
         --> (0)ImageView
         --> (1)RelativeLayout
                -->(0)ImageView
                -->(1)TextView    //id - name
                -->(2)TextView    //id - price
                -->(3)TextView    //id - other

--> (5)RelativeLayout
         --> (0)ImageView
         --> (1)RelativeLayout
                -->(0)ImageView
                -->(1)TextView    //id - name
                -->(2)TextView    //id - price
                -->(3)TextView    //id - other

I could figure out two ways of getting the price:

  1. Traverse through children of list view and get to the price via index. Like below code

    int index = 1;
    ListView view = null;
    
    List<ListView> productList = solo.getCurrentViews(ListView.class);
    view = productList.get(0);
    for (int i = 1; i < view.getChildCount(); i++) {
        RelativeLayout relativeLayoutDetails = (RelativeLayout) view.getChildAt(index++);  // get the first RelativeLayout
    
        RelativeLayout productDetails = (RelativeLayout) relativeLayoutDetails.getChildAt(2); //get the inner child RelativeLayout
        TextView productName = (TextView) productDetails.getChildAt(0);
        System.out.println("********" + productDetails.getChildCount());
        TextView price = (TextView) productDetails.getChildAt(2);
        System.out.println(productName.getText().toString() + "---"+ price.getText().toString());
    }
    

The problem with this code is TextView price = (TextView) hotelDetails.getChildAt(2); doesn't give me price but gives me other TextView (Don't know why). Also this works only for current views. I am not able to scroll down the complete list and get details for each and every product.

  1. Second is, getting all the TextViews for current views and filter them based on the price id. Something like below:

    ListView l = (ListView) solo.getView(android.R.id.list); int viewShown = l.getChildCount();

            int total = l.getCount();
    
            int i;
            int index=1;
            if (hotelsShown != 0) {
                for (i = 0; i < total / viewShown; i++) {
    
    
                        List<TextView> textViews = solo.getCurrentViews(TextView.class, l);  //get all the text views
                        //filter for price
                        for(TextView priceView: textViews){
                           if(priceView.id equals "price-id")
                                    //get this TextView.
                        }
    
                    solo.scrollDown();
                    solo.sleep(500);
                }
    

The problem I am facing with this approach is i don't know how do i filter those views based on the ID. Also, while scrolling, this skips one or two products from current views and am not able to fix that.

If someone could suggest something on this, that would be great.

Was it helpful?

Solution

I will refer to one of my earlier answers which you can use to get you a view at the index of a list here.

Once you have this you can combine the function with a new one that get all the child elements of a view:

private List<View> getAllChildren(View v) {

    if (!(v instanceof ViewGroup)) {
        ArrayList<View> viewArrayList = new ArrayList<View>();
        viewArrayList.add(v);
        return viewArrayList;
    }

    ArrayList<View> result = new ArrayList<View>();

    ViewGroup viewGroup = (ViewGroup) v;
    for (int i = 0; i < viewGroup.getChildCount(); i++) {

        View child = viewGroup.getChildAt(i);

        ArrayList<View> viewArrayList = new ArrayList<View>();
        viewArrayList.add(v);
        viewArrayList.addAll(getAllChildren(child));

        result.addAll(viewArrayList);
    }
    return result;
}

and then finally the last one is to filter a list of views by id

public View(List<View> views, int idToMatch) {
    for (View view : views) {
        if (view.getId() == idToMatch) {
            return view;
        }
    }
    return null;
}

You can probably figure out hwo to combine these all into one function that will do what you want nicely. (Hint an R.id.price is an integer so just pass that into the last functon once you have th elist of children at the index you wanted to get)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top