In UITests, we can use press from XCUIElement to test drag and drop
1 2 3 4 5
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
1 2 3 4 5
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
extensionUILongPressGestureRecognizer{ @objcvar 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))