如何在 react-native detox 中按祖先索引匹配元素

Posted

技术标签:

【中文标题】如何在 react-native detox 中按祖先索引匹配元素【英文标题】:How to match element by ancestor index in react-native detox 【发布时间】:2021-11-03 19:12:47 【问题描述】:

我正在尝试遵循 react-native detox 的个人模式,其中包括如下内容:


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')

并在我的测试中像这样使用它:


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))

这种方法的问题在于,当一个元素是可选的(如date)时,给定的索引将无法正确匹配,因为 detox 将匹配器读取为:

将元素Y IDX 与祖先X

而不是

IDX 获取祖先X 并找到ID 为Y 的孩子

所以我的问题是:

有没有办法告诉 detox 先在IDX 搜索祖先,然后才找到匹配的子代?

类似这样的:

element(by.id(X).withAncestor(by.id(Y).atIndex(0))

注意:我知道我可以将可选字段 getter 转换为方法并覆盖索引,但阅读它会令人困惑,因为我之前已经指定了 ''ancestor'' 索引

【问题讨论】:

【参考方案1】:

Detox matchers 与您尝试使用它们的方式不同。如文档中所述:

Detox 使用匹配器来匹配应用中的 UI 元素。

它们不适用于树遍历以提取元素。匹配器为您提供一组匹配特定条件的元素。 atIndex 匹配器允许您指定在匹配器返回多个 UI 元素时选择哪个元素。 所以,你的例子

element(by.id(X).withAncestor(by.id(Y).atIndex(0))

应该理解为:找到所有 id 为 X 的 UI 元素元素,然后只保留祖先为 id 为 Y 的元素,并在其余元素中选择索引为 0 的元素。

文档强调了 atIndex 匹配器的一些问题,所以我建议不要使用它:

由于 iosandroid 上 Detox 的底层实现不同,以及操作系统实现的其他差异,以及每个操作系统上的 RN 实现差异,iOS 和 Android 之间的索引可能不匹配。随着应用程序用户界面的更新,依赖索引也可能会在测试中引入不稳定因素。建议为您的元素使用唯一标识符匹配器。

【讨论】:

哦,所以推荐的方法是使用唯一标识符...所以如果我使用由索引组成的 id,它可能会起作用 - 这也是推荐的方法。无论如何,感谢您抽出宝贵时间用详细信息回答我的问题!

以上是关于如何在 react-native detox 中按祖先索引匹配元素的主要内容,如果未能解决你的问题,请参考以下文章

Detox E2E 测试不会在 react-native 项目上运行

React-Native 和 Detox:无法关闭位置弹出窗口

React-Native 日历议程没有用于 Detox 的 testID

在 React-Native/Expo 移动应用程序上设置 Detox 时出错:“ReferenceError: element is not defined”

Detox react-native build 成功,“Detox 似乎无法连接到测试应用程序!” (iOS)

获取 ReferenceError:在 react-native ios 上运行 detox 测试时未定义设备