Hi I am writing some UI Test cases using XCTest for my iOS app and I am facing some issues because the property isHittable
and the tap
method both of them don't work as expected in the following case:
I have a button on a fixed position on all the app screens (floating button) with accessibilityElementsHidden
set to true, and another button which might be below the floating one on some devices, isHittable
property for the button below the floating button returns true which i think is not right because the button is not hittable, and when I try to tap on that button using tap
method the button on the top receives the event instead of the button I targeted.
we can reproduce the issue by running the following test case for the following viewController:
final class TestUITests: XCTestCase {
func testExample() throws {
let app = XCUIApplication()
app.launch()
let button = app.buttons.matching(identifier: "button1").firstMatch
XCTAssertTrue(button.waitForExistence(timeout: 10))
XCTAssertTrue(button.isHittable)
button.tap()
}
}
class ViewController: UIViewController {
var button1: UIButton!
var topButton: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
button1 = UIButton()
button1.backgroundColor = .blue
button1.setTitle("button 1", for: .normal)
button1.accessibilityIdentifier = "button1"
button1.backgroundColor = .red
addButtonToCenter(button: button1)
button1.addTarget(self, action: #selector(didClickOnButton1), for: .touchUpInside)
topButton = UIButton()
topButton.setTitle("top Button", for: .normal)
topButton.backgroundColor = .blue
topButton.addTarget(self, action: #selector(didClickOnTopButton), for: .touchUpInside)
topButton.accessibilityElementsHidden = true
addButtonToCenter(button: topButton)
}
@objc func didClickOnTopButton(_ sender: UIButton) {
assertionFailure("unexepected call")
}
@objc func didClickOnButton1(_ sender: UIButton) {
}
func addButtonToCenter(button: UIButton) {
view.addSubview(button)
button.translatesAutoresizingMaskIntoConstraints = false
let horizontalConstraint = NSLayoutConstraint(item: button, attribute: NSLayoutConstraint.Attribute.centerX, relatedBy: NSLayoutConstraint.Relation.equal, toItem: view, attribute: NSLayoutConstraint.Attribute.centerX, multiplier: 1, constant: 0)
let verticalConstraint = NSLayoutConstraint(item: button, attribute: NSLayoutConstraint.Attribute.centerY, relatedBy: NSLayoutConstraint.Relation.equal, toItem: view, attribute: NSLayoutConstraint.Attribute.centerY, multiplier: 1, constant: 0)
let widthConstraint = NSLayoutConstraint(item: button, attribute: NSLayoutConstraint.Attribute.width, relatedBy: NSLayoutConstraint.Relation.equal, toItem: nil, attribute: NSLayoutConstraint.Attribute.notAnAttribute, multiplier: 1, constant: 100)
let heightConstraint = NSLayoutConstraint(item: button, attribute: NSLayoutConstraint.Attribute.height, relatedBy: NSLayoutConstraint.Relation.equal, toItem: nil, attribute: NSLayoutConstraint.Attribute.notAnAttribute, multiplier: 1, constant: 100)
view.addConstraints([horizontalConstraint, verticalConstraint, widthConstraint, heightConstraint])
}
}