Make XCUIElement perform 3D touch for Automate UITest?

拟墨画扇 提交于 2019-11-30 18:34:57

I was able to execute a force press / 3D Touch on an app icon on an iPhone 7 running iOS 10.3. It was not possible on 10.2.

Objective-C

First you have to declare the following or import this header

typedef void (^CDUnknownBlockType)(void);

@interface XCEventGenerator : NSObject

+ (id)sharedGenerator;

// iOS 10.3 specific
- (double)forcePressAtPoint:(struct CGPoint)arg1 orientation:(long long)arg2 handler:(CDUnknownBlockType)arg3;

@end

And then execute the force press

XCUIElement *element = ...; // Get your element
XCUICoordinate *coord = [mapsIcon coordinateWithNormalizedOffset:CGVectorMake(0.5, 0.5)];

[[XCEventGenerator sharedGenerator] forcePressAtPoint:coord.screenPoint orientation:0 handler:^{}]; // handler cannot be nil

Here I execute a force press on the Maps icons.

Swift (not tested)

For Swift you have to declare/import the same interface/header as above and then execute the force press like this

let el = ...; // Get your element
let coord = el.coordinate(withNormalizedOffset: CGVector(dx: 0.5, dy: 0.5) )
let eventGenerator: XCEventGenerator = XCEventGenerator.sharedGenerator() as! XCEventGenerator

eventGenerator.forcePress(at: coord.screenPoint, orientation: 0) { }

As of Xcode 10 there's no public API to achieve this. However you can use the -[XCUIElement forcePress] private API to simulate a full Peek and Pop interaction. Here's a simple Swift extension that exposes this functionality.

extension XCUIElement {
    func _forcePress() {
        XCTAssert(exists) // Forces the app to idle before interacting
        perform(Selector(("forcePress")))
    }
}

Keep in mind that this is a private API and so may be subject to change/removal in future releases of Xcode. That is, your tests may start crashing when running with a different Xcode version.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!