Issue #583

In UITests, we can use press from XCUIElement to test drag and drop

let fromCat = app.buttons["cat1"].firstMatch
let toCat = app.buttons["cat2"]
let fromCoordinate = fromCat.coordinate(withNormalizedOffset: CGVector(dx: 0, dy: 0))
let toCoordinate = toCat.coordinate(withNormalizedOffset: CGVector(dx: 0, dy: -0.5))
fromCoordinate.press(forDuration: 1, thenDragTo: toCoordinate)

and then take screenshot

let screenshot = XCUIScreen.main.screenshot()
let attachment = XCTAttachment(screenshot: screenshot)
attachment.lifetime = .keepAlways
attachment.name = name
add(attachment)

Screenshot capturing happens after the action, so it may be too late. One way is to inject launch arguments, like app.launchArguments.append("--dragdrop") to alter some code in the app.

We can also swizzle gesture recognizer to alter behavior

extension UILongPressGestureRecognizer {
    @objc var uiTests_state: UIGestureRecognizer.State {
        let state = self.uiTests_state
        if state == .ended {
            return .changed
        } else {
            return state
        }
    }
}

let originalSelector = #selector(getter: UILongPressGestureRecognizer.state)
let swizzledSelector = #selector(getter: UILongPressGestureRecognizer.uiTests_state)

let originalMethod = class_getInstanceMethod(UILongPressGestureRecognizer.self, originalSelector)!
let swizzledMethod = class_getInstanceMethod(UILongPressGestureRecognizer.self, swizzledSelector)!

let didAddMethod = class_addMethod(UILongPressGestureRecognizer.self, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod))

if didAddMethod {
    class_replaceMethod(UILongPressGestureRecognizer.self, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod))
} else {
    method_exchangeImplementations(originalMethod, swizzledMethod)
}