2023年6月30日发(作者:)
python写⾃动化测试脚本常见报错_Appium⾃动化测试3. Appium安装配置3.1. 限制如果你在windows上安装appium,你没法使⽤预编译专⽤于OS X的.app⽂件,你也将不能测试IOS apps,因为appium依赖OS X专⽤的库来⽀持IOS测试。这意味着你只能通过在mac上来运⾏IOS的app测试。这点限制挺⼤。3.2. 傻⽠式安装3.2.1. 查看是否安装成功nodejs安装完毕后,需要配置环境变量在PATH中添加:D:Program Filesnodejs;3.3. 傻⽠式安装Appium3.3.1. 成功界⾯3.4. 配置appium环境变量C:Program Files (x86)Appiumnode_3.5. 打开控制台,查看appium环境3.5.1. appium-doctor3.6. 配置Android— 环境变量F:adt-bundle-windows-x86_64_20140101sdk3.7. Python中配置appium环境(联⽹)进⼊:D:pythonScripts打开控制台:pip install Appium-Python-client3.8. 总结:1) android sdk安装完毕后,需要配置环境变量新建ANDROID_HOME在PATH中添加:%ANDROID_HOME%:.....2) nodejs安装完毕后,需要配置环境变量在PATH中添加:D:Program Filesnodejs;3) appium安装完毕后,需要配置环境变量D:Program Files (x86)Appiumnode_;4) 配置好后,启动cmd,输⼊node -v,查看node安装版本输⼊appium-doctor检查appium的安装环境是否成功,5) 安装Python,配置环境变量,4. 第⼀个脚本⽰例4.1. ⾸先通过eclpse启动android模拟器4.2. 启动Appium4.3. 点击左上⾓有“机器⼈”的按钮:选择你的android版本4.4. 点击右上⾓的“三⾓”按钮启动Appium。4.5. 通过Python编写⾃动化测试脚本。desired_caps是⼀个字典,⽤于在appium server 与⼿机端建⽴会话关系时,⼿机端需要告诉服务端设备相关的⼀些参数,根据这些参数服务端可以做出相应的处理。#coding:utf-8from appium import webdriver#desired_caps是⼀个字典,负责启动服务端时的参数设置,启动session的时候是必须提供的。# Desired Capabilities本质上是key value的对象,它告诉appium server这样⼀些事情,⽐如:# 本次测试是启动浏览器还是启动移动设备?# 是启动andorid还是启动ios?# 启动android时,app的package是什么?# 启动android时,app的activity是什么desired_caps = {}#你要测试的⼿机操作系统desired_caps['platformName'] = 'Android'#⼿机操作系统的版本desired_caps['platformVersion'] = '4.2'#使⽤的⼿机类型或模拟器类型desired_caps['deviceName'] = 'Android'#deviceName你的模拟器名字,就是在下载AVD的时候,你填写的,忘了的回头去找,或者在模拟器顶部会显⽰#所运⾏的app包名desired_caps['appPackage'] = 'ator2'#app运⾏的事件desired_caps['appActivity'] = '.Calculator'#启动打开appdriver = ('127.0.0.1:4723/wd/hub', desired_caps)#根据元素定位,执⾏点击操作_element_by_name("6").click()_element_by_name("5").click()_element_by_name("9").click()_element_by_name("1").click()_element_by_name("5").click()_element_by_name("+").click()_element_by_name("6").click()_element_by_name("=").click()()报错解决⽅案会话已存在错误--解决⽅案,关掉appium,重启4.6. 画出来的这三个,是需要在脚本中正确填写的4.7. 执⾏效果5. Appium界⾯内容解析5.1. 整体介绍主页⾯顶部从左到右依次是:1、AndroidSettings:android相关的设置2、 GeneralSettings:全局设置,设置appium相关的内容3、 DeveloperSettings:开发者设置,⼀般不⽤需要关⼼4、About:appium相关信息,不需要关⼼5、Inspector:查找元素⽤的,windows⽆法使⽤,MAC可以使⽤,windows可以不⽤关⼼。6、LaunchAppium:启动appium按钮7、右下⾓清除⽇志按钮。5.2. Android Settings此页⾯分为Application、Launch Device、Capabilities、Advanced四部分,先看图之后分析分别有什么作⽤5.2.1. 1、Application本模块设置被测试app信息,如安装包路径、包名、activity等ApplicationPath:选择要测试的apk,选择他后与全局设置中的Pre-LaunchApplication配合,启动appium时会先把apk安装到⼿机(或模拟器)再启动app。Package:根据apk⽣成的app包名,之前提到过的,我们这个包的⾝份证,我们需要通过这个去找到包,不然我们安装后我们通过什么去辨别这些包呢?Waitfor Package:等待包名。LaunchActivity:启动的activity,我们可以把⼿机当做⼀个浏览器,⽽Activity就是其中的⼀个个⽹页,我们启动app时需要去运⾏的activity,这⾥我们填写⾸次启动页⾯的activity。我们选择第⼀启动的activity与aapt命令⽣成的launchable-activity:name⼀致备注:这⾥需要注意⼀个问题在我们每次通过Choose选择apk后,appium会⾃动把这个包进⾏重新签名,那么在package以及activity⾥⾯会⾃动把包名和activity的名称列进去,但是这⾥会出现⼀个问题,每次选择apk后列表中会有⼀个缓存的原因,即使你更改了apk,但是package还是没有变,这样启动的时候就⼀直报错,遇见这样的情况不要着急,重新启动两次就好。Waitfor Activity:和上⾯的差不多,意思是等待某个Activity打开,⽤的时间不是很多,做了解。UseBrowser:测试浏览器选择这项,与前五项互逆。及选择了他前五个就不可以选择。FullReset:将所有设置复位。即将⼿机(模拟器)恢复到启动到appium前的状态NoReset:不需要重置⼿机(模拟器)中的app剩下的⼏项不重要。可以不需要知道作⽤。6.2.2. Launch Device本模块是模拟器设置,针对的是SDK创建的模拟器,不是genymotion等其他模拟器。LaunchAVD:要启动的模拟器名称。DeviceReady Timeout:等待模拟器启动时间。Arguments:启动模拟器时需要的参数。lities运⾏测试的相关信息。PlatformName:测试平台,可以选择Android、FireFox OS、MAC版的还可以选择IOS。utomationName:测试引擎的名称,我们使⽤的是appium,所以你第⼀眼就能看见Appium,但是他还有⼀个Selendroid。可能看到这⾥会有⼀些疑惑,为什么appium要选择两套系统呢?其实这个应该追溯到android的版本问题,android⾃⼰的⼯具在4.2版本以前是⼀个,但是后⾯进⾏了更新,可能也正是因为这个原因appium也才采⽤了两套,所以当你测试的app安装的机器时在4.2或之前的版本时那么这⾥的引擎你就必须选择Selendroid,PlatformVersion:被测试⼿机(模拟器)版本。DeviceName:设备名称,⼿机连接电脑后打开cmd输⼊adb devices可获取。Language:被测试⼿机(模拟器)使⽤语⾔。Locale:被测试⼿机(模拟器)所属区域。5.2.2. Advanced此模块不需要关⼼,这个标签只是在你想同⼀台电脑同时控制多台⼿机的时候才能使⽤,需要更改Bootstrap Port的端⼝号,记住这⼀点就好。5.3. General Setting全局设置,分为Server和Logging两个,分别是对appium服务和输出⽇志的设置5.3.1. 1、Server此模块测试appium server信息ServerAddress:如果测试机与开发机是同⼀台机器默认即可,否则写appium所在服务器IPport:默认4723,可修改。CheckFor Updates:启动appium时是否检测更新Pre-LaunchApplication:与Android Settings中的Application模块的ApplicationPath配合,启动appium后会直接启动安装的app。OverridingExisting Session:覆盖之前的session。UseRomote Server:使⽤远程appium Server。SeleniumGrid Configuration File:配置Selenium Grid⽂件。并发和分布式时⽤到。5.3.2. 2、Logging⽇志设置ShowTimestamps:appium界⾯输出⽇志时带时间戳Logto File:默认状态是没有任何数据,但是在做⾃动化时建议选择,因为选择之后appium在运⾏时产⽣的⽇志都会保留到你设置的问题件,这个对后期的bug定位有相当⼤的帮助。切记!5.4. 元素侦测:这个按钮的功能和firebug的定位⼯具功能类似,但是他还有⼀个功能,他会检测你的各个系统配置是否正确,如果前⾯各项参数不正确时,使⽤该功能会报错。如果你不正常连接⼿机也不⾏。还是建议⽤sdk⼯具⾥⾯⾃带的uiautomatorviewer。5.5. 启动服务所有参数配置好后你需要做的就是启动appium服务,只有启动之后你才能够做⾃动化。5.6. 清除⽇志(右下⾓):在写脚本、调试过程中会产⽣很多的⽇志,但是你可能想看的只是中间某个时间段的,那么你在这个时候可以将页⾯的⽇志清除。6. Appium查看界⾯元素的⼯具6.1. 通过android sdk的uiautomaterviewer获取元素内容uiautomaterviewer所在⽬录:..是⼀个⽤来来扫描和分析Android应⽤程序的UI组件的GUI⼯具。具体使⽤⽅法可参考。打开uiautomatorviewer以后,可以看到uiautomatorviewer已经将模拟器的图形展⽰在上⾯了。6.2. 右侧xml节点详解节点名 解释index ⽗⽬录下的第⼏个元素,以0开头text 显⽰在界⾯上的内容resource-id 该元素的id(开发不规范时,此id有可能会不存在或多个相同)class 元素的类型package apk的包名content-desc 描述信息checkable 元素特征:是否可选择checked 元素特征:当前是否已选中chlickable 元素特征:是否可点击enabled 元素特征focusable 元素特征focused 元素特征scrollable 元素特征long-clickable 元素特征password 元素特征selected 元素特征bounds 边界,左上⾓和右下⾓的坐标(从屏幕最左侧和最上侧开始)6.3. 使⽤过程常见问题打不开uiautomaterviewer解决⽅法:以⽂本⽅式打开此⽂件,更改⽂件结尾处的="$progdir"为="sdk下tools⽂件夹的路径"7. 获取appPackage和appActivityappPackage和appActivity 进⾏appium⾃动化测试⾮常重要的两个参数,我们所测试的APP不同,这两个参数肯定也是不⼀样的。那如何快速的获取这APP的这两个参数呢7.1. ⽅法⼀:通过cmd指令来获取1. adb shell2. dumpsys activity | grep mFocusedActivity3、adb shell dumpsys activity activities >E:7.2. ⽅法⼆:使⽤Appium来获取进⼊设置页,选择APK 路径,下⾯就会显⽰包名和Activity名称8. Appium常⽤定位⽅法讲解对象定位是⾃动化测试中很关键的⼀步,也可以说是最关键的⼀步,毕竟你对象都没定位那么你想操作也不⾏,下⾯我们来看我们常⽤的⼀些定位⽅式。8.1. ID定位(取resource-id的值):⽆论是在web⾃动化还是app⾃动化中id都是唯⼀的,可能有的⼩伙伴看到这⾥会有疑问,因为有的资料说是通过name定位是唯⼀的,为什么你这⾥是id呢,其实这个在之前是不冲突的,但是如果你⽤的是appium较新版本是不⾏的,在新版本中name定位被去掉了,所以在以后的定位中不会有name定位了,通常情况下我们也更喜欢⽤id进⾏定位。这⾥可能刚学的⼩伙伴会有疑问,有的时候你的应⽤为什么没有id,或者说在这个⼿机上有但是另外的⼿机上没有。1、开发没有添加。2、android版本是4.4以下的。如果我们需要对“7”这个数字进⾏点击操作,_element_by_id("ator2:id/digit7").click()8.2. 通过name定位元素(⼀般text属性认为是name)_element_by_name("5").click()8.3. className定位(取class的内容)在实际⼯作中className定位⽤得相对⽽⾔会⽐较少。当你经常去看class时你会发现很多的className是⼀样的,你没有办法对其进⾏唯⼀定位,下⾯我们看下⾯两张图⽚我们可以仔细看⼀下这两张图⽚中⼿机号、密码两个输⼊框中的className都是⼀样的,如果在这种情况下你使⽤_element_by_class_name("xt").send_keys("111111")这种⽅式去定位,你会发现你永远定位不了密码栏,这是为什么呢?因为在设计的时候如果你查找的元素在页⾯有多个,系统会⾃动给你选择第⼀个,所以你永远操作不了后⾯的8.4. text定位(需要使⽤uiautomator的定位⽅式,使⽤text的内容)_elements_by_android_uiautomator("new UiSelector().text('7')")使⽤这⾥需要注意⼀下,如果通过text定位的结果是个list,不能直接click。所以如果要点击需要取数组的值,⽐如下⾯是点击找到的第⼀个元素_elements_by_android_uiautomator("new UiSelector().text('7')")[0].click()8.5. xpath定位xpath定位在web⾃动化中是最常见的,⽽且也是最有效的,使⽤xpath定位避免了找不到元素导致报错的问题,但是在app中使⽤xpath定位是⼀件很low的事情。只要遇见使⽤xpath定位元素他的反应就会⽐较慢,⾃动化的⽬的是为了提⾼效率,但是使⽤xpath后会降低效率,所以这⾥说很 low在上⾯两张图⽚中我们能够清除的看见他们的id、className都是⼀样的,这样的情况下不⽤层级定位⽅式我们只能够采⽤xpath来进⾏定位,⾸先根据前⾯web的学习⼤家可以思考⼀下该怎么定位。我们直接看代码_element_by_xpath("//ew[@text='JavaScript']").click()在xpath⾥⾯我们的语法是这样“//ew[@text='JavaScript']”,这个和我们之前web的xpath⼀样,意思是查找所有节点中节点为ew (这⾥使⽤的是className,也可以使⽤id,系统会依次去找)并且他的text属性值为JavaScript,这样是否更容易理解呢?下来多练习。这样的定位⽅式不推荐,效率很慢。8.6. css_selector定位(webview)--加载⽹页--css只适⽤于webview的html页⾯,继承⾃webdriver,与pc版本的UI测试⼀致_element_by_css_selector()8.7. link_text定位(webview)只适⽤于webview容器中的html页⾯,继承⾃webdriver,与pc版本的UI测试⼀致_element_by_link_text()8.8. 源代码#coding:utf-8from appium import webdriver#desired_caps是⼀个字典desired_caps = {}#你要测试的⼿机操作系统desired_caps['platformName'] = 'Android'#⼿机操作系统的版本desired_caps['platformVersion'] = '7.0'#使⽤的⼿机类型或模拟器类型desired_caps['deviceName'] = 'XPUDU'#deviceName你的模拟器名字,就是在下载AVD的时候,你填写的,忘了的回头去找,或者在模拟器顶部会显⽰#所运⾏的app包名desired_caps['appPackage'] = ''#app运⾏的事件desired_caps['appActivity'] = '.MainActivity'#启动打开appdriver = ('127.0.0.1:4723/wd/hub', desired_caps)#根据元素定位,执⾏点击操作# user= _element_by_name("请输⼊⽤户名")# user = _element_by_id(":id/et_username")_element_by_class_name("xt").send_keys("jilidaxue")# _element_by_id(":id/et_password").send_keys("66889558")# _keys("liangyibo")_element_by_xpath("//xt[@text='请输⼊密码']").send_keys("233254545")# pwd = _element_by_name("请输⼊密码")# _keys("123456")# # _element_by_xpath("//ayout[1]//Layout[3]").click()_element_by_xpath("//[@text='登录']").click()()9. Appium操作界⾯元素9.1. 安装上两个apk,供测试使⽤9.2. Click(点击事件操作)定位元素点击元素_element_by_id("huan:id/ae8").click()⽅法⼆:(了解)除了定位到元素的点击外,也可以通过tab实现坐标的点击通过触摸时间控制点击tap()tap([左上⾓坐标,右下⾓坐标],持续时间)通过定位⼯具获取坐标值([540,243][1080,363]),03-查看界⾯元素的⼯具使⽤tap()⽅法点击元素([(918,413),(1026,521)], 100) #持续时间100是指100毫秒9.3. Clear(清空输⼊框内容)定位输⼊框元素清空输⼊框的内容_element_by_id("huan:id/ij").clear()9.4. send_keys(输⼊框内输⼊内容 )1.定位输⼊框元素2.输⼊(发送)内容_element_by_id("huan:id/ij").send_keys("test content")9.5. Text(获得元素的text内容 )1.定位元素2.获取元素内容_elements_by_class_name("xt")[0].text;9.6. 编写脚本代码#coding:utf-8from appium import webdriver#desired_caps是⼀个字典desired_caps = {}#你要测试的⼿机操作系统desired_caps['platformName'] = 'Android'#⼿机操作系统的版本desired_caps['platformVersion'] = '7.0'#使⽤的⼿机类型或模拟器类型desired_caps['deviceName'] = 'XPUDU'#deviceName你的模拟器名字,就是在下载AVD的时候,你填写的,忘了的回头去找,或者在模拟器顶部会显⽰#所运⾏的app包名desired_caps['appPackage'] = ''#app运⾏的事件desired_caps['appActivity'] = '.MainActivity'#启动打开appdriver = ('127.0.0.1:4723/wd/hub', desired_caps)#根据元素定位,执⾏点击操作#1、通过name定位元素# user= _element_by_name("请输⼊⽤户名")#2、通过id定位元素user = _element_by_id(":id/et_username")#3、通过class_name定位元素,对元素进⾏清空,再发送内容为:jilidaxue# user = _element_by_class_name("xt").clear().send_keys("jilidaxue")#4、通过id定位元素,发送内容为66889558# _element_by_id(":id/et_password").send_keys("66889558")_keys("liangyibo")#5、打印获取的text属性值,⽂本内容print()#6、通过Xpath定位元素,输⼊密码_element_by_xpath("//xt[@text='请输⼊密码']").send_keys("233254545")#7、通过Xpath定位登录元素,进⾏点击操作_element_by_xpath("//[@text='登录']").click()#8、退出操作()10. Appium操作界⾯之触摸操作(了解)10.1. 规范中的可⽤事件有:* 短按 (press)* 释放 (release)* 移动到 (moveTo)* 点击 (tap)* 等待 (wait)* 长按 (longPress)* 取消 (cancel)* 执⾏ (perform)10.2. 单点触摸TouchAction(driver)通过TouchAction对象,添加tap、move_to等操作,然后perform()执⾏,可以实现解锁屏幕等功能action=TouchAction(driver)(x=220,y=700).move_to(x=840,y=700).move_to(x=220, y=1530).move_to(x=840,y=1530).release().perform()10.3. 多点触控MultiAction()通过MultiAction().add()添加多个TouchAction操作,最后调⽤perform()⼀起执⾏这些操作举例action0 = TouchAction().tap(el)action1 = TouchAction().tap(el)MultiAction().add(action0).add(action1).perform()10.4. 滑动(x1, y1,x2,y2,duration)命令解释:从坐标(x1,x2)滑动到坐标(x2,y2),duration⾮必填项,滑动时间(滑动时中间要加等待时间,不加等待时间容易出错,⽽且加等待时间的长短也要掌握好,⼀般在200-1000毫秒之间应该差不多,⾃⼰调试⼏次感觉⼀下哪个时间⽐较稳,每个程序可能会有所差异)滑动的坐标不能超过屏幕的宽⾼可以通过【_window_size()】命令获得窗⼝⾼和宽{'width': 1080, 'height': 1788}# 获得机器屏幕⼤⼩x,ydef getSize(driver):x = _window_size()['width']y = _window_size()['height']return (x, y)# 屏幕向上滑动def swipeUp(driver, t=500):l = getSize(driver)x1 = int(l[0] * 0.5) # x坐标y1 = int(l[1] * 0.75) # 起始y坐标y2 = int(l[1] * 0.25) # 终点y坐标(x1, y1, x1, y2, t)# 屏幕向下滑动def swipeDown(driver,t=500):l = getSize(driver)x1 = int(l[0] * 0.5) # x坐标y1 = int(l[1] * 0.25) # 起始y坐标y2 = int(l[1] * 0.75) # 终点y坐标(x1, y1, x1, y2, t)# 屏幕向左滑动def swipLeft(driver,t=500):l = getSize(driver)x1 = int(l[0] * 0.75)y1 = int(l[1] * 0.5)x2 = int(l[0] * 0.05)(x1, y1, x2, y1, t)# 屏幕向右滑动def swipRight(driver,t=500):l = getSize(driver)x1 = int(l[0] * 0.05)y1 = int(l[1] * 0.5)x2 = int(l[0] * 0.75)(x1, y1, x2, y1, t)10.5. 长按⽰例# [0,219][1080,363] ----获取某个按钮的位置,执⾏长按操作touch=TouchAction(driver)_press(x=100,y=250).perform();10.6. 滑屏⽰例10.6.1. 安装涂鸦app10.6.2. 打开界⾯,使⽤如下指令,查看activity和package10.6.3. 编写python脚本代码#coding:utf-8from appium import webdriver#desired_caps是⼀个字典from _action import TouchActiondesired_caps = {}#你要测试的⼿机操作系统desired_caps['platformName'] = 'Android'#⼿机操作系统的版本desired_caps['platformVersion'] = '7.0'#使⽤的⼿机类型或模拟器类型desired_caps['deviceName'] = 'XPUDU'#deviceName你的模拟器名字,就是在下载AVD的时候,你填写的,忘了的回头去找,或者在模拟器顶部会显⽰#所运⾏的app包名desired_caps['appPackage'] = 'ti'#app运⾏的事件desired_caps['appActivity'] = '.MainActivity'#启动打开appdriver = ('127.0.0.1:4723/wd/hub', desired_caps)#根据元素定位,执⾏点击操作action=TouchAction(driver)(x=120,y=200).move_to(x=100, y=180).release().perform()()11. 系统按键事件(了解)press_keycode(AndroidKeyCode)#发送按键事件例如:点击home键,home键的KeyCode是312. driver的⼀些⽐较重要操作12.1. reset()#重置app#这时候driver会重置,相当于卸载重装应⽤。所以本地缓存会失效()12.2. start_activity(包名,activity名)例如:#启动app的某⼀个_activity("huan","./Activity")启动⼀个activity,这个activity必须是中有intent-filter的activity,对于其他的activity需要程序跳转过去12.3. scroll(起始元素,结束元素)(origin_el,destination_el)12.4. 获得当前页⾯的所有元素_source这可以⽤来判断元素是否存在,例如(assert “发布成功” in _source)12.5. 补充⼀些driver启动时可能⽤到的项(了解)其实这些在上⼀篇启动⾥都有介绍,但是有些可能⼤家没注意到的点再列⼀下。这些点也是我在测试中实际遇到的点autoLaunch :Appium是否要⾃动启动或安装app,默认truedesired_caps[‘autoLaunch’] = ‘false’有的时候我不想让appium每次都启动app,想⾃⼰去启动activity,那这个项这时就可以起作⽤了noReset:在会话前是否重置app状态。默认是falsedesired_caps[‘noReset’] = ‘true’newCommandTimeout:设置未接收到新命令的超时时间,默认60s如果60s内没有接收到新命令,appium会⾃动断开连接,如果我需要很长时间做driver之外的操作,可能延长接收新命令的超时时间desired_caps[“newCommandTimeout”]=180013. ⾃动化测试简单案例-登录13.1. 打开UI Automator Viewer13.2. 代码实现_element_by_id(":id/et_username").send_keys("hello");_element_by_id(":id/et_password").send_keys("123");_elements_by_class_name("")[1].click()14. ⾃动化测试案例2-转转14.1. 下载转转,并打开,在初始界⾯查看包和activity14.2. 使⽤UI Automator Viewer查看转转按钮14.3. 点击跳过#强制等待3秒钟(3)#跳过按钮#_element_by_id("huan:id/arw").click()14.4. 点击分类itly_wait(10)#分类按钮_element_by_id("huan:id/b1v").click()itly_wait(10)#搜索按钮_element_by_id("huan:id/b1p").click()itly_wait(10)#搜索框中输⼊搜索内容_element_by_id("huan:id/mg").send_keys(u"电动车")(10)#点击搜索_element_by_id("huan:id/mi").click()()15. 启信宝案例#coding:utf-8fromappium importwebdriver#desired_caps是⼀个字典desired_caps = {}#你要测试的⼿机操作系统desired_caps['platformName'] = 'Android'#⼿机操作系统的版本desired_caps['platformVersion'] = '7.0'#使⽤的⼿机类型或模拟器类型desired_caps['deviceName'] = 'XPUDU'#deviceName你的模拟器名字,就是在下载AVD的时候,你填写的,忘了的回头去找,或者在模拟器顶部会显⽰#所运⾏的app包名desired_caps['appPackage'] = ''#app运⾏的事件desired_caps['appActivity'] ='.Activity'#启动打开appdriver = ('127.0.0.1:4723/wd/hub', desired_caps)#根据元素定位,执⾏点击操作itly_wait(10)serh = _element_by_id(":id/tv_home_search_desc")()_element_by_id(":id/et_search_content").send_keys("优思安科技")()
发布者:admin,转转请注明出处:http://www.yc00.com/xiaochengxu/1688092140a79677.html
评论列表(0条)