Reputation: 1759
I am trying to dismiss the search field by tapping 'Cancel' button in search bar.
The test case is failing to find the cancel button. It was working fine in Xcode 7.0.1
I have added predicate to wait for button to appear. The test case is failing when we tap of "cancel" button
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
logs:
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
Upvotes: 110
Views: 38148
Reputation: 1332
I had this issue because I set a toolbar
(and ToolbarItem
) on a GeometryReader
:
GeometryReader { proxy in
ZStack { ... }
}
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
Button(action: { ... }) {
Text(Localizable.Global.login.localized)
}
.accessibilityIdentifier("welcomeViewLoginButton")
}
}
After setting the toolbar on the ZStack
instead, the toolbar item button was hittable again.
GeometryReader { proxy in
ZStack {
...
}
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
Button(action: { ... }) {
Text(Localizable.Global.login.localized)
}
.accessibilityIdentifier("welcomeViewLoginButton")
}
}
}
Upvotes: 0
Reputation: 3131
I guess here "Cancel" button returns false
for hittable
property, that is preventing it from tapping.
If you see tap()
in documentation it says
/*!
* Sends a tap event to a hittable point computed for the element.
*/
- (void)tap;
It seems things are broken with Xcode 7.1. To keep myself (and you too ;)) unblocked from these issues I wrote an extension on XCUIElement
that allows tap on an element even if it is not hittable. Following can help you.
/*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()
}
}
}
Now you can call as
button.forceTapElement()
Update - For Swift 3 use the following:
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()
}
}
}
Upvotes: 176
Reputation: 1279
Try this:
if !button.isHittable {
let coordinate: XCUICoordinate = button.coordinate(withNormalizedOffset: CGVector(dx:0.0, dy:0.0))
coordinate.tap()
}
Upvotes: 1
Reputation: 44459
In the spirit of things that can cover your element, I had the RN debugger partially overlayed on top of my icon:
Upvotes: 0
Reputation: 41
The workaround of Sandy seemed help for a while but then no more - I then changed it like this:
func waitAndForceTap(timeout: UInt32 = 5000) {
XCTAssert(waitForElement(timeout: timeout))
coordinate(withNormalizedOffset: CGVector(dx:0.5, dy:0.5)).tap()
}
Main point being that as the issue is that isHittable check throws an exception, I don't do this check at all and go straight for coordinates after the element is found.
Upvotes: 4
Reputation: 12460
This question ranks well for Google queries around the term "Failed to scroll to visible (by AX action) Button". Given the age of the question I was inclined to think this was no longer an issue with the XCUITest framework as the accepted answer suggests.
I found this issue was due to the XCElement
existing, but being hidden behind the software keyboard. The error is emitted by the framework since it is unable to scroll a view that exists into view to be tappable. In my case the button in question was behind the software keyboard sometimes.
I found the iOS Simulator's software keyboard may be toggled off in some cases (eg: on your machine) and toggled on in others (eg: on your CI). In my case I had toggled the software keyboard off on one machine, and by default it was toggled on on others.
I found tapping somewhere that explicitly dismissed the keyboard before tapping on the button solved my problem in all environments.
I added add some actions to get the current responder to resignFirstResponder. The views behind my text views will force the first responder to resign, so I tap somewhere just underneath the last text area.
/// 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)
Upvotes: 8
Reputation: 11
If you're using the AppCenter simulator to run the tests, you should make sure that you're running the tests on the same device version than your local simulator. I lost 3 days of work because of this.
Upvotes: 0
Reputation: 6384
In my case it was having a programmatically added UI element covering the button.
Upvotes: 0
Reputation: 802
Please check the trait of the element, i was facing the same issue with TableViewSectionHeader, i was trying to tap but it was failing at every point
Upvotes: 2
Reputation: 6387
For me, the root cause was that the objects I wanted to tap
In both cases the isAccessibilityElement
property was false
afterwards. Setting it back to true
fixed it.
Upvotes: 14