如何找出(使用 XCTest UITest)在 tvOS AppleTV 的表格视图中具有焦点的单元格?
Posted
技术标签:
【中文标题】如何找出(使用 XCTest UITest)在 tvOS AppleTV 的表格视图中具有焦点的单元格?【英文标题】:How to find out the (using XCTest UITest) a cell that has a focus in a table view in tvOS AppleTV? 【发布时间】:2016-05-26 16:47:43 【问题描述】:我正在尝试在 Apple TV (tvOS) 上自动执行应用的 UI 测试。
在登录屏幕上,我选择“输入用户名”字段。然后出现以前使用过的登录屏幕。在屏幕上,我想选择“清除所有”单元格。
澄清一下:“以前使用过”菜单似乎内置在 tvOS 中,每当有人在登录菜单中选择用户名文本字段时,它可能会自动出现。我不确定,所以我仍然需要确认该信息。
所以我认为这样的代码将是一个解决方案:
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)
但是即使是这样的状态:
单元格的属性hasFocus
和selected
似乎返回false:
po self.app.cells.staticTexts["Clear All"].hasFocus
po self.app.cells.staticTexts["Clear All"].selected
当单元格处于“聚焦状态”时,如何找到“清除所有”单元格?
更新:
我尝试了@Oletha 提出的解决方案,但没有成功。不幸的是,clearAllCell.hasFocus
似乎总是返回 false。
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)
【问题讨论】:
直接访问静态文本有区别吗?例如app.staticTexts["Clear All"].hasFocus
很遗憾没有,po app.staticTexts["Clear All"].hasFocus
和 po app.staticTexts["Clear All"].selected
仍然返回 false。
嗯。为什么它们首先是细胞?它们可以轻松迁移到按钮吗?我有一个使用按钮和hasFocus
没有问题的应用程序。
我认为“以前使用过”的整个菜单是 tvOS 原生的,因此可能没有简单的方法可以迁移到按钮。我试过 po app.buttons.staticTexts["Clear All"].exists
但它返回 false。
这看起来像是我遇到的一个问题,其中单元格本身是一个可访问性元素,因此检查员看不到它的后代。您是否尝试过在单元格本身上放置一个可访问性标识符并将其称为 app.cells["我的应用遇到了类似的问题,发现有两点有助于编写运行 UI 测试:
每次按下远程按钮后总是延迟 1 秒,因为断言评估通常比焦点更改更快,因此返回 false
XCUIRemote.sharedRemote().pressButton(.Down)
sleep(1)
查找焦点元素的确切 UI 层次结构位置。例如,print(XCUIApplication().debugDescription)
将为您提供详细的 UI 树,并且可以轻松正确地访问您的元素。
此断言返回 true:
XCTAssert(XCUIApplication().tabBars.buttons["Home"].hasFocus)
【讨论】:
【参考方案2】:使用expectationForPredicate
和waitForExpectationsWithTimeout
检查单元格是否有焦点。使用期望会导致每次检查发生时刷新可访问性层次结构快照。您的 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 应用程序可供测试。
【讨论】:
您能否通过重构问题中的不成功解决方案来提供代码示例?我尝试使用expectationForPredicate
和waitForExpectationsWithTimeout
来实现,但没有成功。
@tommagellancook 用我认为应该有帮助的示例更新了答案。
我已经尝试过您的代码,但它看起来不像它应该的那样工作。循环正在检查 clearAll 是否具有焦点,但它永远不会返回 true。我已经更新了我的问题,以便您可以在代码中达到峰值。【参考方案3】:
首先,它是 tvOS 中的本机屏幕,因此所有与尝试设置辅助功能 ID 相关的建议都不相关。当你到达那个屏幕并打印出哪个元素被聚焦时尝试放置一个断点
我相信答案会是。屏幕上的一个位置。或没有标识符的单元格。我在 Apple TV 上遇到了同样的问题,我想知道你遇到的所有问题,因为我想知道 xcuitest 对于 tvOS 有多成熟
【讨论】:
以上是关于如何找出(使用 XCTest UITest)在 tvOS AppleTV 的表格视图中具有焦点的单元格?的主要内容,如果未能解决你的问题,请参考以下文章
如何创建一个在 XCTest 中定义按钮或文本字段的 swift 文件?