技术标签: webview python android 手机端
import time
from appium.webdriver import Remote
# 启动一次请求
caps = {"platformName": "Android",
"udid": "emulator-5554",
"appPackage": "com.lemon.lemonban",
"appActivity": ".activity.WelcomeActivity"
}
driver = Remote(command_executor='http://127.0.0.1:4723/wd/hub',
desired_capabilities=caps)
# 设置隐性等待
driver.implicitly_wait(10)
# 获取app当前活动页面名称
print(driver.current_activity)
# 获取源代码XML
driver.page_source
# 获取定位
print(driver.location)
# 获取设置的capabilities
print(driver.capabilities)
driver.quit()
运行结果:
import time
from appium.webdriver import Remote
# 启动一次请求
# 1.指明需要连接的服务地址和端口号
# 2.You must include a platformName capability
caps = {"platformName": "Android",
"udid": "emulator-5554",
"appPackage": "com.lemon.lemonban",
"appActivity": ".activity.WelcomeActivity"
}
driver = Remote(command_executor='http://127.0.0.1:4723/wd/hub',
desired_capabilities=caps)
# 设置隐性等待
driver.implicitly_wait(10)
el = driver.find_element('xpath', '(//*[@resource-id="com.lemon.lemonban:id/category_description"])[8]')
# 获取元素的文本
print(el.text)
# 获取元素的尺寸
print(el.rect)
time.sleep(3)
driver.quit()
运行结果:
用法跟selenium中的用法是一样的,但有个注意点:如果想输入中文,必须要设置两个参数
在现在的手机中,滑动操作是常见的操作,如果引导页的滑动,刷新,向上一直滑动加载新内容等
如引导页是一个元素,所以只能通过滑动操作来控制元素
driver.swipe(start_x=700, end_x=10, start_y=500, end_y=10)
这种固定的写法不可取,为什么呢?因为我们现在的手机尺寸有大有小,这样就会造成在这个手机上能执行,在那个手机上不能执行,所以我们要想一种不同尺寸的手机都可以执行的写法,因此我们可以使用比例控制
第一步:我们要得到屏幕的尺寸,使用到get_window_size()方法得到width与height的值,看源码可知返回值是个字典,因此可以取出key的value
print(driver.get_window_size())运行结果:{'width': 900, 'height': 1600}
第二步:使用屏幕的比例来进行滑动,如从右往左滑动,从屏幕宽度的90%滑动到10%的位置,高度不变
driver.swipe(start_x=width * 0.9, end_x=width * 0.1, start_y=height * 0.5, end_y=height * 0.5)
具体代码如下:
import time
from appium.webdriver import Remote
# 启动一次请求
caps = {"platformName": "Android",
"udid": "emulator-5554",
"appPackage": "com.xxzb.fenwoo",
"appActivity": ".activity.addition.SplashActivity",
"unicodeKeyboard": True,
"resetKeyboard": True
}
driver = Remote(command_executor='http://127.0.0.1:4723/wd/hub',
desired_capabilities=caps)
# 设置隐性等待
driver.implicitly_wait(10)
# 滑动操作
# 1.获取屏幕的宽度和高度
# 2.从右到左滑动
width = driver.get_window_size()['width']
height = driver.get_window_size()['height']
driver.swipe(start_x=width * 0.9, end_x=width * 0.1, start_y=height * 0.5, end_y=height * 0.5)
driver.swipe(start_x=width * 0.9, end_x=width * 0.1, start_y=height * 0.5, end_y=height * 0.5)
driver.swipe(start_x=width * 0.9, end_x=width * 0.1, start_y=height * 0.5, end_y=height * 0.5)
driver.quit()
这种方法有没有觉得太重复了,因此我们可以进行封装,这样就可以调用了,所以我们可以封装到basepage类中
basepage.py代码如下:
class BasePage:
def __init__(self, driver):
self.driver = driver
def width(self):
"""获取app的宽度"""
return self.driver.get_window_size()['width']
def height(self):
"""获取app的高度"""
return self.driver.get_window_size()['height']
def swipe_left(self):
"""从右往左滑动"""
self.driver.swipe(start_x=self.width() * 0.9, end_x=self.width() * 0.1,
start_y=self.height() * 0.5, end_y=self.height() * 0.5)
def swipe_right(self):
"""从左往右滑动"""
self.driver.swipe(start_x=self.width() * 0.1, end_x=self.width() * 0.9,
start_y=self.height() * 0.5, end_y=self.height() * 0.5)
def swipe_up(self):
"""从下往上滑动"""
self.driver.swipe(start_x=self.width() * 0.5, end_x=self.width() * 0.5,
start_y=self.height() * 0.9, end_y=self.height() * 0.1)
def swipe_down(self):
"""从上往下滑动"""
self.driver.swipe(start_x=self.width() * 0.5, end_x=self.width() * 0.5,
start_y=self.height() * 0.1, end_y=self.height() * 0.9)
调用代码如下:
from basepage import BasePage
from appium.webdriver import Remote
# 启动一次请求
caps = {"platformName": "Android",
"udid": "emulator-5554",
"appPackage": "com.xxzb.fenwoo",
"appActivity": ".activity.addition.SplashActivity",
"unicodeKeyboard": True,
"resetKeyboard": True
}
driver = Remote(command_executor='http://127.0.0.1:4723/wd/hub',
desired_capabilities=caps)
# 设置隐性等待
driver.implicitly_wait(10)
# 滑动操作
# 直接调用BasePage类中的方法即可
BasePage(driver).swipe_left()
BasePage(driver).swipe_left()
BasePage(driver).swipe_left()
driver.quit()
运行结果是一样的,虽然封装的过程麻烦,但之后再调用就会很方便,而且也方便代码维护
app的路径依赖是很严重的,如果需要测试某个单独的页面,但是进入这个页面有很长的路径,则会严重影响效率,而且路径过长,会让测试程序不稳定
start_activity可以快速进入指定页面,只需要指定activity的名称即可
获取当前页面的名称:
adb shell -s 设备名称 dumpsys activity | find "mResumedActivity" (如果有多台设备加上-s)
注意:要获取哪个页面名称,一定要打开app的那个页面
代码如下:
driver.start_activity('com.lemon.lemonban', '.activity.LoginActActivity')
在不同的app中都可以使用,直接跳转到设置的页面
# 按键操作
# 1.选通过功能查对应的事件数字
# 2.通过press_keycode()方法发送
driver.press_keycode(24)
具体的按键对应的事件数字可参考此网站:https://www.jianshu.com/p/f7ec856ff56f
注意:相机键模拟器是无法进行操作的,只能真机操作
上面的代码可读性太差,时间长了肯定就不记得24代表什么了,因此我们进行封装,增强可读性,封装的代码也可以放到basepage.py中
class MobileKey:
ENTER = 66
VOLUME_UP = 24
VOLUME_DOWN = 25
调用MobileKey中的类属性
driver.press_keycode(MobileKey.VOLUME_UP)
还可以把常用的方法进行二次封装,代码如下:
class MobileKey:
ENTER = 66
VOLUME_UP = 24
VOLUME_DOWN = 25
BACK = 4
class BasePage:
def __init__(self, driver):
self.driver = driver
def enter(self):
"""回车"""
self.driver.press_keycode(MobileKey.ENTER)
def volume_up(self):
"""音量加"""
self.driver.press_keycode(MobileKey.VOLUME_UP)
def volume_down(self):
"""音量减"""
self.driver.press_keycode(MobileKey.VOLUME_DOWN)
def back(self):
"""返回"""
self.driver.press_keycode(MobileKey.BACK)
调用BasePage类中的方法即可
BasePage(driver).volume_up()
前提:
登录:Toast是viewer识别不到的,但是我们需要确认文本是否正确
因为现在 appium server的版本比较高,默认使用的也是UiAutomator2,所以上面提到的前提不用特意设置
定位表达式:
from appium.webdriver import Remote
# 启动一次请求
caps = {"platformName": "Android",
"udid": "emulator-5554",
"appPackage": "com.lemon.lemonban",
"appActivity": ".activity.WelcomeActivity",
"unicodeKeyboard": True,
"resetKeyboard": True,
"automationName": "UiAutomator2"
}
driver = Remote(command_executor='http://127.0.0.1:4723/wd/hub',
desired_capabilities=caps)
# 设置隐性等待
driver.implicitly_wait(10)
# 查找元素输入账号密码,点击登录按钮
driver.start_activity('com.lemon.lemonban', '.activity.LoginActActivity')
driver.find_element('id', 'com.lemon.lemonban:id/et_mobile').send_keys('123')
driver.find_element('id', 'com.lemon.lemonban:id/et_password').send_keys('123')
driver.find_element('id', 'com.lemon.lemonban:id/btn_login').click()
el = driver.find_element('xpath', '//android.widget.Toast')
# 断言
assert el.text == '手机号码格式不正确'
driver.quit()
注意:以上所有的代码最后一定要加上driver.quit(),否则非正常关闭,下次再跑代码就会报错,这是appium的一个bug
原生应用是使用系统原生的组件开发的app,需要特定的语言,比如android的java,kotlin,ios的swift,object c
H5技术可以使用web技术开发app,原生和H5的组合就成了混合应用
混合应用不是在app上直接写HTML页面,而是把H5页面放在一个webview控件当中
webview是原生应用的一种控件,还有其他ImageView等,webview能做到和web页面交互的功能
常用的混合应用技术框架:
如何区分是原生页面还是web网页:
方式一:UI上区分:看页面上方有没有进度条与关闭按钮
方式二:利用元素定位区分:原生页面是有很多元素,而且好定位,而web页面整个页面是一个元素,并且class名称是固定的android.webkit.WebView
方式三:下拉页面,背面会出现一个网址(这个不一定有)
方式四:网页定位工具chrome://inspect(这个是判断是不是webview最可靠的工具,但不稳定,速度慢,经常打不开定位元素页面)
chrome://version/查看一些信息
输入chrome://inspect,可以打开DevTools工具,下图是连接上了设备后的显示
当app中打开了一个网页时,刷新DevTools工具,可以查看到关于网页的相关信息,需要注意的是显示的chrome版本是手机端的不是浏览器的版本
点击inspect,就进入了定位元素的页面,其实就是F12的功能
方式五:当方式四不好用的时候,可以下载一个UC-DevTools工具,下载网址:https://dev.ucweb.com/docs/pwa/docs-zh/xy3whu
下载安装好,打开界面如下:
注意:设置中一定要选择本地资源
点击inspect后,进入元素定位页面,可以看到跟网页的那个显示是一样的
三种等待方法(同selenium用法)
文章浏览阅读467次。计算机毕业设计Java疫情防控医用品管理(系统+源码+mysql数据库+Lw文档)springboot基于SpringBoot的婚庆策划系统的设计与实现。JSP健身俱乐部网站设计与实现sqlserver和mysql。JSP网上测试系统的研究与设计sqlserver。ssm基于SpringMvC的流浪狗领养系统。ssm基于Vue.js的音乐播放器设计与实现。ssm校园流浪猫图鉴管理系统的设计与实现。_疫情防护用品销售管理系统 论文
文章浏览阅读988次,点赞28次,收藏28次。最后小编想说:不论以后选择什么方向发展,目前重要的是把Android方面的技术学好,毕竟其实对于程序员来说,要学习的知识内容、技术有太多太多,要想不被环境淘汰就只有不断提升自己,从来都是我们去适应环境,而不是环境来适应我们!这里附上我整理的几十套腾讯、字节跳动,京东,小米,头条、阿里、美团等公司19年的Android面试题。把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节。由于篇幅有限,这里以图片的形式给大家展示一小部分。
文章浏览阅读600次,点赞11次,收藏6次。*单片机设计介绍,基于单片机数码管秒表控制系统设计。
文章浏览阅读235次。python小程序之验证码图片的生成定义随机字母的生成函数定义随机颜色生成函数,采用RGB格式,生成一个元组调用Image,生成画布,填充底色为白色调用画笔函数Draw,传入画布对象填充画布的每一个色块,作为背景在画布上控制间距,填上每一个字在最后的图上进行模糊操作代码# 生成一个随机的二维码小程序from PIL import Image,ImageDraw,ImageF..._小程序图片验证码后端生成
文章浏览阅读2.2k次。 1. 用户需求分析客户规模:客户有一个总部,具有一定规模的园区网络; 一个分支机构,约有20-50名员工; 用户有很多移动办公用户 客户需求:组建安全可靠的总部和分支LAN和WAN; 总部和分支的终端需要提供安全防护,并实现网络准入控制,未来实现对VPN用户的网络准入检查; 需要提供IPSEC/SSLVPN接入; 在内部各主要部门间,及内外网络间进_思科设备怎么ranga)服务器区域独立防护;
文章浏览阅读445次。4、转移账号生成的 p8 文件(证书文件)1、转移苹果账号的 teamID。2、接受苹果账号的 teamID。5、接受账号生成的 p8 文件。3、转移应用的 AppID。_apple 账号迁移
文章浏览阅读1k次。https://blog.csdn.net/u012328159/article/details/80311892_momentum seg
文章浏览阅读816次。主要的原理就是替换模板里的特殊字符。 1、静态模板页面 template.html,主要是定义了一些特殊字符,用来被替换。 HTML code DOCTYPE HT_监听数据变更自动生成静态html
文章浏览阅读494次。 今日在做一个新闻系统的评论时. 想到了预防"提交"按钮的多次点击的问提 (prevent multiple clicks of a submit button in ASP.NET). 以前碰到此类问提总是用重定位页面来解决. 这次我想找到一个一劳永逸的办法. 通过查讯Google,找到了一些代码,挑选一些较好的修改了一下。public void pa
文章浏览阅读4.7k次。近来公司业务有需要做socks5代理的需求,研究了一下,主要的开源实现有2个:dante http://www.inet.no/dante/ss5 http://ss5.sourceforge.net/比较了一下,还是比较倾向于dante,因为看到有人这样评价ss5:Project has an incredibly poor source code quality. Th_dante 代理 配置pam用户名密码 模式
文章浏览阅读809次。在excel vba 中用到countifs 函数,但用来统计带有特殊符号* 时总是统计chu_vba countifs 源码
文章浏览阅读2.6k次。当两个效果之间变换时,可以使用transition过渡属性,但是有多个效果来回变换时,就需要使用动画效果,且动画过程可控(重复播放,画面暂停,最终画面等)文章目录1、简介2、实现步骤3、复合属性animation4、动画属性1、简介动画的本质是快速切换大量图片在人脑中形成的具有连续性的画面构成动画的最小单元:帧或者动画帧2、实现步骤定义动画@keyframes 动画名称{ from{} to{}}@keyframes 动画名称{ 0%{} 10%{} 20%{} 50._web前端实现图片动画效果