Appium上下文和H5测试(二)

{"type":"doc","content":[{"type":"heading","attrs":{"align":"center","level":2},"content":[{"type":"text","text":"坚持原创输出,点击蓝字关注我吧","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/6c/6c566c07e586927aa4268eeb3baf4ea3.png","alt":null,"title":null,"style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"作者:清菡","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"博客:oschina、云+社区、知乎等各大平台都有。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":"center","level":2},"content":[{"type":"text","text":"文章总览图","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/8e/8e21659ecfc6b6766c14be44051c13b3.png","alt":null,"title":null,"style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"一、往期回顾","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"python"},"content":[{"type":"text","text":"loc='new UiSelector().text(\"全程班\")'\nWebDriverWait(driver,20).until(EC.visibility_of_element_located((MobileBy.ANDROID_UIAUTOMATOR,loc))\ndriver.find_element_by_android_uiautomator(loc).click()\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"这个步骤后进入了这个页面:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/ac/ac7bddc9e8d84a6adb0b07c8f24cf634.png","alt":null,"title":null,"style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"进入这个页面也是需要时间的。WebView 这个元素当中,放的才是 html 页面。真的等到 html 页面加载出来之后,再去获取所有相关的内容,这样比较好。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"万一切过来的时候,html 页面还没有开始加载,我就马上去获取当前所有可以操作的对象,这样很容易丢失,所以也一样要讲究等待。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"讲究等待,首先等到 WebView 这个元素出现。等到 WebView 这个 class 控件出现,class 值代表它的控件。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"python"},"content":[{"type":"text","text":"# 等待Web View元素出现 -Web View里面放的是Html\nWebDriverWait(driver,20).until(EC.visibility_of_element_located((MobileBy.CLASS_NAME,'android.webkit.WebView')))","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"sleep","attrs":{}}],"attrs":{}},{"type":"text","text":"1 秒钟,确保里面的 html,所有的都能加载完成。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"time.sleep(1)","attrs":{}}],"attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"二、怎么切换?","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"用什么样的语句来获取我们的 WebView、获取我们的原生控件呢?","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"它这个东西在我们 App 当中叫做","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"context","attrs":{}}],"attrs":{}},{"type":"text","text":",翻译成中文就是","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"上下文。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"上下文在我们自动化中就是指可以切换的东西,就是我们的原生控件。","attrs":{}},{"type":"text","text":" 原生控件是我们默认的,就像窗口切换就是我们默认的窗口是一样的。原生控件是它的默认上下文。打开 app,默认就是在它的原生控件当中。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"WebView 就是它的第二种","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"context","attrs":{}}],"attrs":{}},{"type":"text","text":"。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/9f/9f5b5f38c12e5fc935ce436cbb2fa2c8.png","alt":null,"title":null,"style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"只要当前页面中有 WebView,它就会显示出来,有 2 个就会显示 2 个。如图片中这个例子中只有一个 Webview,所以它只显示一个 WebView。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/b1/b1c06c964e1284dbdbe9dfa13053115e.png","alt":null,"title":null,"style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"这就是","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"context","attrs":{}}],"attrs":{}},{"type":"text","text":"上下文。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"只有这种情况下需要切换,其它情况下都是原生控件就不需要切换,不用管它,一旦有 html 页面就需要考虑这些事情了。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"三、上下文切换","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"可用的上下文(Contexts)","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"列出所有可用的上下文(contexts)","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"driver.contexts","attrs":{}}],"attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"driver.window_handles","attrs":{}}],"attrs":{}},{"type":"text","text":" 获取所有窗口的 handle,返回 list 列表。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"当前上下文(context):列出当前的上下文(context)","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"driver.current_context","attrs":{}}],"attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"切换至默认的上下文(context)","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"切换回默认的上下文(context)。(译者注:一般就是原生上下文 “NATIVE_APP”)","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"driver.switch_to.context(None)","attrs":{}}],"attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"当前 Activity:获取当前的 Acticity。仅支持 Android。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"driver.current_activity","attrs":{}}],"attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"当前包名(package):获取当前包名(package)。仅支持 Android 。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"driver.current_package","attrs":{}}],"attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"上下文的操作方式在这里,和 Windows 窗口是一模一样的。和 Web 自动化中所谓的窗口是一样的。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"首先列出所有可用的上下文。就像列出目前所有打开的窗口是一样的。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"这个上下文,有 WebView 的时候,也是在执行代码的时候,它进入了有 WebView 的","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"页面当中","attrs":{}},{"type":"text","text":",才会有多个,没有进入有 WebView 的页面当中只有一个 WebView 的(相当于一个大箱子,箱子打开后有多个)。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"列出所有可用的上下文,再去切换至需要的上下文。怎么切换呢?他们得到的结果也是个列表啊。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"列表当中放的值呢,不是原生控件就是 WebView。所以它也有下标。如果要切换的话就是","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"driver.switch_to.context(None)","attrs":{}}],"attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"None 表示什么呢?","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"表示切换回默认的上下文,按照 Web 自动化的讲法就是默认的窗口,在我们这里就是默认的原生控件里面。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如果你想切换到 WebView 的话,","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"driver.contexts","attrs":{}}],"attrs":{}},{"type":"text","text":"返回值 0,列表取下标 1,2,3,4 都是可以取得。也可以将你得到的 Web 名称放在","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"driver.switch_to.context(None)","attrs":{}}],"attrs":{}},{"type":"text","text":"中替换 None 就可以了。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"driver.switch_to.context(None)","attrs":{}}],"attrs":{}},{"type":"text","text":"可以切进去,也可以切出来。如果你想获取当前的窗口,当前的上下文,叫做","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"driver.current_context","attrs":{}}],"attrs":{}},{"type":"text","text":"。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"它的做法与窗口是一模一样的。","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"Web 自动化中叫做窗口,这里叫做上下文。","attrs":{}},{"type":"text","text":" 其它的时候不需要切换,但是有窗口需要交替的时候就必须要切换。有 iframe,需要更换 html 页面的时候就需要切换,其它情况下就不切换。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"现在在这个地方已经等到了这个所有的 WebView 出现了,所以接下来这样做:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/4c/4cd16ac8e86630be87a37b64fcd7adc0.jpeg","alt":null,"title":null,"style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"button[@class=\"bottom-btn buy\"]","attrs":{}}],"attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/a8/a8e36cd47441c787ffca40b2719142a1.jpeg","alt":null,"title":null,"style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"相当于 App 自动化和 Web 自动化组合起来用了,无缝切换,不需要改什么,照着套路用就好了:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"python"},"content":[{"type":"text","text":"# 切换之后:当前的操作对象:html页面。\n# 等待元素可见\n# 因为是通用的,所以接下来的代码是web自动化的代码\nWebDriverWait(driver,20).until(EC.visibility_of_element_located((MobileBy.XPATH,'//button[@class=\"bottom-btn buy\"]')))\n# 这个用Mobileby或者By都无所谓。\ndriver.find_element_by_xpath('//button[@class=\"bottom-btn buy\"]').click()","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/6f/6f5422b4b266806312e92e6bb024bee5.png","alt":null,"title":null,"style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"列出了当前的上下文:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"['NATIVE_APP', 'WEBVIEW_com.tencent.mobileqq:mini', 'WEBVIEW_com.保密']","attrs":{}}],"attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"NATIVE_APP 是当前的原生控件,按照 web 自动化来说,是默认的主窗口。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"是因为这段代码:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"python"},"content":[{"type":"text","text":"# 1、先列出所有的context\ncons=driver.contexts #列表\n#也是按照出现的先后顺序,WebView是操作过程中才出现的,所以它肯定排队。\nprint(cons)","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/23/231f08b3b20f352b77900d31c6d0dac7.png","alt":null,"title":null,"style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"一定要开启 webview debug 属性,如果你没有开启它,那么这 2 项,在这里获取的时候是看不到的:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/ac/acf73ae3f258f517759aad2f69e02d94.png","alt":null,"title":null,"style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"就只有一个了,就是 NATIVE","attrs":{}},{"type":"text","marks":[{"type":"italic","attrs":{}}],"text":"APP。只能看到 NATIVE","attrs":{}},{"type":"text","text":"APP 是切换不到 WebView 的。一定要保证能够识别得到,才能够去切换。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"技巧:","attrs":{}},{"type":"text","text":" 报错的时候先看第一行代码,看看在你自己当前脚本当中到底是哪一行出错了。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"四、样例代码","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"手机设置中开启着显示布局边界的情况下,然后 run 代码。因为 App 界面有变更,所以代码和现有界面不一致,即","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"立即购买","attrs":{}},{"type":"text","text":"现在成了","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"报名截止并跳转至 QQ 界面","attrs":{}},{"type":"text","text":"。代码提示找不到元素请不要奇怪,因为为了便于理解,放的元素还是","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"立即购买","attrs":{}},{"type":"text","text":"的元素。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"此代码只是样例,不一定保证在你的电脑上就能运行成功,请根据实际情况修改。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"python"},"content":[{"type":"text","text":"from appium import webdriver\nimport time\nfrom selenium.webdriver.support.wait import WebDriverWait\nfrom selenium.webdriver.support import expected_conditions as EC\nfrom appium.webdriver.common.mobileby import MobileBy\n\n\ndesired_caps={}\n# 平台类型\ndesired_caps[\"platformName\"]=\"Android\"\n# 平台版本号\ndesired_caps[\"platformVersion\"]=\"10\"\n# 设备名称\ndesired_caps[\"deviceName\"]=\"2NSDU20410017297\"\n# app 包名\ndesired_caps[\"appPackage\"]=\"输入appPackage\"\n# app 入口 acitivity\ndesired_caps[\"appActivity\"]=\"输入appActivity\"\n\n\n# 连接Appium server。前提:appium desktop要启动。有监听端口。\n# 将desired_caps发送给appium server。打开app\ndriver = webdriver.Remote('http://127.0.0.1:4723/wd/hub',desired_caps)\n\nloc='new UiSelector().text(\"全程班\")'\nWebDriverWait(driver,20).until(EC.visibility_of_element_located((MobileBy.ANDROID_UIAUTOMATOR,loc)))\ndriver.find_element_by_android_uiautomator(loc).click()\n\n\n\n# 等待Web View元素出现 -Web View里面放的是Html\nWebDriverWait(driver,20).until(EC.visibility_of_element_located((MobileBy.CLASS_NAME,'android.webkit.WebView')))\n# 因为只是等它这个元素出现了,至于里面的html有没有加载完成,并不是很确定。\ntime.sleep(1)#为了稳定起见,稍微sleep 1秒,确保里面的Html,所有的都能加载完成。\n\n# 前提:可以识别到WebView,\n# 这个识别不是肉眼识别,而是通过调用代码的时候可以识别。需要开启app的webview debug调试属性,对外可见。\n\n# context #原生控件 #webview\n\n# 1、先列出所有的context\ncons=driver.contexts #列表\n#也是按照出现的先后顺序,WebView是操作过程中才出现的,所以它肯定排队。\nprint(cons)\n\n# 2、切换至WebView,要确保chromedriver的版本要与webView的版本匹配。也要放置在对应的位置。\ndriver.switch_to.context(cons[-1])#这个地方没有给你提示,不代表你错了,照着操作就好了。\n# 先写个-1,因为现在不知道WebView的名字。但是知道WebView一定是出现在最后的就可以了。\n\n# 3、切换之后:当前的操作对象:html页面。\n# 等待元素可见\n# 因为是通用的,所以接下来的代码是web自动化的代码\nWebDriverWait(driver,20).until(EC.visibility_of_element_located((MobileBy.XPATH,'//button[@class=\"bottom-btn buy\"]')))\n# 这个用Mobileby或者By都无所谓。\ndriver.find_element_by_xpath('//button[@class=\"bottom-btn buy\"]').click()\n# 这里为什么用MobileBy.XPATH而不是By.XPATH?\n# MobileBy这个类继承了By,所以这个用Mobileby或者By都无所谓。\n# 原理:大家背后走的都是同一套逻辑,同一段请求,同一种命令。都是find_element\n# 只不过我们查找元素的方式不一样。所以它只是一个外部的形式而已,在内部也是一样的。\n# 即便用Selenium Webdriver 写代码,也可以把MobileBy引进来,只要我不去用移动端的定位方式,都是可以做的。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"遇到的问题","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"appium 报错 session not created: This version of ChromeDriver only supports Chrome version 84","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"靠谱链接:","attrs":{}},{"type":"text","text":" https://www.codenong.com/jsb8d9e8746809/","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"温馨提示:","attrs":{}},{"type":"text","text":" 如果你的代码没问题,还报错,那么就换 Appium 版本吧,Appium 的 bug 很多。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"上篇文章 中此处代码错了,应该改成这样:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/d8/d8838420592575aedb0467f81159c54f.png","alt":null,"title":null,"style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"horizontalrule","attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"公众号 ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"清菡软件测试","attrs":{}},{"type":"text","text":" 首发,更多原创文章:清菡软件测试 95+原创文章,欢迎关注、交流,禁止第三方擅自转载。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}}]}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章