如何找到(使用XCTest UITest)在tvOS AppleTV的表格视图中具有焦点的单元格?

时间:2016-05-26 16:47:44

标签: xcode swift tvos xctest xcode-ui-testing

我试图在Apple TV(tvOS)上自动执行应用程序的UI测试。

在登录屏幕上,我选择'输入用户名'领域。然后出现具有先前使用的登录的屏幕。在屏幕上,我想选择“清除所有内容”。细胞

澄清:"以前用过的"菜单似乎是内置于tvOS中的,当有人在登录菜单中选择用户名文本字段时,它可能会自动出现。我对此不确定,所以我仍需要确认这些信息。

enter image description here

所以我认为像这样的代码是一个解决方案:

    if self.app.staticTexts["Previously Used"].exists {

        let clearAllCell = self.app.cells.staticTexts["Clear All"]

        while clearAllCell.hasFocus == false {
            XCUIRemote.sharedRemote().pressButton(.Down)
            sleep(1)
        }

        XCUIRemote.sharedRemote().pressButton(.Select)
    }

然而即使在这样的状态:

enter image description here

单元格的属性hasFocusselected似乎返回false:

po self.app.cells.staticTexts["Clear All"].hasFocus
po self.app.cells.staticTexts["Clear All"].selected

enter image description here

如何找到"全部清除"当它具有聚焦状态"?

更新:

我已经尝试过@Oletha提出的解决方案,但没有成功。遗憾的是,clearAllCell.hasFocus似乎总是错误的。

    if self.app.staticTexts["Previously Used"].exists {

        let clearAllCell = self.app.cells.staticTexts["Clear All"]

        let predicateHasFocus = NSPredicate(format: "exists == true", argumentArray: nil)

        expectationForPredicate(predicateHasFocus, evaluatedWithObject: clearAllCell, handler: { () -> Bool in
            if clearAllCell.hasFocus {
                return true
            } else {
                sleep(1)
                XCUIRemote.sharedRemote().pressButton(.Down)
                return false
            }
        })

        waitForExpectationsWithTimeout(10, handler: nil)

        XCUIRemote.sharedRemote().pressButton(.Select)
    }

更新:

目前一个不优雅的解决方案是:

    if self.app.staticTexts["Previously Used"].exists {
        var cellsCount = self.app.cells.count

        // Select Clear All menu button, hack as it was not possible to detect "Clear All" cell in another way
        while cellsCount > 0 {
            sleep(1)
            XCUIRemote.sharedRemote().pressButton(.Down)
            cellsCount -= 1
        }

        sleep(1)
        XCUIRemote.sharedRemote().pressButton(.Up)
        sleep(1)
        XCUIRemote.sharedRemote().pressButton(.Select)
    }

3 个答案:

答案 0 :(得分:1)

我的应用程序遇到了类似的问题,发现有两件事有助于编写运行的UI测试:

  1. 每次按下远程按钮后总是延迟1秒,因为断言评估通常比焦点更改快,因此返回false

    XCUIRemote.sharedRemote().pressButton(.Down)
    sleep(1)
    
  2. 查找焦点元素的确切UI层次结构位置。例如,print(XCUIApplication().debugDescription)将为您提供详细的用户界面树,以便您正确访问元素。

  3. enter image description here

    此断言已返回true:

        XCTAssert(XCUIApplication().tabBars.buttons["Home"].hasFocus)
    

答案 1 :(得分:0)

使用expectationForPredicatewaitForExpectationsWithTimeout检查单元格是否具有焦点。使用期望会导致每次检查发生时刷新可访问性层次结构快照。您的while循环每次都会检查相同的缓存层次结构快照,因此结果不会更改。

let app = XCUIApplication()
let clearAllCell = app.cells.staticTexts["Clear All"]
let focusedPredicate = NSPredicate(format: "exists == true")
let remote = XCUIRemote.sharedRemote()

expectationForPredicate(focusedPredicate, evaluatedWithObject: clearAllCell, handler: {() -> Bool in
    // Check if the cell has focus
    if clearAllCell.hasFocus {
        // Fulfill the expectation
        return true
    } else {
        // Move down one cell before the next check
        remote.pressButton(.Down)
        return false
    }
})
waitForExpectationsWithTimeout(5, handler: nil)

remote.pressButton(.Select)

XCUIRemote.sharedRemote()实际上对我不起作用,但我猜这对你有用 - 我没有Apple TV应用程序可供测试。

答案 2 :(得分:0)

首先,它是tvOS中的原生屏幕所以与try和set accessibility id相关的所有建议都不相关。当你到达那个屏幕并打印出哪个元素聚焦时,尝试设置一个断点

我相信答案会是。屏幕上的位置。或没有标识符的单元格我在Apple TV上遇到同样的问题,想知道你遇到的所有问题,因为我想知道tvOS的xcuitest是多么成熟