1.iOS手机的滑动

相关代码

  1. #python
  2. class IOS(Device):
  3. ...
  4. @property
  5. #获取屏幕的尺寸
  6. def display_info(self):
  7. if not self._size['width'] or not self._size['height']:
  8. self.snapshot()
  9. return {'width': self._size['width'], 'height': self._size['height'], 'orientation': self.orientation,\
  10. 'physical_width': self._size['width'], 'physical_height': self._size['height']}
  11. ...
  12. #滑动
  13. def swipe(self, fpos, tpos, duration=0.5, steps=5, fingers=1):
  14. # trans pos of swipe
  15. fx, fy = self._touch_point_by_orientation(fpos)
  16. tx, ty = self._touch_point_by_orientation(tpos)
  17. self.session.swipe(fx * self._touch_factor, fy * self._touch_factor,
  18. tx * self._touch_factor, ty * self._touch_factor, duration)
  19. ...

1.1直接使用IOS类进行滑动

  1. #python
  2. test=IOS()
  3. a=test.display_info
  4. for i in a:
  5. print(i,a[i])
  6. fpos=(600,2000)
  7. tpos=(600,1000)
  8. test.swipe(fpos,tpos)
  1. #log
  2. [Start running..]
  3. save log in '/var/folders/c7/kh0qq_r10kb7_7fhdsgmrgbh0000gn/T/AirtestIDE/scripts/c6f4a07d9c8371543fcf247becedb4ff'
  4. width
  5. 1125
  6. height
  7. 2436
  8. orientation
  9. PORTRAIT
  10. physical_width
  11. 1125
  12. physical_height
  13. 2436
  14. ----------------------------------------------------------------------
  15. Ran 1 test in 1.628s
  16. OK
  17. [Finished]
  18. ============================================================

1.2编写一个类根据输入的比例值实现滑动

  1. # -*- encoding=utf8 -*-
  2. __author__ = "chenshanju"
  3. #Base类实现屏幕的滑动
  4. from airtest.core.api import *
  5. from airtest.core.ios import IOS
  6. auto_setup(__file__)
  7. class Base():
  8. def __init__(self):
  9. test1=IOS()
  10. self.width=test1.display_info['physical_width']
  11. self.height=test1.display_info['physical_height']
  12. self.left_point=(0.2*self.width,0.5*self.height)
  13. self.right_point=(0.8*self.width,0.5*self.height)
  14. self.up_point=(0.5*self.width,0.25*self.height)
  15. self.down_point=(0.5*self.width,0.75*self.height)
  16. def swipe_to_left(self):
  17. swipe(self.right_point,self.left_point)
  18. print(self.right_point,self.left_point)
  19. def swipe_to_right(self):
  20. swipe(self.left_point,self.right_point)
  21. print(self.left_point,self.right_point)
  22. def swipe_to_up(self):
  23. swipe(self.down_point,self.up_point)
  24. print(self.down_point,self.up_point)
  25. def swipe_to_down(self):
  26. swipe(self.up_point,self.down_point)
  27. print(self.up_point,self.down_point)
  28. #测试代码,要删掉
  29. test=Base()
  30. print("start")
  31. test.swipe_to_up()
  32. test.swipe_to_left()
  33. print("end")
  1. ============================================================
  2. [Start running..]
  3. save log in '/var/folders/c7/kh0qq_r10kb7_7fhdsgmrgbh0000gn/T/AirtestIDE/scripts/c6f4a07d9c8371543fcf247becedb4ff'
  4. start
  5. (562.5, 1827.0)
  6. (562.5, 609.0)
  7. (900.0, 1218.0)
  8. (225.0, 1218.0)
  9. end
  10. ----------------------------------------------------------------------
  11. Ran 1 test in 3.406s
  12. OK
  13. [Finished]
  14. ============================================================

airtest ios类源代码

  1. #! /usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. import requests
  4. import six
  5. import time
  6. import json
  7. import base64
  8. import wda
  9. import chenyi
  10. if six.PY3:
  11. from urllib.parse import urljoin
  12. else:
  13. from urlparse import urljoin
  14. from airtest import aircv
  15. from airtest.core.device import Device
  16. from airtest.core.ios.constant import CAP_METHOD, TOUCH_METHOD, IME_METHOD
  17. from airtest.core.ios.rotation import XYTransformer, RotationWatcher
  18. from airtest.core.ios.fake_minitouch import fakeMiniTouch
  19. from airtest.core.ios.instruct_helper import InstructHelper
  20. from airtest.utils.logger import get_logger
  21. # roatations of ios
  22. from wda import LANDSCAPE, PORTRAIT, LANDSCAPE_RIGHT, PORTRAIT_UPSIDEDOWN
  23. from wda import WDAError
  24. logger = get_logger(__name__)
  25. DEFAULT_ADDR = "http://localhost:8100/"
  26. # retry when saved session failed
  27. def retry_session(func):
  28. def wrapper(self, *args, **kwargs):
  29. try:
  30. return func(self, *args, **kwargs)
  31. except WDAError as err:
  32. # 6 : Session does not exist
  33. if err.status == 6:
  34. self._fetchNewSession()
  35. return func(self, *args, **kwargs)
  36. else:
  37. raise err
  38. return wrapper
  39. class IOS(Device):
  40. """ios client
  41. # befor this you have to run WebDriverAgent
  42. # xcodebuild -project path/to/WebDriverAgent.xcodeproj -scheme WebDriverAgentRunner -destination "id=$(idevice_id -l)" test
  43. # iproxy $port 8100 $udid
  44. """
  45. def __init__(self, addr=DEFAULT_ADDR):
  46. super(IOS, self).__init__()
  47. # if none or empty, use default addr
  48. self.addr = addr or DEFAULT_ADDR
  49. # fit wda format, make url start with http://
  50. if not self.addr.startswith("http://"):
  51. self.addr = "http://" + addr
  52. """here now use these supported cap touch and ime method"""
  53. self.cap_method = CAP_METHOD.WDACAP
  54. self.touch_method = TOUCH_METHOD.WDATOUCH
  55. self.ime_method = IME_METHOD.WDAIME
  56. # wda driver, use to home, start app
  57. # init wda session, updata when start app
  58. # use to click/swipe/close app/get wda size
  59. wda.DEBUG = False
  60. self.driver = wda.Client(self.addr)
  61. # record device's width
  62. self._size = {'width': None, 'height': None}
  63. self._touch_factor = 0.5
  64. self._last_orientation = None
  65. self.defaultSession = None
  66. # start up RotationWatcher with default session
  67. self.rotation_watcher = RotationWatcher(self)
  68. # fake minitouch to simulate swipe
  69. self.minitouch = fakeMiniTouch(self)
  70. # helper of run process like iproxy
  71. self.instruct_helper = InstructHelper()
  72. @property
  73. def uuid(self):
  74. return self.addr
  75. @property
  76. def session(self):
  77. if not self.defaultSession:
  78. self.defaultSession = self.driver.session()
  79. return self.defaultSession
  80. def _fetchNewSession(self):
  81. self.defaultSession = self.driver.sess ion()
  82. @retry_session
  83. def window_size(self):
  84. """
  85. return window size
  86. namedtuple:
  87. Size(wide , hight)
  88. """
  89. return self.session.window_size()
  90. @property
  91. @retry_session
  92. def orientation(self):
  93. """
  94. return device oritantation status
  95. in LANDSACPE POR
  96. """
  97. return self.session.orientation
  98. @property
  99. def display_info(self):
  100. if not self._size['width'] or not self._size['height']:
  101. self.snapshot()
  102. return {'width': self._size['width'], 'height': self._size['height'], 'orientation': self.orientation,\
  103. 'physical_width': self._size['width'], 'physical_height': self._size['height']}
  104. def get_current_resolution(self):
  105. w, h = self.display_info["width"], self.display_info["height"]
  106. if self.display_info["orientation"] in [LANDSCAPE, LANDSCAPE_RIGHT]:
  107. w, h = h, w
  108. return w, h
  109. def home(self):
  110. return self.driver.home()
  111. def _neo_wda_screenshot(self):
  112. """
  113. this is almost same as wda implementation, but without png header check,
  114. as response data is now jpg format in mid quality
  115. """
  116. value = self.driver.http.get('screenshot').value
  117. raw_value = base64.b64decode(value)
  118. return raw_value
  119. def snapshot(self, filename=None, strType=False, ensure_orientation=True):
  120. """
  121. take snapshot
  122. filename: save screenshot to filename
  123. """
  124. data = None
  125. if self.cap_method == CAP_METHOD.MINICAP:
  126. raise NotImplementedError
  127. elif self.cap_method == CAP_METHOD.MINICAP_STREAM:
  128. raise NotImplementedError
  129. elif self.cap_method == CAP_METHOD.WDACAP:
  130. data = self._neo_wda_screenshot() # wda 截图不用考虑朝向
  131. if strType:
  132. if filename:
  133. with open(filename, 'wb') as f:
  134. f.write(data)
  135. return data
  136. # output cv2 object
  137. try:
  138. screen = aircv.utils.string_2_img(data)
  139. except:
  140. # may be black/locked screen or other reason, print exc for debugging
  141. import traceback
  142. traceback.print_exc()
  143. return None
  144. now_orientation = self.orientation
  145. # ensure the orientation is right
  146. if ensure_orientation and now_orientation in [LANDSCAPE, LANDSCAPE_RIGHT]:
  147. # minicap screenshots are different for various sdk_version
  148. if self.cap_method in (CAP_METHOD.MINICAP, CAP_METHOD.MINICAP_STREAM) and self.sdk_version <= 16:
  149. h, w = screen.shape[:2] # cvshape是高度在前面!!!!
  150. if w < h: # 当前是横屏,但是图片是竖的,则旋转,针对sdk<=16的机器
  151. screen = aircv.rotate(screen, self.display_info["orientation"] * 90, clockwise=False)
  152. # wda 截图是要根据orientation旋转
  153. elif self.cap_method == CAP_METHOD.WDACAP:
  154. # seems need to rotate in opencv opencv-contrib-python==3.2.0.7
  155. screen = aircv.rotate(screen, 90, clockwise=(now_orientation == LANDSCAPE_RIGHT))
  156. # readed screen size
  157. h, w = screen.shape[:2]
  158. # save last res for portrait
  159. if now_orientation in [LANDSCAPE, LANDSCAPE_RIGHT]:
  160. self._size['height'] = w
  161. self._size['width'] = h
  162. else:
  163. self._size['height'] = h
  164. self._size['width'] = w
  165. winw, winh = self.window_size()
  166. self._touch_factor = float(winh) / float(h)
  167. # save as file if needed
  168. if filename:
  169. aircv.imwrite(filename, screen)
  170. return screen
  171. @retry_session
  172. def touch(self, pos, duration=0.01):
  173. # trans pos of click
  174. pos = self._touch_point_by_orientation(pos)
  175. # scale touch postion
  176. x, y = pos[0] * self._touch_factor, pos[1] * self._touch_factor
  177. if duration >= 0.5:
  178. self.session.tap_hold(x, y, duration)
  179. else:
  180. self.session.tap(x, y)
  181. def double_click(self, pos):
  182. # trans pos of click
  183. pos = self._touch_point_by_orientation(pos)
  184. x, y = pos[0] * self._touch_factor, pos[1] * self._touch_factor
  185. self.session.double_tap(x, y)
  186. def swipe(self, fpos, tpos, duration=0.5, steps=5, fingers=1):
  187. # trans pos of swipe
  188. fx, fy = self._touch_point_by_orientation(fpos)
  189. tx, ty = self._touch_point_by_orientation(tpos)
  190. self.session.swipe(fx * self._touch_factor, fy * self._touch_factor,
  191. tx * self._touch_factor, ty * self._touch_factor, duration)
  192. def keyevent(self, keys):
  193. """just use as home event"""
  194. if keys not in ['HOME', 'home', 'Home']:
  195. raise NotImplementedError
  196. self.home()
  197. @retry_session
  198. def text(self, text, enter=True):
  199. """bug in wda for now"""
  200. if enter:
  201. text += '\n'
  202. self.session.send_keys(text)
  203. def install_app(self, uri, package):
  204. """
  205. curl -X POST $JSON_HEADER \
  206. -d "{\"desiredCapabilities\":{\"bundleId\":\"com.apple.mobilesafari\", \"app\":\"[host_path]/magicapp.app\"}}" \
  207. $DEVICE_URL/session
  208. https://github.com/facebook/WebDriverAgent/wiki/Queries
  209. """
  210. raise NotImplementedError
  211. def start_app(self, package, activity=None):
  212. self.defaultSession = None
  213. self.driver.session(package)
  214. def stop_app(self, package):
  215. self.driver.session().close()
  216. def get_ip_address(self):
  217. """
  218. get ip address from webDriverAgent
  219. Returns:
  220. raise if no IP address has been found, otherwise return the IP address
  221. """
  222. return self.driver.status()['ios']['ip']
  223. def device_status(self):
  224. """
  225. show status return by webDriverAgent
  226. Return dicts of infos
  227. """
  228. return self.driver.status()
  229. def _touch_point_by_orientation(self, tuple_xy):
  230. """
  231. Convert image coordinates to physical display coordinates, the arbitrary point (origin) is upper left corner
  232. of the device physical display
  233. Args:
  234. tuple_xy: image coordinates (x, y)
  235. Returns:
  236. """
  237. x, y = tuple_xy
  238. # use correct w and h due to now orientation
  239. # _size 只对应竖直时候长宽
  240. now_orientation = self.orientation
  241. if now_orientation in [PORTRAIT, PORTRAIT_UPSIDEDOWN]:
  242. width, height = self._size['width'], self._size["height"]
  243. else:
  244. height, width = self._size['width'], self._size["height"]
  245. # check if not get screensize when touching
  246. if not width or not height:
  247. # use snapshot to get current resuluton
  248. self.snapshot()
  249. x, y = XYTransformer.up_2_ori(
  250. (x, y),
  251. (width, height),
  252. now_orientation
  253. )
  254. return x, y
  255. def _check_orientation_change(self):
  256. pass
  257. if __name__ == "__main__":
  258. start = time.time()
  259. ios = IOS("http://10.254.51.239:8100")
  260. ios.snapshot()
  261. # ios.touch((242 * 2 + 10, 484 * 2 + 20))
  262. # ios.start_app("com.tencent.xin")
  263. ios.home()
  264. ios.start_app('com.apple.mobilesafari')
  265. ios.touch((88, 88))
  266. ios.stop_app('com.apple.mobilesafari')
  267. ios.swipe((100, 100), (800, 100))
  268. print(ios.device_status())
  269. print(ios.get_ip_address())

Air test ios类使用的更多相关文章

  1. air for ios

    在 Adobe AIR 中为不同屏幕尺寸的多种设备提供支持 使用Flash Builder 4.5进行多平台游戏开发 手机屏幕触控技术与提升AIR在Android上的触控体验 AIR Native E ...

  2. AIR for IOS开发问题小结

    昨天终于成功地向APP STORE提交了应用,个人感觉用AIR做IOS开发就是个坑啊.出了问题之后,问苹果的技术支持,人家说“对于非XCODE环境下开发及发布所造成的问题我们在资料库中无法找到相应的解 ...

  3. 从零开始学C++之IO流类库(四):输出流格式化(以操纵子方式格式化 以ios类成员函数方式格式化)

    一.以操纵子方式格式化 数据输入输出的格式控制使用系统头文件<iomanip>中提供的操纵符.把它们作为插入操作符<<的输出对象即可.如setiosflags.setw.set ...

  4. 输出流格式化(以操纵子方式格式化,以ios类成员函数方式格式化)

    一.以操纵子方式格式化 数据输入输出的格式控制使用系统头文件<iomanip>中提供的操纵符.把它们作为插入操作符<<的输出对象即可.如setiosflags.setw.set ...

  5. iOS类的合理设计,面向对象思想

    每天更新的东西可能有反复的内容.当时每一部分的知识点是不同的,须要大家认真阅读 这里介绍了iOS类的合理设计.面向对象思想 main.m #import <Foundation/Foundati ...

  6. AIR面向IOS设备的原生扩展

    来源:http://www.cnblogs.com/alex-tech/archive/2012/03/22/2411264.html ANE组成部分 在IOS平台中,ANE的组成部分基本分为AS 3 ...

  7. 关于iOS 类扩展Extension的进一步理解

    很多人可能会问  iOS的分类和扩展的区别,网上很多的讲解,但是一般都是分类讲的多,而这也是我们平常比较常用的知识:但是,对于扩展,总觉得理解的朦朦胧胧,不够透彻. 这里就讲一下我自己的理解,但是这个 ...

  8. iOS类目

    首先我们解释一下类目是什么 iOS中类目是为给已经存在的类加入新的方法.(可是不能加入实例变量) 也就是说 我们已经有一个类了 .可是我们发现这个类眼下所提供的方法,满足不了我们的需求,我们须要新的方 ...

  9. iOS - 类扩展与分类的区别

    类扩展 (Class Extension也有人称为匿名分类) 作用: 能为某个类附加额外的属性,成员变量,方法声明 一般的类扩展写到.m文件中 一般的私有属性写到类扩展 使用格式: @interfac ...

随机推荐

  1. reboot 后 Docker服务及容器自动启动设置

    https://blog.csdn.net/wxb880114/article/details/82904765 重启reboot操作系统后,发现docker 服务未启动,容器也未启动,天生反骨,怎么 ...

  2. ZooKeeper 之 zkCli.sh客户端的命令使用

    zkCli.sh的使用 ZooKeeper服务器简历客户端 ./zkCli.sh -timeout 0 -r -server ip:port ./zkCli.sh -timeout 5000 -ser ...

  3. json数组和json字符串转换成map解析

    package demo; import java.util.List;import java.util.Map;import java.util.Map.Entry; import net.sf.j ...

  4. git的时候 WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!

    更改Ubuntu服务器的时候,提交git出错: @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ WARNING: REMOTE ...

  5. idea中看不到项目结构该怎么办

    点击file->project structure..->Modules 点击右上角+加号 ->import Modules 2.选择你的项目,点击确定   3.在如下页面选择imp ...

  6. 构建你自己的论坛,基于windows服务器的xampp+discuz论坛

    首先声明,论坛的构建需要基于企业,并且基于企业注册,然后进行域名备案. 此处作为研究,先示例: 1. 安装 xampp 软件,百度搜索 然后在服务器安装,基本都是默认安装,然后出来. 安装完成后,接下 ...

  7. C# 高性能的数组 高性能数组队列实战 HslCommunication的SharpList类详解

    本文将使用一个gitHub开源的组件技术来实现这个功能 github地址:https://github.com/dathlin/HslCommunication                     ...

  8. 新手小白Linux(Centos6.5)部署java web项目(mysql5.7安装及相关操作)

    一.安装 参考:https://dev.mysql.com/doc/refman/5.7/en/linux-installation-yum-repo.html # 检测系统中是否安装了mysql y ...

  9. Tomcat下JSP、Servlet和JavaBean环境的配置

    经常看到jsp的初学者问tomcat下如何配置jsp.servlet和bean的问题,于是总结了一下如何tomcat下配置jsp.servlet和ben,希望对那些初学者有所帮助. 第一步:下载j2s ...

  10. HDU 5178:pairs(二分,lower_bound和upper_bound)

    pairs Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Subm ...