2016-11-12 62 views
3

在Xcode 8/Swift 3中,使用坐标(withNormalizedOffset:CGVector)函数与XCUIElement交互似乎只能在纵向模式下工作。无法在横向模式下点击(x,y)坐标

为了测试此功能,我创建了一个屏幕项目,并在视图中居中放置了一个按钮。然后我运行以下UI测试:

func testExample() { 

    XCUIDevice.shared().orientation = .portrait 

    let window = XCUIApplication().windows.element(boundBy: 0) 

    let centerPoint = window.coordinate(withNormalizedOffset: CGVector(dx: 0.5, dy: 0.5)) 

    centerPoint.tap() 
} 

这成功点击按钮。但是,如果我在landscapeLeft或landscapeRight中运行相同的测试,则不会轻敲该按钮。打印坐标的屏幕显示,它位于按钮框架的纵向和横向模式中。

相同的逻辑是成功的在Xcode 7 /斯威夫特2所有方向:

func testExample() { 

    XCUIDevice.sharedDevice().orientation = .LandscapeLeft 

    let window = XCUIApplication().windows.elementBoundByIndex(0) 

    let centerPoint = window.coordinateWithNormalizedOffset(CGVectorMake(0.5, 0.5)) 

    centerPoint.tap() 
} 

我失去了一些东西,或者这是一个合法的框架的错误?它与Swift 2中的CGVectorMake到Swift 3中的CGVector(dx:dy :)有什么关系?

+0

在这一点上,我相信这是一个框架的bug。向苹果提交了一份报告。 – tedrothrock

回答

3

同样的问题 - 屏幕点是正确的,但实际的手势坐标是混乱的。这种解决方法奏效了我:

class SmartXCUICoordinate 
{ 
    let element: XCUIElement 
    let normalizedOffset: CGVector 

    init(element: XCUIElement, normalizedOffset offset: CGVector) { 
     self.element = element 
     self.normalizedOffset = offset 
    } 

    var realCoordinate: XCUICoordinate { 
     guard XCUIDevice.shared().orientation.isLandscape else { 
      return element.coordinate(withNormalizedOffset: normalizedOffset) 
     } 

     let app = XCUIApplication() 
     _ = app.isHittable // force new UI hierarchy snapshot 

     let screenPoint = element.coordinate(withNormalizedOffset: normalizedOffset).screenPoint 

     let portraitScreenPoint = XCUIDevice.shared().orientation == .landscapeLeft 
      ? CGVector(dx: app.frame.width - screenPoint.y, dy: screenPoint.x) 
      : CGVector(dx: screenPoint.y, dy: app.frame.height - screenPoint.x) 

     return app 
      .coordinate(withNormalizedOffset: CGVector.zero) 
      .withOffset(portraitScreenPoint) 
    } 

    func tap() { 
     realCoordinate.tap() // wrap other XCUICoordinate methods as needed 
    } 
} 

extension XCUIElement 
{ 
    func smartCoordinate(withNormalizedOffset normalizedOffset: CGVector) -> SmartXCUICoordinate { 
     return SmartXCUICoordinate(element: self, normalizedOffset: normalizedOffset) 
    } 
} 

已知问题:不会为您的应用程序不支持方向都能正常运作。

+0

优秀的解决方法,谢谢! – tedrothrock

0

优秀的答案。 我有相同的坐标问题测试一个[Xcode 8 Swift 3] SpriteKit风景模式的应用程序,我最初错误地指出SpriteKit。 SmartXCUICoordinate让我重新走上正轨。

我添加了两个方法,您的评论 //下包装其他XCUICoordinate方法需要

//support UILongPressGestureRecognizer 
func longPress(){ 
    realCoordinate.press(forDuration: 2.25) 
} 
//support drag an element to a second element 
//For SpriteKit this drags one SKNode to a second SKNode) 
func pressThenDragTo(element: XCUIElement){ 
    realCoordinate.press(forDuration: 0.1, thenDragTo: element.smartCoordinate(withNormalizedOffset: CGVector(dx: 0.5, dy: 0.5)).realCoordinate) 
}