Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

XCUIElement tap() not working

I have a very simple XCTestCase implementation that tests a tap on a button and expects an Alert controller to show up. The problem is that the tap() method doesn't work. Placing a breakpoint in the associated button's IBAction I realise the logic doesn't even get called.

class uitestsampleUITests: XCTestCase {

    var app: XCUIApplication!

    override func setUp() {
        super.setUp()
        continueAfterFailure = false
        app = XCUIApplication()
        app.launch()
    }

    func testButton() {
        let button = app.buttons["Button"]
        button.tap()

        expectationForPredicate(NSPredicate(format: "exists == 1"), evaluatedWithObject: button, handler: nil)
        waitForExpectationsWithTimeout(5.0, handler: nil)
    }
}

Also, duplicating the button.tap() instruction makes the test pass, like this:

    func testButton() {
        let button = app.buttons["Button"]
        button.tap()
        button.tap()

        expectationForPredicate(NSPredicate(format: "exists == 1"), evaluatedWithObject: button, handler: nil)
        waitForExpectationsWithTimeout(5.0, handler: nil)    
    }

I am facing this issue in Xcode 7.3.1 Am I missing something? Is it a bug?

like image 422
Xavi Gil Avatar asked May 17 '16 12:05

Xavi Gil


2 Answers

For UIWebView which is hittable, the tap didn't work until I've done it via coordinate:

extension XCUIElement {
    func forceTap() {
        coordinate(withNormalizedOffset: CGVector(dx:0.5, dy:0.5)).tap()
    }
}

Hope it helps someone

P.S. Also works for items that are not hittable, like labels and such.

like image 114
Alexandre G Avatar answered Sep 30 '22 00:09

Alexandre G


You can wait while the element load, I created this extension:

import XCTest

extension XCUIElement {
    func tap(wait: Int, test: XCTestCase) {
        if !isHittable {
            test.expectation(for: NSPredicate(format: "hittable == true"), evaluatedWith: self, handler: nil)
            test.waitForExpectations(timeout: TimeInterval(wait), handler: nil)
        }
        tap()
    }
}

Use like this:

app.buttons["start"].tap(wait: 20, test: self)
like image 30
Narlei Moreira Avatar answered Sep 29 '22 23:09

Narlei Moreira