1.iOS手机的滑动

相关代码

#python
class IOS(Device):
...
@property
#获取屏幕的尺寸
def display_info(self):
if not self._size['width'] or not self._size['height']:
self.snapshot() return {'width': self._size['width'], 'height': self._size['height'], 'orientation': self.orientation,\
'physical_width': self._size['width'], 'physical_height': self._size['height']}
...
#滑动
def swipe(self, fpos, tpos, duration=0.5, steps=5, fingers=1):
# trans pos of swipe
fx, fy = self._touch_point_by_orientation(fpos)
tx, ty = self._touch_point_by_orientation(tpos) self.session.swipe(fx * self._touch_factor, fy * self._touch_factor,
tx * self._touch_factor, ty * self._touch_factor, duration)
...

1.1直接使用IOS类进行滑动

#python
test=IOS()
a=test.display_info
for i in a:
print(i,a[i])
fpos=(600,2000)
tpos=(600,1000)
test.swipe(fpos,tpos)
#log
[Start running..]
save log in '/var/folders/c7/kh0qq_r10kb7_7fhdsgmrgbh0000gn/T/AirtestIDE/scripts/c6f4a07d9c8371543fcf247becedb4ff'
width
1125
height
2436
orientation
PORTRAIT
physical_width
1125
physical_height
2436
----------------------------------------------------------------------
Ran 1 test in 1.628s OK
[Finished] ============================================================

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

# -*- encoding=utf8 -*-
__author__ = "chenshanju"
#Base类实现屏幕的滑动
from airtest.core.api import *
from airtest.core.ios import IOS
auto_setup(__file__)
class Base():
def __init__(self):
test1=IOS()
self.width=test1.display_info['physical_width']
self.height=test1.display_info['physical_height']
self.left_point=(0.2*self.width,0.5*self.height)
self.right_point=(0.8*self.width,0.5*self.height)
self.up_point=(0.5*self.width,0.25*self.height)
self.down_point=(0.5*self.width,0.75*self.height)
def swipe_to_left(self):
swipe(self.right_point,self.left_point)
print(self.right_point,self.left_point)
def swipe_to_right(self):
swipe(self.left_point,self.right_point)
print(self.left_point,self.right_point)
def swipe_to_up(self):
swipe(self.down_point,self.up_point)
print(self.down_point,self.up_point)
def swipe_to_down(self):
swipe(self.up_point,self.down_point)
print(self.up_point,self.down_point)
#测试代码,要删掉
test=Base()
print("start")
test.swipe_to_up()
test.swipe_to_left()
print("end")
============================================================

[Start running..]
save log in '/var/folders/c7/kh0qq_r10kb7_7fhdsgmrgbh0000gn/T/AirtestIDE/scripts/c6f4a07d9c8371543fcf247becedb4ff'
start
(562.5, 1827.0)
(562.5, 609.0)
(900.0, 1218.0)
(225.0, 1218.0)
end
----------------------------------------------------------------------
Ran 1 test in 3.406s OK
[Finished] ============================================================

airtest ios类源代码

#!  /usr/bin/env  python
# -*- coding: utf-8 -*- import requests
import six
import time
import json
import base64
import wda
import chenyi if six.PY3:
from urllib.parse import urljoin
else:
from urlparse import urljoin from airtest import aircv
from airtest.core.device import Device
from airtest.core.ios.constant import CAP_METHOD, TOUCH_METHOD, IME_METHOD
from airtest.core.ios.rotation import XYTransformer, RotationWatcher
from airtest.core.ios.fake_minitouch import fakeMiniTouch
from airtest.core.ios.instruct_helper import InstructHelper
from airtest.utils.logger import get_logger # roatations of ios
from wda import LANDSCAPE, PORTRAIT, LANDSCAPE_RIGHT, PORTRAIT_UPSIDEDOWN
from wda import WDAError logger = get_logger(__name__)
DEFAULT_ADDR = "http://localhost:8100/" # retry when saved session failed
def retry_session(func):
def wrapper(self, *args, **kwargs):
try:
return func(self, *args, **kwargs)
except WDAError as err:
# 6 : Session does not exist
if err.status == 6:
self._fetchNewSession()
return func(self, *args, **kwargs)
else:
raise err
return wrapper class IOS(Device):
"""ios client
# befor this you have to run WebDriverAgent
# xcodebuild -project path/to/WebDriverAgent.xcodeproj -scheme WebDriverAgentRunner -destination "id=$(idevice_id -l)" test
# iproxy $port 8100 $udid
""" def __init__(self, addr=DEFAULT_ADDR):
super(IOS, self).__init__() # if none or empty, use default addr
self.addr = addr or DEFAULT_ADDR # fit wda format, make url start with http://
if not self.addr.startswith("http://"):
self.addr = "http://" + addr """here now use these supported cap touch and ime method"""
self.cap_method = CAP_METHOD.WDACAP
self.touch_method = TOUCH_METHOD.WDATOUCH
self.ime_method = IME_METHOD.WDAIME # wda driver, use to home, start app
# init wda session, updata when start app
# use to click/swipe/close app/get wda size
wda.DEBUG = False
self.driver = wda.Client(self.addr) # record device's width
self._size = {'width': None, 'height': None}
self._touch_factor = 0.5
self._last_orientation = None
self.defaultSession = None # start up RotationWatcher with default session
self.rotation_watcher = RotationWatcher(self) # fake minitouch to simulate swipe
self.minitouch = fakeMiniTouch(self) # helper of run process like iproxy
self.instruct_helper = InstructHelper() @property
def uuid(self):
return self.addr @property
def session(self):
if not self.defaultSession:
self.defaultSession = self.driver.session()
return self.defaultSession def _fetchNewSession(self):
self.defaultSession = self.driver.sess ion() @retry_session
def window_size(self):
"""
return window size
namedtuple:
Size(wide , hight)
"""
return self.session.window_size() @property
@retry_session
def orientation(self):
"""
return device oritantation status
in LANDSACPE POR
"""
return self.session.orientation @property
def display_info(self):
if not self._size['width'] or not self._size['height']:
self.snapshot() return {'width': self._size['width'], 'height': self._size['height'], 'orientation': self.orientation,\
'physical_width': self._size['width'], 'physical_height': self._size['height']} def get_current_resolution(self):
w, h = self.display_info["width"], self.display_info["height"]
if self.display_info["orientation"] in [LANDSCAPE, LANDSCAPE_RIGHT]:
w, h = h, w
return w, h def home(self):
return self.driver.home() def _neo_wda_screenshot(self):
"""
this is almost same as wda implementation, but without png header check,
as response data is now jpg format in mid quality
"""
value = self.driver.http.get('screenshot').value
raw_value = base64.b64decode(value)
return raw_value def snapshot(self, filename=None, strType=False, ensure_orientation=True):
"""
take snapshot
filename: save screenshot to filename
"""
data = None if self.cap_method == CAP_METHOD.MINICAP:
raise NotImplementedError
elif self.cap_method == CAP_METHOD.MINICAP_STREAM:
raise NotImplementedError
elif self.cap_method == CAP_METHOD.WDACAP:
data = self._neo_wda_screenshot() # wda 截图不用考虑朝向 if strType:
if filename:
with open(filename, 'wb') as f:
f.write(data)
return data # output cv2 object
try:
screen = aircv.utils.string_2_img(data)
except:
# may be black/locked screen or other reason, print exc for debugging
import traceback
traceback.print_exc()
return None now_orientation = self.orientation # ensure the orientation is right
if ensure_orientation and now_orientation in [LANDSCAPE, LANDSCAPE_RIGHT]: # minicap screenshots are different for various sdk_version
if self.cap_method in (CAP_METHOD.MINICAP, CAP_METHOD.MINICAP_STREAM) and self.sdk_version <= 16:
h, w = screen.shape[:2] # cvshape是高度在前面!!!!
if w < h: # 当前是横屏,但是图片是竖的,则旋转,针对sdk<=16的机器
screen = aircv.rotate(screen, self.display_info["orientation"] * 90, clockwise=False) # wda 截图是要根据orientation旋转
elif self.cap_method == CAP_METHOD.WDACAP:
# seems need to rotate in opencv opencv-contrib-python==3.2.0.7
screen = aircv.rotate(screen, 90, clockwise=(now_orientation == LANDSCAPE_RIGHT)) # readed screen size
h, w = screen.shape[:2] # save last res for portrait
if now_orientation in [LANDSCAPE, LANDSCAPE_RIGHT]:
self._size['height'] = w
self._size['width'] = h
else:
self._size['height'] = h
self._size['width'] = w winw, winh = self.window_size() self._touch_factor = float(winh) / float(h) # save as file if needed
if filename:
aircv.imwrite(filename, screen) return screen @retry_session
def touch(self, pos, duration=0.01):
# trans pos of click
pos = self._touch_point_by_orientation(pos) # scale touch postion
x, y = pos[0] * self._touch_factor, pos[1] * self._touch_factor
if duration >= 0.5:
self.session.tap_hold(x, y, duration)
else:
self.session.tap(x, y) def double_click(self, pos):
# trans pos of click
pos = self._touch_point_by_orientation(pos) x, y = pos[0] * self._touch_factor, pos[1] * self._touch_factor
self.session.double_tap(x, y) def swipe(self, fpos, tpos, duration=0.5, steps=5, fingers=1):
# trans pos of swipe
fx, fy = self._touch_point_by_orientation(fpos)
tx, ty = self._touch_point_by_orientation(tpos) self.session.swipe(fx * self._touch_factor, fy * self._touch_factor,
tx * self._touch_factor, ty * self._touch_factor, duration) def keyevent(self, keys):
"""just use as home event"""
if keys not in ['HOME', 'home', 'Home']:
raise NotImplementedError
self.home() @retry_session
def text(self, text, enter=True):
"""bug in wda for now"""
if enter:
text += '\n'
self.session.send_keys(text) def install_app(self, uri, package):
"""
curl -X POST $JSON_HEADER \
-d "{\"desiredCapabilities\":{\"bundleId\":\"com.apple.mobilesafari\", \"app\":\"[host_path]/magicapp.app\"}}" \
$DEVICE_URL/session
https://github.com/facebook/WebDriverAgent/wiki/Queries
"""
raise NotImplementedError def start_app(self, package, activity=None):
self.defaultSession = None
self.driver.session(package) def stop_app(self, package):
self.driver.session().close() def get_ip_address(self):
"""
get ip address from webDriverAgent Returns:
raise if no IP address has been found, otherwise return the IP address """
return self.driver.status()['ios']['ip'] def device_status(self):
"""
show status return by webDriverAgent
Return dicts of infos
"""
return self.driver.status() def _touch_point_by_orientation(self, tuple_xy):
"""
Convert image coordinates to physical display coordinates, the arbitrary point (origin) is upper left corner
of the device physical display Args:
tuple_xy: image coordinates (x, y) Returns: """
x, y = tuple_xy # use correct w and h due to now orientation
# _size 只对应竖直时候长宽
now_orientation = self.orientation if now_orientation in [PORTRAIT, PORTRAIT_UPSIDEDOWN]:
width, height = self._size['width'], self._size["height"]
else:
height, width = self._size['width'], self._size["height"] # check if not get screensize when touching
if not width or not height:
# use snapshot to get current resuluton
self.snapshot() x, y = XYTransformer.up_2_ori(
(x, y),
(width, height),
now_orientation
)
return x, y def _check_orientation_change(self):
pass if __name__ == "__main__":
start = time.time()
ios = IOS("http://10.254.51.239:8100") ios.snapshot()
# ios.touch((242 * 2 + 10, 484 * 2 + 20)) # ios.start_app("com.tencent.xin")
ios.home()
ios.start_app('com.apple.mobilesafari')
ios.touch((88, 88))
ios.stop_app('com.apple.mobilesafari')
ios.swipe((100, 100), (800, 100)) print(ios.device_status())
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. L1-031 到底是不是太胖了

    据说一个人的标准体重应该是其身高(单位:厘米)减去100.再乘以0.9所得到的公斤数.真实体重与标准体重误差在10%以内都是完美身材(即 | 真实体重 − 标准体重 | < 标准体重×10%). ...

  2. 添加MyEclipse WebSphere Portal Server支持(一)

    [周年庆]MyEclipse个人授权 折扣低至冰点!立即开抢>> [MyEclipse最新版下载] 一.支持WebSphere Portal Server 本文档介绍了如何支持和开发 We ...

  3. css 课堂笔记

    css:层叠样式表  Cascading( [kæ'skeɪdɪŋ] 级联)Style Sheet css基本语法结构:选择器{ 属性:值; 属性:值: ... } 三种主要的选择器: 标签选择器: ...

  4. 2018-2019-2 网络对抗技术 20165202 Exp5 MSF基础应用

    博客目录 一.实践目标 二.实践内容 一个主动攻击实践,ms08_067(成功).ms03_026(成功且唯一); 一个针对浏览器的攻击,如ms11_050(成功)ms11_03(失败.唯一)ms10 ...

  5. redis的主从复制和高可用集群

    一.redis的简介 Redis是一个开源的使用ANSI C语言编写.支持网络.可基于内存亦可持久化的日志型.Key-Value数据库,并提供多种语言的API.redis是一个key-value存储系 ...

  6. torch7 安装 并安装 hdf5模块 torch模块 nn模块 (系统平台为 ubuntu18.04 版本)

    今年的CCF A会又要开始投稿了,实验室的师弟还在玩命的加实验,虽然我属于特殊情况是该从靠边站被老板扶正但是实验室的事情我也尽力的去帮助大家,所以师弟在做实验的时候遇到了问题也会来问问我,这次遇到的一 ...

  7. 安卓手机文件管理器简单横向评比 - imsoft.cnblogs

      X-plore文件管理器 个人评价:安卓手机上管理文件的神器,所有文件一览无余,加上自己对软件常用功能的配置,管理文件无比方便.(本人一直使用)   Solid文件管理器 个人评价:用户体验真的很 ...

  8. Unity3D-常用小功能详解,例子(得分变动效果、倒计时)

    Unity3D-Demo多个功能方法 本文提供全流程,中文翻译.Chinar坚持将简单的生活方式,带给世人!(拥有更好的阅读体验 -- 高分辨率用户请根据需求调整网页缩放比例) 1 Score Ind ...

  9. 20155225 2016-2017-2 《Java程序设计》第五周学习总结

    20155225 2006-2007-2 <Java程序设计>第五周学习总结 教材学习内容总结 使用try.catch异常处理,异常处理继承架构等 使用Collection收集对象,了解C ...

  10. t添加最佳视口

    <!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title>& ...