8

我有一个带有 Today Widget 的应用程序。所以我想对其进行一些 UI 测试。

我找到了一种打开今日/通知面板的方法。这似乎很容易:

let statusBar = XCUIApplication().statusBars.elementBoundByIndex(0)
statusBar.swipeDown()

但是后来我找不到一种方法来做一些有用的事情。可以在 Today/Notifications 面板中记录 UI 交互,但这样的代码无法重现我的操作。

4

2 回答 2

6

首先你需要打开今日视图,你可以这样使用:

    let app = XCUIApplication()
    // Open Notification Center
    let bottomPoint = app.coordinate(withNormalizedOffset: CGVector(dx: 0, dy: 2))
    app.coordinate(withNormalizedOffset: CGVector(dx: 0, dy: 0)).press(forDuration: 0.1, thenDragTo: bottomPoint)
    // Open Today View
    let springboard = XCUIApplication(bundleIdentifier: "com.apple.springboard")
    springboard.scrollViews.firstMatch.swipeRight()

然后,要访问您需要的一切,只需使用springboard,例如:

let editButton = springboard.buttons["Edit"]
于 2018-03-22T09:52:46.130 回答
4

有一个类似的问题测试扩展。我发现你必须做的是点击元素在屏幕上的位置而不是元素本身来驱动交互。我还没有在你的场景中测试过这个,但是我还没有发现任何无法通过这种方法开发的东西。

这是一个在 Springboard 上点击“X”按钮以获取应用程序图标的 Swift 示例,同样无法通过典型交互点击该按钮:

let iconFrame = icon.frame // App icon on the springboard
let springboardFrame = springboard.frame // The springboard (homescreen)
icon.pressForDuration(1.3) // tap and hold

// Tap the little "X" button at approximately where it is. The X is not exposed directly
springboard.coordinateWithNormalizedOffset(CGVectorMake((iconFrame.minX + 3) / springboardFrame.maxX, (iconFrame.minY + 3) / springboardFrame.maxY)).tap()

通过获取父视图和子视图的框架,您可以计算元素应该在屏幕上的哪个位置。请注意,它coordinateWithNormalizedOffset采用 [0,1] 范围内的向量,而不是帧或像素偏移量。在坐标处点击元素本身也不起作用,因此您必须在 superview / XCUIApplication() 层点击。

更普遍的例子:

let myElementFrame = myElement.frame
let appFrame = XCUIApplication().frame
let middleOfElementVector = CGVectorMake(iconFrame.midX / appFrame.maxX, iconFrame.midY / appFrame.maxY)

// Tap element from the app-level at the given coordinate
XCUIApplication().coordinateWithNormalizedOffset(middleOfElementVector).tap()

如果您需要访问 Springboard 层并离开您的应用程序,您可以这样做:

let springboard = XCUIApplication(privateWithPath: nil, bundleID: "com.apple.springboard")
springboard.resolve()

但是您需要使用 Objective-C 公开一些私有 XCUITest 方法:

@interface XCUIApplication (Private) {
    - (id)initPrivateWithPath:(id)arg1 bundleID:(id)arg2;
}

@interface XCUIElement (Private) {
    - (void) resolve;
}
于 2016-05-24T18:47:55.390 回答