I'm trying to follow a personal pattern for react-native detox, which consist of something like this:
export const noteCardDescriptor = (baseID: string) => (index: number) => {
return {
get element() {
return element(by.id(baseID)).atIndex(index);
},
get title() {
return element(
by.id('NoteCardTitle').withAncestor(by.id(baseID)),
).atIndex(index);
},
get date {
return element(by.id('NoteCardDate').withAncestor(by.id(baseID))).atIndex(
index,
);
},
};
};
class MyScreen {
static note = noteCardDescriptor('MyScreenNoteCard')
}
And using it in my tests like this:
const noteOne = MyScreen.note(0)
await expect(noteOne.title).toHaveText('Hello there')
await expect(noteOne.date).toNotBeVisible()
const noteTwo = MyScreen.note(1)
await expect(noteTwo.title).toHaveText('Hello there')
await expect(noteTwo.date).toHaveText(formatDate(date))
The problem with this approach is that when an element is optional (like date
), the given index will fail to match properly because detox reads the matcher as:
- take element
Y
atIDX
with ancestorX
instead of
- take ancestor
X
atIDX
and find child with idY
so my question is:
Is there any way to tell detox to search first for a ancestor at IDX
and only then find childrens for matches?
Something like this:
element(by.id(X).withAncestor(by.id(Y).atIndex(0))
Note: I know I can transform the optional field getter into a method and override the index, but reading it is confusing since I've already specified the ''ancestor'' index previously