List Item as a page object


#1

'm working with page objects in Appium.

I’ve some view which contains a recyclerview with an items in it.

Each item contain several ui controls (button , image , text , etc …

I was thinking to create a page object which represent an item in the list.

Something like that :

class MainView{
    ....
    AndroidFindBy(...)
    private AndroidElement list;
    }


class Item{
  @AndroidFindBy(....)
  private AndroidElement button;

  @AndroidFindBy(....)
  private AndroidElement text;

  @AndroidFindBy(....)
  private AndroidElement image;

  ...
}

But I had a trouble to connect between the “Item” PO to the list which is in MainView.

Any ideas or what is the best practice to work in such case ?

thanks


#2

@igal_epshtein you should pass your item container as AndroidElement to Item class.


#3

Thank you for the answer.

But I think I didn’t get you :thinking:


#4

@igal_epshtein how we see list:

list container
 item container
  item el1
  item el2
  item el3
 item container
  item el1
  item el2
  item el3
... so on

now lets try it like:

class MyList {
    @HowToUseLocators(androidAutomation = LocatorGroupStrategy.CHAIN)
    @AndroidFindBy(id = "list_container")
    @AndroidFindBy(id = "item_container")
    private List<AndroidElement> myItem;

    public MyList(WebDriver driver) {
        PageFactory.initElements(new AppiumFieldDecorator(driver, 10, SECONDS), this);
    }

    public Item getItem(Integer num) {
        return new Item(myItem.get(num));
    }
}

class Item {
    private AndroidElement el;

    public Item(AndroidElement el) {
        this.el = el;
    }

    public AndroidElement myButton() {
        return (AndroidElement) el.findElement(MobileBy.id("button_id"));
    }

}

    // in code
    MyList myList = new MyList(driver);
    myList.getItem(1).myButton().click();


#5

Ok , so actually you are injecting the AndroidElement into the Item class , but the class is not an Item PO but just simple pojo , am I right ?

If I see it correctly , once you will define the Item as PO , and you need to initialise it , there is no way to tell the scope of the specific item.

Or there is some way to initial a PO in scope of given AndroidElement (el) ?


#6

Yes. Also init needed. Just forgot to add.


#7

Didn’t get you :slight_smile:

Is there a way to build an Item class as a PO ?

the PageFactory.initElements needs a FieldDecorator and an Object .

How do I tell to the PO that the scope is AndroidElement el (in your example) and not the entire view ?


#8

yes. just add Driver variable to MyList class (as usual) (ping me 4h later - will add)


#9

@igal_epshtein code updated


#10

Thanks Aleksei,

I’ve already done it for the list class,
The problem is with the item class, as I don’t want to search for each Itemvs container element separately, but to initialize the all during the PO creation.

The problem is that the page object created in scope of the entire view, so in case I have a button inside item container, and I have 5 containers, the declaration on the button by using find by annotation will always bring me the first button with the specific ID within the view, and not in scope of the container…


#11

@igal_epshtein when some items will not have some elements you will always search for wrong element number. e.g. you want tap on third element button BUT second item does not have button -> this will cause problem.


#12

Eventually the issue was solved with " Widget " appium’s API.

@Aleksei thanks for pointing me to the right place !