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

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

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

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

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

【问题讨论】:

    标签: ios xcode-ui-testing ios8-today-widget today-extension ios9-today-widget


    【解决方案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;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-10-15
      • 1970-01-01
      • 1970-01-01
      • 2017-03-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多