macaca 自带了获取控件坐标的功能
element = driver.element_by_xxx(xxx)
rect = element.rect
x = rect['x']
y = rect['y']
width = rect['width']
height = rect['height']
为了不在 case 当中写死坐标, 研究了一下怎样获取控件坐标, 从而通过获取到的坐标实现滑动
用到的模块:
pip install lxml
pip install beautifulsoup4
webdriver 中有一个获取页面 xml 的方法: xml = driver.source
但问题是, 这个 xml 的所有节点名字都是 node
, 不太容易通过简单的 xpath 去获取里面的内容. 通过 app-inspector 发现每个节点的名字和 class 是相同的. 因此想到通过 beautifulsoup 把 xml 中的 node 都用 class 的内容替换, 然后在用 lxml 模块去读取其中的 bounds 坐标属性.
from bs4 import BeautifulSoup
from lxml import etree
def getElementBounds(xml, xpath):
'''
xml: 通过 driver.source 获取
'''
soup = BeautifulSoup(xml, 'lxml')
while soup.node is not None:
soup.node.name = soup.node['class'][0]
final_xml = str(soup).replace('$', '')
# logging.info(final_xml)
selector = etree.XML(final_xml)
logging.info(selector.xpath(xpath))
element = selector.xpath(xpath)[0]
location_str = element.attrib['bounds'] # [0,1266][1080,1641]
location_str = location_str[1:-1].replace('][', ',') # 0,1266,1080,1641
location_list = location_str.split(',') # ['0', '1266', '1080', '1641']
logging.info(location_list)
for i in xrange(len(location_list)):
location_list[i] = int(location_list[i])
# logging.info(location_list) # [0, 1266, 1080, 1641]
return location_list
def move(from_xpath, to_xpath):
xml = driver.source
from_location = getElementBounds(xml, from_xpath)
to_location = getElementBounds(xml, to_xpath)
actions = {}
actions.update({'fromX': int(from_location[2] / 2), 'fromY': from_location[1]}) # 起点控件的上边缘的中间位置
actions.update({'toX': int(to_location[2] / 2), 'toY': to_location[3]}) # 终点控件的下边缘的中间位置
actions.update({'steps': 50})
driver.touch('drag', actions)