无法在横向模式下点击 (x,y) 坐标
Unable to tap (x,y) coordinate in landscape mode
在Xcode 8 / Swift 3中,使用坐标(withNormalizedOffset: CGVector)函数与XC交互UIElement似乎只能在纵向模式下工作。
为了测试此功能,我创建了一个单屏项目,其中一个按钮位于视图的中央。然后我 运行 下面 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 / Swift 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:) 的 t运行sition 有什么关系吗?
同样的问题——屏幕点是正确的,但实际的手势坐标是乱七八糟的。这个解决方法对我有用:
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)
}
}
已知问题: 不适用于您的应用不支持的方向。
很好的回答。
我在测试 [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)
}
在Xcode 8 / Swift 3中,使用坐标(withNormalizedOffset: CGVector)函数与XC交互UIElement似乎只能在纵向模式下工作。
为了测试此功能,我创建了一个单屏项目,其中一个按钮位于视图的中央。然后我 运行 下面 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 / Swift 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:) 的 t运行sition 有什么关系吗?
同样的问题——屏幕点是正确的,但实际的手势坐标是乱七八糟的。这个解决方法对我有用:
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)
}
}
已知问题: 不适用于您的应用不支持的方向。
很好的回答。 我在测试 [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)
}