Search code examples
iosxcodeios13xcuitest

Accessing buttons on a UIActivityViewController in an iOS 13 UI test causes a crash


Is anyone else having problems running Xcode UI tests with Xcode 11 targeting an iOS 13 simulator or device where looking for the buttons on an UIActivityViewController causes a crash?

I have multiple UI tests that verify the buttons that appear in a UIActivityViewController. They do the expected setup work and then look for the button with something like:

XCTAssertTrue(app.buttons["Copy"].exists)

The tests have run fine iOS 10, 11, and 12. If I try to run the same test on an iOS 13 simulator or device, the moment the code attempts to access app.buttons, execution stops and I'll get a Thread 1: signal SIGABRT followed by Failed to get matching snapshots: Lost connection to the application (pid 33047). at the line where I try to access app.buttons.

Adding a wait or even an old-school sleep does nothing. I've tried to dig around some of the other queries hanging off of XCUIElementTypeQueryProvider to find the elements with no luck.

If I debug the test and put a breakpoint before the test accesses app.buttons, and I try to print out what it contains, I get a different error message.

po app.buttons
    t =    49.37s Requesting snapshot of accessibility hierarchy for app with pid 37576
expression produced error: error: /var/folders/f2/zhwz28mn1hd815pc78kg02q80000gp/T/expr5-3b2971..swift:1:72: error: 'XCUIElementQuery' is not a member type of 'XCTest'
Swift._DebuggerSupport.stringForPrintObject(Swift.UnsafePointer<XCTest.XCUIElementQuery>(bitPattern: 0x10c73f4d0)!.pointee)

This sure feels like an Xcode bug. Has anyone else run into this?

Here's a bit of code if anyone else wants to try it out.

From a view controller:

@IBAction func showPressed(_ sender: Any) {
    let text = "I have something to share."

    let vc = UIActivityViewController(activityItems: [text], applicationActivities: nil)
    vc.popoverPresentationController?.sourceView = self.view

    self.present(vc, animated: true, completion: nil)
}

The UI test:

func testActivityViewController() {
    let app = XCUIApplication()
    app.launch()

    app.buttons["Show AVC"].tap()

    let buttons = app.buttons
    let copy = buttons["Copy"]
    sleep(2) // Just keeping things simple for the example.

    XCTAssertTrue(copy.exists)
}

Solution

  • I'm not sure exactly in which version this was fixed, but the UI elements are available in a slightly different configuration as of Xcode version 11.2.1 (11B500). Here's how you might access the Copy button from UIActivityViewController now:

    XCUIApplication().otherElements["ActivityListView"].cells.containing(.label(equals: "Copy")).firstMatch
    

    HT to https://stackoverflow.com/a/48450562/19626 for the otherElements selector.

    The close/cancel button moved, too. Here's where I found it:

    XCUIApplication().otherElements["ActivityListView"].buttons["Close"].tap()