Hello
I have a screen witch contain elements, one of these elements is a list
and the list item is contain some elements(strings, images ,)
I want to define the item as a page object using the locaters
I did smth like this
class ScreenPageObject {
@iOSXCUITFindBy(id = "list")
lateinit var list: Items
// initial page object using PageFactory.initElements.......
}
open class Items(element: WebElement) : Widget(element) {
@iOSXCUITFindBy(id = "CellContainer")
lateinit var items: MutableList<Item>
}
open class Item(element: WebElement?) : Widget(element) {
@iOSXCUITFindBy(xpath = "//XCUIElementTypeStaticText[@name=\"TitleLabel\"]")
lateinit var title: MobileElement
}
but I get an error on lateinit property items has not been initialized
thanks…
better use something like:
@iOSXCUITFindBys(value = {
@iOSXCUITBy(id = "list"),
@iOSXCUITBy(id = "CellContainer")
})
@iOSXCUITFindBys(value = {
@iOSXCUITBy(id = "list"),
@iOSXCUITBy(id = "TitleLabel")
})
@Aleksei
the items on the Items class which not initialized
anythings on the items class are not initialized
this line should be in all classes. you have strange a bit page object. normally it looks like:
public class MyPage extends BasePage {
@iOSXCUITFindBy(id = "xxx")
@AndroidFindBy(id = "xxx")
private WebElement mainContainer;
// header
@iOSXCUITFindBy(id = "xxx")
@AndroidFindBy(id = "xxx")
private WebElement backButton;
// body
@iOSXCUITFindBy(id = "xxx")
@AndroidFindBy(id = "xxx")
private WebElement seeCountriesCurrenciesLink;
// ...
// footer
@iOSXCUITFindBy(id = "xxx")
@AndroidFindBy(id = "xxx")
private WebElement autoRenewSubscriptionLink;
public MyPagePage(AppiumDriver driver) {
super(driver);
// where super in base page does init e.g.
// PageFactory.initElements(new AppiumFieldDecorator(driver, Duration.ofSeconds(DEFAULT_WAIT_TIME)), this);
}
@Step("Check 'MyPage' loaded {sec}")
public boolean isLoaded(int sec) {
Logger.log("sec: '" + sec + "'");
setLookTiming(sec);
return super.isLoaded(mainContainer);
}
@Step("Tap 'SeeCountriesCurrencies' link")
public MyOtherPage tapSeeCountriesCurrenciesLink() {
Logger.log();
Assert.assertTrue(tap(seeCountriesCurrenciesLink), createAssertionLog("FAILED"));
return new MyOtherPage(driver);
}
}
just ignore Step annotation from Allure and logs line
yeah I already have the initial line on base class, but I didn’t add it when I copy this code
my question is about the Widget class, how is initialize the elements? should it also have this line PageFactory.initElements…etc??
ok, when I add this
init {
PageFactory.initElements(AppiumFieldDecorator(driver), this)
}
on both Item and Items
the title always is located as the title of first element in the list
do u know why?
what? show pls code and say what you are expecting
here
open class Items(element: WebElement) : Widget(element) {
@iOSXCUITFindBy(id = "CellContainer")
lateinit var items: MutableList<Item>
init {
PageFactory.initElements(AppiumFieldDecorator(driver), this)
}
}
open class Item(element: WebElement?) : Widget(element) {
@iOSXCUITFindBy(xpath = "//XCUIElementTypeStaticText[@name=\"TitleLabel\"]")
lateinit var title: MobileElement
init {
PageFactory.initElements(AppiumFieldDecorator(driver), this)
}
}
the items list on the Items class, all of its items have the same title element and its the first one
I expect that each item should locate its tittle
right?
this is list of elements
this is only one element
“TitleLabel” only in last.
PS I am not sure in your code as far as I am more with Java
Why you need search elements inside classes of some page? Why not define all on one page…
I have example like this
I have a screen having list of components
each component have some component such as title (my project is more complex but I put here a part of it)
ok ok🥲
thank u for ur time