К сожалению, Apple не предоставила метод scrollTo
или параметр .visible
для XCUIElement
. Тем не менее, вы можете добавить пару вспомогательных методов для реализации некоторых из этих функций. Вот как я это сделал в Swift.
Сначала для проверки, виден ли элемент:
func elementIsWithinWindow(element: XCUIElement) -> Bool {
guard element.exists && !CGRectIsEmpty(element.frame) && element.hittable else { return false }
return CGRectContainsRect(XCUIApplication().windows.elementBoundByIndex(0).frame, element.frame)
}
К сожалению, .exists
возвращает true, если элемент был загружен, но не отображается на экране. Кроме того, мы должны проверить, что у целевого элемента есть кадр больше 0 на 0 (иногда это тоже верно) — тогда мы можем проверить, находится ли этот кадр в главном окне.
Затем нам нужен метод для прокрутки контролируемой суммы вверх или вниз:
func scrollDown(times: Int = 1) {
let topScreenPoint = app.mainWindow().coordinateWithNormalizedOffset(CGVector(dx: 0.5, dy: 0.05))
let bottomScreenPoint = app.mainWindow().coordinateWithNormalizedOffset(CGVector(dx: 0.5, dy: 0.90))
for _ in 0..<times {
bottomScreenPoint.pressForDuration(0, thenDragToCoordinate: topScreenPoint)
}
}
func scrollUp(times: Int = 1) {
let topScreenPoint = app.mainWindow().coordinateWithNormalizedOffset(CGVector(dx: 0.5, dy: 0.05))
let bottomScreenPoint = app.mainWindow().coordinateWithNormalizedOffset(CGVector(dx: 0.5, dy: 0.90))
for _ in 0..<times {
topScreenPoint.pressForDuration(0, thenDragToCoordinate: bottomScreenPoint)
}
}
Изменение значений CGVector для topScreenPoint и bottomScreenPoint изменит масштаб действия прокрутки — имейте в виду, что если вы подойдете слишком близко к краям экрана, вы вытащите одно из меню ОС.
Используя эти два метода, вы можете написать цикл, который прокручивается до заданного порога в одну сторону, пока элемент не станет видимым, а затем, если он не находит свою цель, он прокручивается в другую сторону:
func scrollUntilElementAppears(element: XCUIElement, threshold: Int = 10) {
var iteration = 0
while !elementIsWithinWindow(element) {
guard iteration < threshold else { break }
scrollDown()
iteration++
}
if !elementIsWithinWindow(element) { scrollDown(threshold) }
while !elementIsWithinWindow(element) {
guard iteration > 0 else { break }
scrollUp()
iteration--
}
}
Этот последний метод не очень эффективен, но, по крайней мере, он должен позволить вам находить элементы за пределами экрана. Конечно, если вы знаете, что ваш целевой элемент всегда будет выше или ниже вашей начальной точки в данном тесте, вы можете просто написать здесь метод scrollDownUntil
или scrollUpUntill
без пороговой логики. Надеюсь это поможет!
person
Tucker Sherman
schedule
05.11.2015