在 iOS 上的点击行为与 disableSynchroniztion 不一致

Posted

技术标签:

【中文标题】在 iOS 上的点击行为与 disableSynchroniztion 不一致【英文标题】:tap behaviour not consistent on iOS with disableSynchroniztion 【发布时间】:2019-11-13 09:52:39 【问题描述】:

我有一个使用 WebView 登录应用程序的测试(通过使用带有按钮 + injectedjavascript 的文本输入以不支持 WebView 检测的方式完成)。

问题出现是因为WebView内部的登录操作是异步发生的,破坏了Detox同步,所以我必须自己手动管理disableSynchronizationenableSynchronization。 登录后,我有一个堆栈转换动画到一个新屏幕(来自 react-navigation),我需要按下该屏幕上的一个按钮才能走得更远。但是 Detox 仍然无法与该屏幕同步,所以我正在使用点击按钮按下禁用同步的按钮。

这就是问题发生的地方,点击并不总是有效,并且在 50% 的时间里,在disableSynchronization 调用之后执行的任何操作都会超时而失败。这使得测试变得不稳定并且几乎毫无用处

谁能推荐一个解决方法或知道问题出在哪里?

环境 排毒:12.10.3。 反应原生:0.59.8 节点:v11.7.0 设备:ios模拟器(iPhone 8) 操作系统:iOS

我尝试在点击按钮之前和之后禁用和启用同步,但没有帮助,实际上导致测试因超时而失败。

我的登录方法代码:

export const loginAs = async (userID) => 
  await element(by.id('introLoginBtn')).tap();
  await expect(element(by.id('loginScreen'))).toBeVisible();

  const userIdInput = element(by.id('testUserIdInput'));
  await userIdInput.tap();
  await userIdInput.typeText(userID);
  await element(by.id('testLoginBtn')).tap();

  // NOTE: WebView login breaks synchronization see 
  // https://github.com/wix/Detox/blob/master/docs/Troubleshooting.Synchronization.md
  await device.disableSynchronization();

  // Waiting for the element to be visible
  await waitFor(element(by.id('acceptTermsBtn'))).toBeVisible().withTimeout(9000);

  // This does not work consistently
  await element(by.id('acceptTermsBtn')).tap();

  await device.enableSynchronization();
;

当我使用--debug-synchronization 200 进入调试控制台时:

detox[33941] INFO:  [actions.js] Sync Timer: Tracking Timer <__NSCFTimer: 0x600003e6de00>
detox[33941] INFO:  [actions.js] Sync Timed: performSelector @selector(removeInactiveFingerTips) on DTXTouchVisualizerWindow
detox[33941] INFO:  [actions.js] Sync Timed: animateWithDuration:delay:options:animations:completion:
detox[33941] INFO:  [actions.js] Sync JavaScript Timers: Javascript Timers
detox[33941] INFO:  [actions.js] Sync App State: undefined
detox[33941] INFO:  [actions.js] Sync Dispatch Queue: com.apple.main-thread
detox[33941] INFO:  [actions.js] Sync Timed: performSelector @selector(removeFromSuperview) on COSTouchSpotView
detox[33941] INFO:  [actions.js] Sync Timed: animateWithDuration:delay:options:animations:completion:
detox[33941] INFO:  [actions.js] Sync Timed: performSelector @selector(removeInactiveFingerTips) on DTXTouchVisualizerWindow
detox[33941] INFO:  [actions.js] Sync Timed: animateWithDuration:delay:options:animations:completion:
detox[33941] INFO:  [actions.js] Sync JavaScript Timers: Javascript Timers
detox[33941] INFO:  [actions.js] Sync App State: undefined
detox[33941] INFO:  [actions.js] Sync Dispatch Queue: com.apple.main-thread
detox[33941] INFO:  [actions.js] Sync Timed: performSelector @selector(removeInactiveFingerTips) on DTXTouchVisualizerWindow
detox[33941] INFO:  [actions.js] Sync Timed: performSelector @selector(removeFromSuperview) on COSTouchSpotView
detox[33941] INFO:  [actions.js] Sync Timed: animateWithDuration:delay:options:animations:completion:
detox[33941] INFO:  [actions.js] Sync JavaScript Timers: Javascript Timers
detox[33941] INFO:  [actions.js] Sync App State: undefined
detox[33941] INFO:  [actions.js] Sync Dispatch Queue: com.apple.main-thread
detox[33941] INFO:  [actions.js] Sync Timed: performSelector @selector(removeInactiveFingerTips) on DTXTouchVisualizerWindow
detox[33941] INFO:  [actions.js] Sync Timed: performSelector @selector(removeFromSuperview) on COSTouchSpotView
detox[33941] INFO:  [actions.js] Sync WXAnimatedDisplayLinkIdlingResource: undefined
detox[33941] INFO:  [actions.js] Sync App State: undefined
detox[33941] INFO:  [actions.js] Sync Dispatch Queue: com.apple.main-thread
detox[33941] INFO:  [actions.js] Sync Timed: performSelector @selector(removeInactiveFingerTips) on DTXTouchVisualizerWindow
detox[33941] INFO:  [actions.js] Sync WXAnimatedDisplayLinkIdlingResource: undefined
detox[33941] INFO:  [actions.js] Sync Dispatch Queue: com.apple.main-thread
detox[33941] INFO:  [actions.js] Sync WXAnimatedDisplayLinkIdlingResource: undefined
detox[33941] INFO:  [actions.js] Sync Dispatch Queue: com.apple.main-thread
detox[33941] INFO:  [actions.js] Sync JavaScript Timers: Javascript Timers
detox[33941] INFO:  [actions.js] Sync Dispatch Queue: com.apple.main-thread
detox[33941] INFO:  [actions.js] Sync JavaScript Timers: Javascript Timers
detox[33941] INFO:  [actions.js] Sync Dispatch Queue: com.apple.main-thread
detox[33941] INFO:  [actions.js] Sync JavaScript Timers: Javascript Timers
detox[33941] INFO:  [actions.js] Sync Dispatch Queue: com.apple.main-thread
detox[33941] INFO:  [actions.js] Sync JavaScript Timers: Javascript Timers

最后 3 行重复直到测试超时。

在使用launchArgs: 'detoxPrintBusyIdleResources': 'YES' 启动并运行xcrun simctl spawn booted log stream --level debug --style compact --predicate "category=='EarlGreyStatistics'" 之后:

Error from getpwuid_r: 0 (Undefined error: 0)
Filtering the log data using "category == "EarlGreyStatistics""

【问题讨论】:

你有什么理由禁用同步? 我有一个测试,它使用脚本注入绕过发生在 WebView 内的登录步骤。之后,我触发到本机屏幕的导航操作,但匹配器无法在其上找到任何元素,除非我禁用同步。然后他们可以,但它很不稳定,并且在 50% 的时间里会因为在同步调度循环中超时而失败。 将代码注入 Web 视图不需要禁用同步。如果您看到一个循环,则表示您的应用程序正忙。无论如何,当您尝试点击按钮时,错误会告诉您什么? 没有错误,只是测试超时。如果我更改我的应用程序并导航到另一个堆栈导航器中的屏幕(来自 react-navigation),同步问题就会消失。 您可以启用各种同步调试功能来帮助您。这就是我所说的“错误”。 【参考方案1】:

我遇到的问题确实是由Leo Nathan 提到的无限循环中运行的动画引起的。

我有一个屏幕安装在来自react-navigation 的堆栈导航器中的当前屏幕下方。使用reset 卸载堆栈(以及无休止的动画屏幕)解决了这个问题。

【讨论】:

你在哪里/怎么做的reset 我正在使用 react-navigation',所以在导航卸载当前屏幕(不断动画)时我调用 navigation.reset()

以上是关于在 iOS 上的点击行为与 disableSynchroniztion 不一致的主要内容,如果未能解决你的问题,请参考以下文章

由 xcode 4.6 与 xcode 5.0 创建时,iOS 应用程序在 iOS 7.0 设备上的行为不同

iOS状态栏点击上的Javascript事件

(iOS,Xcode)有没有办法覆盖“点击状态栏向上滚动”行为?

带有波纹动画的 ng-click 在 Safari iOS 上的点击功能与在 PC 上的点击不同

如何通过与 swift/xctest 协调来点击 iOS 主屏幕上的某个点

strcpy 在 ios7 上的行为不同