Я пишу тест, который должен прокручивать страницу вниз, пока кнопка Activate card
не станет видимой для пользователя, а затем нажмите на нее.
Проблема
Драйвер Appium is_displayed
возвращает true
, когда элемент виден в области просмотра. Поскольку в нашем приложении есть плавающие кнопки над панелью навигации, is_displayed()
возвращает true, даже если плавающие кнопки перекрывают кнопку Activate card
.
Когда я call element.click()
вместо этого он нажимает на плавающую кнопку по координатам в центре.
Согласно Appium docs , в таком случае должна быть выдана ошибка:
Щелкает элемент в его центральной точке. Если центральная точка элемента закрыта другим элементом, возвращается ошибка перехвата щелчка элемента.
Если бы это было так, я мог бы прокрутить немного больше при ошибке, но этого не происходит ( проблема драйвера?).
Единственный способ, которым мне удалось решить эту проблему, - это прокрутить над какой-то «безопасной зоной» внизу, которая составляет 20% от высоты.
Вот код.
def scroll_down_to(self, to: TestObject, max_scrolls: int = 10):
"""
Scrolls down until `to` element is in safe area. If maximum scrolls reached, throws an exception
"""
try:
self._check_element_in_safe_area(to)
logger.debug('Element is on the screen, no need to scroll')
return
except NoSuchElementException:
pass
size = self.driver.get_window_size()
width = size['width']
height = size['height']
start_x = width / 2
start_y = height / 3
end_x = width / 2
end_y = 0
for i in range(0, max_scrolls):
try:
self._check_element_in_safe_area(to)
logger.debug('Element found after scroll')
return
except NoSuchElementException:
self.driver.swipe(start_x, start_y, end_x, end_y)
logger.debug('Element not found after scroll, scrolling down more')
raise NoSuchElementException(f'No element found after scroll matching {to.locator}')
def _check_element_in_safe_area(self, obj: TestObject):
"""
Throws NoSuchElementException in case element is not in the safe area
"""
element: WebElement = self.driver.find_element(obj.match_type, obj.locator)
if not element.is_displayed() or not self._is_in_safe_area(element):
raise NoSuchElementException()
def _is_in_safe_area(self, element: WebElement) -> bool:
rect = element.rect
el_y = rect['y'] + rect['height'] * 0.5
return el_y < self.safe_bottom_area
Вопрос
Как правильно написать кросс-платформенный (iOS / Android) тест, чтобы он нажимал на элементы, которые полностью видны user?
Вместо этого я попытался найти способ через UIAutomator, но безуспешно.