XCUITest 和今日小部件

Posted

技术标签:

【中文标题】XCUITest 和今日小部件【英文标题】:XCUITest and Today Widget 【发布时间】:2016-03-30 11:47:25 【问题描述】:

我有一个带有今日小部件的应用程序。所以我想对其进行一些 UI 测试。

我找到了一种打开今日/通知面板的方法。看起来很简单:

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

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

【问题讨论】:

【参考方案1】:

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

    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"]

【讨论】:

我过去曾用它取得了巨大的成功,但在 ios 13 上它不再有效:​​( 除了 iPhone 11 Pro Max 以外的任何地方都适用于我。由于某些未知原因,它不想向右滑动。超级困惑...【参考方案2】:

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

这是一个在 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()

通过获取superview和subview的frame,你可以计算出元素应该在屏幕上的什么位置。请注意,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;

【讨论】:

以上是关于XCUITest 和今日小部件的主要内容,如果未能解决你的问题,请参考以下文章

iOS 8 今日小部件 - UIAlertView

今日 iOS 小部件仅在调试时显示

通过应用内购买启用今日视图小部件

带有参数的今日小部件 openurl

如何在通知中心频繁更新今日小部件?

Xamarin-iOS今日小部件,无法加载问题