做者:清菡
博客:oschina、雲+社區、知乎等各大平臺都有。html
loc='new UiSelector().text("全程班")'
WebDriverWait(driver,20).until(EC.visibility_of_element_located((MobileBy.ANDROID_UIAUTOMATOR,loc))
driver.find_element_by_android_uiautomator(loc).click()
這個步驟後進入了這個頁面:android
進入這個頁面也是須要時間的。WebView 這個元素當中,放的纔是 html 頁面。真的等到 html 頁面加載出來以後,再去獲取全部相關的內容,這樣比較好。web
萬一切過來的時候,html 頁面尚未開始加載,我就立刻去獲取當前全部能夠操做的對象,這樣很容易丟失,因此也同樣要講究等待。chrome
講究等待,首先等到 WebView 這個元素出現。等到 WebView 這個 class 控件出現,class 值表明它的控件。session
# 等待Web View元素出現 -Web View裏面放的是Html
WebDriverWait(driver,20).until(EC.visibility_of_element_located((MobileBy.CLASS_NAME,'android.webkit.WebView')))
sleep
1 秒鐘,確保裏面的 html,全部的都能加載完成。app
time.sleep(1)
koa
它這個東西在咱們 App 當中叫作context
,翻譯成中文就是上下文。編輯器
上下文在咱們自動化中就是指能夠切換的東西,就是咱們的原生控件。 原生控件是咱們默認的,就像窗口切換就是咱們默認的窗口是同樣的。原生控件是它的默認上下文。打開 app,默認就是在它的原生控件當中。佈局
WebView 就是它的第二種context
。測試
只要當前頁面中有 WebView,它就會顯示出來,有 2 個就會顯示 2 個。如圖片中這個例子中只有一個 Webview,因此它只顯示一個 WebView。
這就是context
上下文。
只有這種狀況下須要切換,其它狀況下都是原生控件就不須要切換,不用管它,一旦有 html 頁面就須要考慮這些事情了。
可用的上下文(Contexts)
列出全部可用的上下文(contexts)
driver.contexts
driver.window_handles
獲取全部窗口的 handle,返回 list 列表。
當前上下文(context):列出當前的上下文(context)
driver.current_context
切換至默認的上下文(context)
切換回默認的上下文(context)。(譯者注:通常就是原生上下文 「NATIVE_APP」)
driver.switch_to.context(None)
當前 Activity:獲取當前的 Acticity。僅支持 Android。
driver.current_activity
當前包名(package):獲取當前包名(package)。僅支持 Android 。
driver.current_package
上下文的操做方式在這裏,和 Windows 窗口是如出一轍的。和 Web 自動化中所謂的窗口是同樣的。
首先列出全部可用的上下文。就像列出目前全部打開的窗口是同樣的。
這個上下文,有 WebView 的時候,也是在執行代碼的時候,它進入了有 WebView 的頁面當中,纔會有多個,沒有進入有 WebView 的頁面當中只有一個 WebView 的(至關於一個大箱子,箱子打開後有多個)。
列出全部可用的上下文,再去切換至須要的上下文。怎麼切換呢?他們獲得的結果也是個列表啊。
列表當中放的值呢,不是原生控件就是 WebView。因此它也有下標。若是要切換的話就是driver.switch_to.context(None)
表示切換回默認的上下文,按照 Web 自動化的講法就是默認的窗口,在咱們這裏就是默認的原生控件裏面。
若是你想切換到 WebView 的話,driver.contexts
返回值 0,列表取下標 1,2,3,4 都是能夠取得。也能夠將你獲得的 Web 名稱放在driver.switch_to.context(None)
中替換 None 就能夠了。
driver.switch_to.context(None)
能夠切進去,也能夠切出來。若是你想獲取當前的窗口,當前的上下文,叫作driver.current_context
。
它的作法與窗口是如出一轍的。Web 自動化中叫作窗口,這裏叫作上下文。 其它的時候不須要切換,可是有窗口須要交替的時候就必需要切換。有 iframe,須要更換 html 頁面的時候就須要切換,其它狀況下就不切換。
如今在這個地方已經等到了這個全部的 WebView 出現了,因此接下來這樣作:
button[@class="bottom-btn buy"]
至關於 App 自動化和 Web 自動化組合起來用了,無縫切換,不須要改什麼,照着套路用就行了:
# 切換以後:當前的操做對象:html頁面。
# 等待元素可見
# 由於是通用的,因此接下來的代碼是web自動化的代碼
WebDriverWait(driver,20).until(EC.visibility_of_element_located((MobileBy.XPATH,'//button[@class="bottom-btn buy"]')))
# 這個用Mobileby或者By都無所謂。
driver.find_element_by_xpath('//button[@class="bottom-btn buy"]').click()
列出了當前的上下文:
['NATIVE_APP', 'WEBVIEW_com.tencent.mobileqq:mini', 'WEBVIEW_com.保密']
NATIVE_APP 是當前的原生控件,按照 web 自動化來講,是默認的主窗口。
是由於這段代碼:
# 一、先列出全部的context
cons=driver.contexts #列表
#也是按照出現的前後順序,WebView是操做過程當中纔出現的,因此它確定排隊。
print(cons)
必定要開啓 webview debug 屬性,若是你沒有開啓它,那麼這 2 項,在這裏獲取的時候是看不到的:
就只有一個了,就是 NATIVE_APP。只能看到 NATIVE_APP 是切換不到 WebView 的。必定要保證可以識別獲得,纔可以去切換。
技巧: 報錯的時候先看第一行代碼,看看在你本身當前腳本當中究竟是哪一行出錯了。
手機設置中開啓着顯示佈局邊界的狀況下,而後 run 代碼。由於 App 界面有變動,因此代碼和現有界面不一致,即當即購買如今成了報名截止並跳轉至 QQ 界面。代碼提示找不到元素請不要奇怪,由於爲了便於理解,放的元素仍是當即購買的元素。
此代碼只是樣例,不必定保證在你的電腦上就能運行成功,請根據實際狀況修改。
from appium import webdriver
import time
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from appium.webdriver.common.mobileby import MobileBy
desired_caps={}
# 平臺類型
desired_caps["platformName"]="Android"
# 平臺版本號
desired_caps["platformVersion"]="10"
# 設備名稱
desired_caps["deviceName"]="2NSDU20410017297"
# app 包名
desired_caps["appPackage"]="輸入appPackage"
# app 入口 acitivity
desired_caps["appActivity"]="輸入appActivity"
# 鏈接Appium server。前提:appium desktop要啓動。有監聽端口。
# 將desired_caps發送給appium server。打開app
driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub',desired_caps)
loc='new UiSelector().text("全程班")'
WebDriverWait(driver,20).until(EC.visibility_of_element_located((MobileBy.ANDROID_UIAUTOMATOR,loc)))
driver.find_element_by_android_uiautomator(loc).click()
# 等待Web View元素出現 -Web View裏面放的是Html
WebDriverWait(driver,20).until(EC.visibility_of_element_located((MobileBy.CLASS_NAME,'android.webkit.WebView')))
# 由於只是等它這個元素出現了,至於裏面的html有沒有加載完成,並非很肯定。
time.sleep(1)#爲了穩定起見,稍微sleep 1秒,確保裏面的Html,全部的都能加載完成。
# 前提:能夠識別到WebView,
# 這個識別不是肉眼識別,而是經過調用代碼的時候能夠識別。須要開啓app的webview debug調試屬性,對外可見。
# context #原生控件 #webview
# 一、先列出全部的context
cons=driver.contexts #列表
#也是按照出現的前後順序,WebView是操做過程當中纔出現的,因此它確定排隊。
print(cons)
# 二、切換至WebView,要確保chromedriver的版本要與webView的版本匹配。也要放置在對應的位置。
driver.switch_to.context(cons[-1])#這個地方沒有給你提示,不表明你錯了,照着操做就行了。
# 先寫個-1,由於如今不知道WebView的名字。可是知道WebView必定是出如今最後的就能夠了。
# 三、切換以後:當前的操做對象:html頁面。
# 等待元素可見
# 由於是通用的,因此接下來的代碼是web自動化的代碼
WebDriverWait(driver,20).until(EC.visibility_of_element_located((MobileBy.XPATH,'//button[@class="bottom-btn buy"]')))
# 這個用Mobileby或者By都無所謂。
driver.find_element_by_xpath('//button[@class="bottom-btn buy"]').click()
# 這裏爲何用MobileBy.XPATH而不是By.XPATH?
# MobileBy這個類繼承了By,因此這個用Mobileby或者By都無所謂。
# 原理:你們背後走的都是同一套邏輯,同一段請求,同一種命令。都是find_element
# 只不過咱們查找元素的方式不同。因此它只是一個外部的形式而已,在內部也是同樣的。
# 即使用Selenium Webdriver 寫代碼,也能夠把MobileBy引進來,只要我不去用移動端的定位方式,都是能夠作的。
appium 報錯 session not created: This version of ChromeDriver only supports Chrome version 84
靠譜連接: https://www.codenong.com/jsb8d9e8746809/
舒適提示: 若是你的代碼沒問題,還報錯,那麼就換 Appium 版本吧,Appium 的 bug 不少。
上篇文章 中此處代碼錯了,應該改爲這樣:
公衆號 清菡軟件測試 首發,更多原創文章:清菡軟件測試 95+原創文章,歡迎關注、交流,禁止第三方擅自轉載。