driver의 find_element
로 접근한 element에 click()
함수를 실행해보았지만 아무일도 일어나지 않았다..
find_element
로 정상적으로 접근이 가능한 것으로 보아 NoSuchElementError
에러는 아닌듯하였다.
Appium 공식문서에 따르면 python으로 unittest 모듈을 생성해 테스트 코드 작성하는 법은 아래와 같다.
test.py
import unittest
from appium import webdriver
from appium.webdriver.common.appiumby import AppiumBy
capabilities = dict(
platformName='Android',
automationName='uiautomator2',
deviceName='Android',
appPackage='com.android.settings',
appActivity='.Settings',
language='en',
locale='US'
)
appium_server_url = 'http://localhost:4723'
class TestAppium(unittest.TestCase):
def setUp(self) -> None:
self.driver = webdriver.Remote(appium_server_url, capabilities)
def tearDown(self) -> None:
if self.driver:
self.driver.quit()
def test_find_battery(self) -> None:
el = self.driver.find_element(by=AppiumBy.XPATH, value='//*[@text="Battery"]')
el.click()
if __name__ == '__main__':
unittest.main()
이때 TestAppium 클래스에서 생성한 driver를 사용하여 iOS 디바이스를 조작할 수 있는데 해당 driver에는 여러 메소드들이 있다. 그 중 대표적으로 쓰이는게 find_element
이다. find_element
를 사용해 AppiumBy으로 부터 받은 위치 값으로 element를 찾는다.
find_element(by: str = 'id', value: str | Dict | None = None) → WebElement
Parameters
Usage
driver.find_element(by=AppiumBy.ACCESSIBILITY_ID, value=’accessibility_id’)
Returns
The found element
Return type
appium.webdriver.webelement.WebElement
추가로 find_elements
도 있다. find_element
와 차이점은 리스트를 반환한다는 것이고 자세한 내용은 아래에 기재하도록 함.
예시 이미지와 같이 특정 element의 값을 inspector를 통해 조회할 수 있다. 보통 주로 에러가 발생할 때는 NoSuchElementError: An element could not be located on the page using the given search parameters.
해당 element의 id로 접근할 수 없는 경우가 대다수이다.
하지만 이번 에러는 appium inspector로 접근도 가능하고, 심지어 print(element)로 조회했을 때 출력도 정상 작동했다.
그럼 뭐가 문제지..
혹시 몰라 find_elements
로 접근한 element를 출력해보았다. 해당 메소드는 리스트를 반환하기에 WebElement가 담긴 리스트가 출력될 것이라 예상했다.
> [<appium.webdriver.webelement.WebElement (session="0000", element="0000")>,
<appium.webdriver.webelement.WebElement (session="0001", element="0001")>,
<appium.webdriver.webelement.WebElement (session="0002", element="0002")>]
보이는 것과 같이 element가 3개 담긴 리스트가 출력되었다. 여기서 문제는 내가 click할 element는 무엇인가..인데 결국 두번째 항목으로 하니 정상적으로 동작하였다.
요약.
1. find_element로 찾은 element에 click() 함수가 먹히지 않음
2. 혹시몰라 find_elements로 리스트를 출력해봄
3. 찾은 element는 총 3개로, element[2].click()을 하니 정상 동작하였음
결론.
한 화면에 해당 id로 다수의 element가 있는 경우 이벤트를 실행시키고자 할 때는 정확히 해당 id의 element를 지정해줘야 한다.
find_element by id를 참조하여 특정 element에 접근 시 화면에 없거나 찾을 수 없는 항목일 경우 NoSuchElementError
오류를 바로 뱉었었다. 따라서 아래의 try~ except~ 구문으로 코드를 짰었다.
try:
# 내가 찾고자 하는 항목
element = driver.find_element(by=id, value="element_id")
except Exception as e:
print("오류가 났으니 에러 메시지 출력해봐:", e)
그러나 find_elements를 사용하니 찾을 수 없는 element를 접근 시도하여도 빈배열을 뱉을 뿐 오류를 바로 뱉지 않음을 알게되었다!!