環境:
1、Appium: 1.15.1
2、Python: 3.7.0
3、Selenium: 3.141.0
4、IDE: Pycharm
5、PC:Windows 10
問題:在 Pycharm 中輸入 driver.find_element_by_后可以直接聯想出name這個,然后就通過這個name屬性去定位界面元素,在運行時居然報 "Locator Strategy 'name' is not supported for this session",從這個錯誤來看,顯然可以看出不是selenium的鍋,要不然 pycharm 也不可能聯想出來,那么這個很可能是 appium 不支持這個屬性了,據說是從appium 1.5版本之后就不支持這個了,為了驗證這個觀點,到這個目錄下:C:\Program Files\Appium\resources\app\node_modules\appium\node_modules\appium-android-driver\build\lib 找到 driver.js 打開如下,看到沒它只支持下面五種屬性
class AndroidDriver extends _appiumBaseDriver.BaseDriver {
constructor(opts = {}, shouldValidateCaps = true) {
super(opts, shouldValidateCaps);
this.locatorStrategies = ['xpath', 'id', 'class name', 'accessibility id', '-android uiautomator'];
this.desiredCapConstraints = _desiredCaps.default;
this.sessionChromedrivers = {};
this.jwpProxyActive = false;
this.jwpProxyAvoid = _lodash.default.clone(NO_PROXY);
this.settings = new _appiumBaseDriver.DeviceSettings({
那么如果一定要用name這個屬性來進行元素定位的話,那么如何操作呢,下面介紹兩種方法:
1、修改driver.js文件,添加name到locatorStrategies里去,經驗證這種方法不可行,仍然報同樣錯誤,顯然通過簡單的修改這個方式不太可行
class AndroidDriver extends _appiumBaseDriver.BaseDriver {
constructor(opts = {}, shouldValidateCaps = true) {
super(opts, shouldValidateCaps);
this.locatorStrategies = ['xpath', 'id', 'class name', 'accessibility id', '-android uiautomator', 'name'];
this.desiredCapConstraints = _desiredCaps.default;
this.sessionChromedrivers = {};
this.jwpProxyActive = false;
this.jwpProxyAvoid = _lodash.default.clone(NO_PROXY);
this.settings = new _appiumBaseDriver.DeviceSettings({
1 driver.find_element_by_name("Browsing").click()
2、通過find_element_by_android_uiautomator這個來進行元素定位,這個是基於uiautomator原生的來支持,這個肯定是會支持界面中所有支持的元素定位,直接上腳本,這個是可以正常跑通的。
1 # -*- coding:utf-8 -*- 2 3 import unittest 4 import time 5 from appium import webdriver 6 from selenium.webdriver.common.by import By 7 from selenium.webdriver.support.ui import WebDriverWait 8 from selenium.webdriver.support import expected_conditions as EC 9 10 server = 'http://localhost:4723/wd/hub' 11 desired_capabilities = { 12 'platformName': 'Android', 13 'deviceName': 'abcdefg1234', 14 'appPackage': 'com.sina.weibo', 15 'appActivity': 'com.sina.weibo.VisitorMainTabActivity', 16 'autoGrantPermissions': True 17 } 18 19 driver = webdriver.Remote(server, desired_capabilities) 20 21 time.sleep(30) 22 23 driver.find_element_by_android_uiautomator("new UiSelector().text(\"Browsing\")").click()
建議:以后在寫適用appium自動化框架的腳本時,凡是不能通過這幾個屬性['xpath', 'id', 'class name', 'accessibility id']直接定位元素的,都直接用 '-android uiautomator' 這個屬性來進行定位,其實大家也能發現,前面那幾個屬性在uiautomator里面是全部包括的(xpath除外),下面把這幾個對應關系列舉如下:
driver.find_element_by_id("com.sina.weibo:id/tv_title_lookaround").click() <==> driver.find_element_by_android_uiautomator("new UiSelector().resourceId(\"com.sina.weibo:id/tv_title_lookaround\")").click()
driver.find_element_by_name("Browsing").click() <==> driver.find_element_by_android_uiautomator("new UiSelector().text(\"Browsing\")").click()
driver.find_element_by_accessibility_id("Browsing").click() <==> driver.find_element_by_android_uiautomator("new UiSelector().description(\"Browsing\")").click()
driver.find_element_by_class_name("android.widget.TextView").click() <==> driver.find_element_by_android_uiautomator("new UiSelector().className(\"android.widget.TextView\")").click()
注:以上四個對應關系並沒有一個一個去驗證,只是根據自己的理解寫出來,有錯誤的地方還請各路英雄好漢指出,謝謝!