XPath와 Appium과 Python

XPath란?

XML파일에서 elements와 attributes를 찾기위한 path

XML표현은 익숙한 아래 그림으로 대변된다









XPath언어는 다음 언어에사 사용되어지고 있다.
JavaScript, Java, XML Schema, PHP, Python, C and C++, and lots of other languages

XPath3.0이 2014년도부터 W3C추천사항으로 선정됨

XPath에서 Node란?

element, attribute, text, namespace, processing-instruction, comment and document nodes

XML문서는 node들의 tree형태

최상위 element는 root element라고 한다



연습문제:
다음 코드에서 element와 attribute를 찾으시오
<?xml version="1.0" encoding="UTF-8"?>

<bookstore>
  <book>
    <title lang="en">Harry Potter</title>
    <author>J K. Rowling</author>
    <year>2005</year>
    <price>29.99</price>
  </book>
</bookstore>


정답: 
element: bookstore (root), book 등등
attribute: lang="en"

Atomic value란?

J K. Rowling이나 "en"

Items이란?

atomic values + nodes



문법

<?xml version="1.0" encoding="UTF-8"?>

<bookstore>

<book>
  <title lang="en">Harry Potter</title>
  <price>29.99</price>
</book>

<book>
  <title lang="en">Learning XML</title>
  <price>39.95</price>
</book>

</bookstore>

ExpressionDescription
nodenameSelects all nodes with the name "nodename"
/Selects from the root node
//Selects nodes in the document from the current node that match the selection no matter where they are
.Selects the current node
..Selects the parent of the current node
@Selects attributes
예)
bookstore
/bookstore
bookstore/book
bookstore//book
book
//book (이거는 book과 같다)
//@lang(어트리뷰트 검색)

예2)
/bookstore/book[1] (부모가 bookstore인 첫번째 book)
/bookstore/book[last()] (마지막 book)
/bookstore/book[last()-1]
/bookstore/book[position()<3]
//title[@lang] (title중에 lang어트리뷰트를 가진것을 모두 고름)
//title[@lang='en']
/bookstore/book[price>35.00]/title

존재하지 않는 경우
/book(루트밑에 book 없음)

WildcardDescription
*Matches any element node
@*Matches any attribute node
node()Matches any node of any kind
Path ExpressionResult
/bookstore/*Selects all the child element nodes of the bookstore element
//*Selects all elements in the document
//title[@*]Selects all title elements which have at least one attribute of any kind



Appium-Python에서 xpath 활용법

"//android.widget.TextView[contains(@text, 'Call')]"
어느 위치에 있던 상관없고 TextView element중에 text attribute의 값이 Call인것들을 모두 찾기
driver.find_element_by_xpath('//*[@id="menu"]/ul/li[1]/a')
모든 element들 중에 id attribute를 갖고있고 그 값이 "menu"인 것들중에 자식으로 ul/ li를 갖고있고 li중에 첫번째여야하고 그 밑에 또 a가 있어야함. 결국 이 a가 선택됨


실제예제:
els = self.driver.find_elements_by_xpath('//android.widget.TextView')
self.assertEqual('API Demos', els[0].text)
TextView 엘리먼트를 찾아서 첫번째인자의 text값을 체크 


el = self.driver.find_element_by_xpath('//android.widget.TextView[contains(@text, "Animat")]')
self.assertEqual('Animation', el.text)


els = self.driver.find_elements_by_xpath('//android.widget.TextView')
self.assertLess(10, len(els))
self.assertEqual('Action Bar', els[1].text)


sleep(2)
els = self.driver.find_elements_by_xpath('//android.widget.TextView')
self.driver.scroll(els[7], els[3])

els = self.driver.find_elements_by_class_name('android.widget.TextView')
self.driver.scroll(els[len(els)-1], els[0])

# 해상도 등에 따른 뷰가 안보일시에 적용할 수 있는 테크닉_START
el = None
try:
el = self.driver.find_element_by_accessibility_id('Touch Paint')
except Exception as e:
els = self.driver.find_elements_by_class_name('android.widget.TextView')
self.driver.scroll(els[len(els)-1], els[0])

if el is None:
el = self.driver.find_element_by_accessibility_id('Touch Paint')
el.click()
# 해상도 등에 따른 뷰가 안보일시에 적용할 수 있는 테크닉_END


# paint
e1 = TouchAction()
e1.press(x=150, y=100).release()

e2 = TouchAction()
e2.press(x=250, y=100).release()

smile = TouchAction()
smile.press(x=110, y=200) \
.move_to(x=1, y=1) \
.move_to(x=1, y=1) \
.move_to(x=1, y=1) \
.move_to(x=1, y=1) \

댓글

이 블로그의 인기 게시물

Gradle