2016-11-12 64 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) 
}