我试图通过点击搜索栏中的“取消”按钮来关闭搜索字段。
测试用例未能找到取消按钮。它在Xcode 7.0.1中运行良好
我添加了谓词等待按钮出现。当我们点击“取消”按钮时,测试用例失败
let button = app.buttons[“Cancel”]
let existsPredicate = NSPredicate(format: "exists == 1")
expectationForPredicate(existsPredicate, evaluatedWithObject: button, handler: nil)
waitForExpectationsWithTimeout(5, handler: nil)
button.tap() // Failing here
日志:
t = 7.21s Tap SearchField
t = 7.21s Wait for app to idle
t = 7.29s Find the SearchField
t = 7.29s Snapshot accessibility hierarchy for com.test.mail
t = 7.49s Find: Descendants matching type SearchField
t = 7.49s Find: Element at index 0
t = 7.49s Wait for app to idle
t = 7.55s Synthesize event
t = 7.84s Wait for app to idle
t = 8.97s Type '[email protected]' into
t = 8.97s Wait for app to idle
t = 9.03s Find the "Search" SearchField
t = 9.03s Snapshot accessibility hierarchy for com.test.mail
t = 9.35s Find: Descendants matching type SearchField
t = 9.35s Find: Element at index 0
t = 9.36s Wait for app to idle
t = 9.42s Synthesize event
t = 10.37s Wait for app to idle
t = 10.44s Check predicate `exists == 1` against object `"Cancel" Button`
t = 10.44s Snapshot accessibility hierarchy for com.test.mail
t = 10.58s Find: Descendants matching type Button
t = 10.58s Find: Elements matching predicate '"Cancel" IN identifiers'
t = 10.58s Tap "Cancel" Button
t = 10.58s Wait for app to idle
t = 10.64s Find the "Cancel" Button
t = 10.64s Snapshot accessibility hierarchy for com.test.mail
t = 10.78s Find: Descendants matching type Button
t = 10.78s Find: Elements matching predicate '"Cancel" IN identifiers'
t = 10.79s Wait for app to idle
t = 11.08s Synthesize event
t = 11.13s Scroll element to visible
t = 11.14s Assertion Failure: UI Testing Failure - Failed to scroll to visible (by AX action) Button 0x7f7fcaebde40: traits: 8589934593, {{353.0, 26.0}, {53.0, 30.0}}, label: 'Cancel', error: Error -25204 performing AXAction 2003
我猜这里的“取消”按钮为false
属性返回hittable
,这是为了防止它被点击。
如果你在文档中看到tap()
它说
/*!
* Sends a tap event to a hittable point computed for the element.
*/
- (void)tap;
似乎XCode 7.1打破了一些事情。为了保持自己(以及你也;))从这些问题中解脱,我在XCUIElement
上写了一个扩展,允许点击元素,即使它不可打击。以下可以帮到你。
/*Sends a tap event to a hittable/unhittable element.*/
extension XCUIElement {
func forceTapElement() {
if self.hittable {
self.tap()
}
else {
let coordinate: XCUICoordinate = self.coordinateWithNormalizedOffset(CGVectorMake(0.0, 0.0))
coordinate.tap()
}
}
}
现在你可以打电话给
button.forceTapElement()
更新 - 对于swift 3使用以下:
extension XCUIElement {
func forceTapElement() {
if self.isHittable {
self.tap()
}
else {
let coordinate: XCUICoordinate = self.coordinate(withNormalizedOffset: CGVector(dx:0.0, dy:0.0))
coordinate.tap()
}
}
}
对我来说,根本原因是我想要点击的对象
在这两种情况下,isAccessibilityElement
属性之后是false
。将它设置回true
修复它。
我发现这个问题是由于XCElement
存在,但隐藏在软件键盘后面。框架发出错误,因为它无法滚动存在于视图中的视图以进行可点击。在我的情况下,有时按钮位于软件键盘后面。
我发现iOS模拟器软件键盘在某些情况下可能会被切换(例如:在您的机器上)并在其他情况下切换(例如:在您的CI上)。在我的情况下,我在一台机器上关闭了软件键盘,默认情况下,它在其他机器上切换。
我发现在敲击按钮之前轻敲某个明确解开键盘的地方解决了我在所有环境中的问题。
我添加了一些操作来让当前的响应者进入resignFirstResponder。我的文本视图背后的视图将强制第一个响应者辞职,所以我点击最后一个文本区域下面的某个地方。
/// The keyboard may be up, dismiss it by tapping just below the password field
let pointBelowPassword = passwordSecureTextField.coordinate(withNormalizedOffset: CGVector(dx: 0.5, dy: 1))
pointBelowPassword.press(forDuration: 0.1)
对于“无法滚动到可见(通过AX操作)按钮”这一术语,Google问题的排名很好。考虑到问题的年龄,我倾向于认为这不再是XCUITest框架的问题,因为已接受的答案表明。一些反复试验引导我进入上面的解决方案。
在我的例子中,它是一个以编程方式添加的UI元素覆盖按钮。
如果您使用AppCenter模拟器运行测试,则应确保在与本地模拟器相同的设备版本上运行测试。因此,我失去了3天的工作。