Appium 关于解决 Appium 里的控件的定位问题。不使用 By.name()这个方法

tomchen · 2013年12月19日 · 最后由 恒温 回复于 2013年12月20日 · 3268 次阅读

我现在想测试一款 APP,该 App 包含一个登陆的界面以及登陆后的页面,如何不用 By.name() 这个方法 ,能够定位控件。我曾经想过使用 XPath,但问题在于,其登录前与登陆后 XPath 的开头均为//window[1] 。无法确定是哪一个的控件,大神帮帮忙吧。

5:30 PM
已经能够获取指定控件(Textfield),但是传值失效。
java 代码:

List<WebElement> elems = wd.findElements(By.tagName("UIASecureTextField"));
    for(WebElement e:elems){
  e.sendKeys("123456");}   //能够获取控件 ,但是传值失效

log:


info: Welcome to Appium v0.12.3

info: Appium REST http interface listener started on 127.0.0.1:4723
   info  - socket.io started

info: Not spawning instruments force-quit watcher since it only works on 10.9 and you have 10.8.5

info: Responding to client with success: {"status":0,"value":{"build":{"version":"0.12.3","revision":"c8abd030c0cedcc387532f2aa986fd956e46eb4f"}}}

debug: Appium request initiated at /wd/hub/status

GET /wd/hub/status 200 9ms - 144b

debug: Request received with params: {}

debug: Appium request initiated at /wd/hub/status

info: Responding to client with success: {"status":0,"value":{"build":{"version":"0.12.3","revision":"c8abd030c0cedcc387532f2aa986fd956e46eb4f"}}}

debug: Request received with params: {}

GET /wd/hub/status 200 2ms - 144b

debug: Appium request initiated at /wd/hub/session

info: Using local app from desiredCaps: /Users/DEV/Library/Developer/Xcode/DerivedData/Inspector-dldvhbusyfhhaifiqsmclsjgisxy/Build/Products/Debug-iphonesimulator/Inspector.app

debug: Request received with params: {"desiredCapabilities":{"platform":"Mac","app":"/Users/DEV/Library/Developer/Xcode/DerivedData/Inspector-dldvhbusyfhhaifiqsmclsjgisxy/Build/Products/Debug-iphonesimulator/Inspector.app","browserName":"iOS","version":"6.1"}}

info: Creating new appium session e61d6443-50dd-4720-bb70-a42546709b86
info: Removing any remaining instruments sockets
info: Cleaned up instruments socket /tmp/instruments_sock

info: Parsed app Localizable.strings

info: Killing the simulator process

debug: Launching device: iPhone (3.5-inch)

info: Parsed app Info.plist

info: Wrote new app Info.plist with device type

info: Starting iOS 7.* simulator log capture

debug: No device id or app, not installing to real device.

debug: Creating instruments

info: Instruments is at: /Applications/Xcode.app/Contents/Developer/usr/bin/instruments

info: [INSTSERVER] Instruments socket server started at /tmp/instruments_sock

info: Spawning instruments with command: /Applications/Xcode.app/Contents/Developer/usr/bin/instruments -t /Applications/Xcode.app/Contents/Applications/Instruments.app/Contents/PlugIns/AutomationInstrument.bundle/Contents/Resources/Automation.tracetemplate /Users/DEV/Library/Developer/Xcode/DerivedData/Inspector-dldvhbusyfhhaifiqsmclsjgisxy/Build/Products/Debug-iphonesimulator/Inspector.app -e UIASCRIPT /Applications/Appium.app/Contents/Resources/node_modules/appium/lib/devices/ios/uiauto/bootstrap.js -e UIARESULTSPATH /tmp/appium-instruments/
info: And extra without-delay env: {"DYLD_INSERT_LIBRARIES":"/Applications/Appium.app/Contents/Resources/node_modules/appium/build/iwd/InstrumentsShim.dylib","LIB_PATH":"/Applications/Appium.app/Contents/Resources/node_modules/appium/build/iwd"}
info: And launch timeout: 90000ms

debug: Appium request initiated at /wd/hub/status

info: Responding to client with success: {"status":0,"value":{"build":{"version":"0.12.3","revision":"c8abd030c0cedcc387532f2aa986fd956e46eb4f"}},"sessionId":"e61d6443-50dd-4720-bb70-a42546709b86"}

debug: Request received with params: {}

GET /wd/hub/status 200 1ms - 199b

info: [INST STDERR] 2013-12-20 11:24:57.972 ScriptAgent[16241:2e07] CLTilesManagerClient: initialize, sSharedTilesManagerClient


info: [INST STDERR] 2013-12-20 11:24:57.972 ScriptAgent[16241:2e07] CLTilesManagerClient: init
2013-12-20 11:24:57.973 ScriptAgent[16241:2e07] CLTilesManagerClient: reconnecting, 0x96705e0


info: [INSTSERVER] Instruments is ready to receive commands

debug: Sending command to instruments: au.bundleId()

info: Instruments launched. Starting poll loop for new commands.
info: Pushing command to appium work queue: "au.bundleId()"
info: [INSTSERVER] Socket data received (15 bytes)
info: [INSTSERVER] Socket data being routed for 'cmd' event
info: [INSTSERVER] Sending command to instruments: au.bundleId()

info: [INSTSERVER] Socket data received (68 bytes)

debug: Sending command to instruments: au.setScreenOrientation('PORTRAIT')

info: [INSTSERVER] Socket data being routed for 'cmd' event
info: [INSTSERVER] Got result from instruments: {"status":0,"value":"com.accela.inspector"}
info: Bundle ID for open app is com.accela.inspector
info: Setting initial orientation to PORTRAIT
info: Pushing command to appium work queue: "au.setScreenOrientation('PORTRAIT')"
info: [INSTSERVER] Sending command to instruments: au.setScreenOrientation('PORTRAIT')

info: [INSTSERVER] Socket data received (56 bytes)

info: [INSTSERVER] Socket data being routed for 'cmd' event
info: [INSTSERVER] Got result from instruments: {"status":0,"value":"PORTRAIT"}
info: Device launched! Ready for commands (will time out in 60secs)
info: Appium session started with sessionId e61d6443-50dd-4720-bb70-a42546709b86
POST /wd/hub/session 303 87390ms - 9b

debug: Appium request initiated at /wd/hub/session/e61d6443-50dd-4720-bb70-a42546709b86

info: Responding to client with success: {"status":0,"value":{"version":"7.0","webStorageEnabled":false,"locationContextEnabled":false,"browserName":"iOS","platform":"Mac","javascriptEnabled":true,"databaseEnabled":false,"takesScreenshot":true,"app":"/Users/DEV/Library/Developer/Xcode/DerivedData/Inspector-dldvhbusyfhhaifiqsmclsjgisxy/Build/Products/Debug-iphonesimulator/Inspector.app"},"sessionId":"e61d6443-50dd-4720-bb70-a42546709b86"}

debug: Request received with params: {}

GET /wd/hub/session/e61d6443-50dd-4720-bb70-a42546709b86 200 1ms - 470b

debug: Appium request initiated at /wd/hub/session/e61d6443-50dd-4720-bb70-a42546709b86/timeouts/implicit_wait

info: Set iOS implicit wait to 60000ms

debug: Request received with params: {"ms":60000}

info: Responding to client with success: {"status":0,"value":null,"sessionId":"e61d6443-50dd-4720-bb70-a42546709b86"}
POST /wd/hub/session/e61d6443-50dd-4720-bb70-a42546709b86/timeouts/implicit_wait 200 2ms - 89b
info: Pushing command to appium work queue: "au.getElementsByType('UIATextField')"
info: [INSTSERVER] Sending command to instruments: au.getElementsByType('UIATextField')

debug: Appium request initiated at /wd/hub/session/e61d6443-50dd-4720-bb70-a42546709b86/elements
debug: Request received with params: {"using":"tag name","value":"UIATextField"}
debug: Sending command to instruments: au.getElementsByType('UIATextField')

info: [INSTSERVER] Socket data received (79 bytes)

info: [INSTSERVER] Socket data being routed for 'cmd' event
info: [INSTSERVER] Got result from instruments: {"status":0,"value":[{"ELEMENT":"0"},{"ELEMENT":"1"}]}
info: Responding to client with success: {"status":0,"value":[{"ELEMENT":"0"},{"ELEMENT":"1"}],"sessionId":"e61d6443-50dd-4720-bb70-a42546709b86"}
POST /wd/hub/session/e61d6443-50dd-4720-bb70-a42546709b86/elements 200 1375ms - 157b

debug: Appium request initiated at /wd/hub/session/e61d6443-50dd-4720-bb70-a42546709b86/element/0/value

info: Pushing command to appium work queue: "au.getElement('0').setValueByType('123456')"

debug: Request received with params: {"id":"0","value":["123456"]}
debug: Sending command to instruments: au.getElement('0').setValueByType('123456')

info: [INSTSERVER] Sending command to instruments: au.getElement('0').setValueByType('123456')

info: [INSTSERVER] Socket data received (202 bytes)

info: [INSTSERVER] Socket data being routed for 'cmd' event
info: [INSTSERVER] Got result from instruments: {"status":17,"value":"Unexpected error in -[UIATextField_0xa3a67d0 setValue:], /SourceCache/UIAutomation_Sim/UIAutomation-365/Framework/UIAElement.m line 1061, kAXErrorFailure"}
info: Responding to client with error: {"status":17,"value":{"message":"An error occurred while executing user supplied JavaScript.","origValue":"Unexpected error in -[UIATextField_0xa3a67d0 setValue:], /SourceCache/UIAutomation_Sim/UIAutomation-365/Framework/UIAElement.m line 1061, kAXErrorFailure"},"sessionId":"e61d6443-50dd-4720-bb70-a42546709b86"}
POST /wd/hub/session/e61d6443-50dd-4720-bb70-a42546709b86/element/0/value 500 201ms - 342b







2013.12.20  2:02PM  



info: Welcome to Appium v0.12.3

info: Appium REST http interface listener started on 127.0.0.1:4723
   info  - socket.io started
info: Not spawning instruments force-quit watcher since it only works on 10.9 and you have 10.8.5

info: Responding to client with success: {"status":0,"value":{"build":{"version":"0.12.3","revision":"c8abd030c0cedcc387532f2aa986fd956e46eb4f"}}}

GET /wd/hub/status 200 7ms - 144b

debug: Appium request initiated at /wd/hub/status

debug: Request received with params: {}

debug: Appium request initiated at /wd/hub/session

debug: Request received with params: {"desiredCapabilities":{"platform":"Mac","app":"/Users/DEV/Library/Developer/Xcode/DerivedData/Inspector-dldvhbusyfhhaifiqsmclsjgisxy/Build/Products/Debug-iphonesimulator/Inspector.app","browserName":"iOS","version":"6.1"}}

info: Using local app from desiredCaps: /Users/DEV/Library/Developer/Xcode/DerivedData/Inspector-dldvhbusyfhhaifiqsmclsjgisxy/Build/Products/Debug-iphonesimulator/Inspector.app

info: Creating new appium session 0b708449-5477-424b-ba90-15f26df3cf66
info: Removing any remaining instruments sockets
info: Cleaned up instruments socket /tmp/instruments_sock

info: Parsed app Localizable.strings

info: Killing the simulator process

debug: Launching device: iPhone (3.5-inch)

info: Parsed app Info.plist

debug: No device id or app, not installing to real device.
debug: Creating instruments

info: Wrote new app Info.plist with device type
info: Starting iOS 7.* simulator log capture

info: Instruments is at: /Applications/Xcode.app/Contents/Developer/usr/bin/instruments
info: [INSTSERVER] Instruments socket server started at /tmp/instruments_sock
info: Spawning instruments with command: /Applications/Xcode.app/Contents/Developer/usr/bin/instruments -t /Applications/Xcode.app/Contents/Applications/Instruments.app/Contents/PlugIns/AutomationInstrument.bundle/Contents/Resources/Automation.tracetemplate /Users/DEV/Library/Developer/Xcode/DerivedData/Inspector-dldvhbusyfhhaifiqsmclsjgisxy/Build/Products/Debug-iphonesimulator/Inspector.app -e UIASCRIPT /Applications/Appium.app/Contents/Resources/node_modules/appium/lib/devices/ios/uiauto/bootstrap.js -e UIARESULTSPATH /tmp/appium-instruments/
info: And extra without-delay env: {"DYLD_INSERT_LIBRARIES":"/Applications/Appium.app/Contents/Resources/node_modules/appium/build/iwd/InstrumentsShim.dylib","LIB_PATH":"/Applications/Appium.app/Contents/Resources/node_modules/appium/build/iwd"}
info: And launch timeout: 90000ms

debug: Appium request initiated at /wd/hub/status

info: Responding to client with success: {"status":0,"value":{"build":{"version":"0.12.3","revision":"c8abd030c0cedcc387532f2aa986fd956e46eb4f"}},"sessionId":"0b708449-5477-424b-ba90-15f26df3cf66"}
GET /wd/hub/status 200 2ms - 199b

debug: Request received with params: {}

info: [INST STDERR] 2013-12-20 14:01:17.722 ScriptAgent[1139:2e07] CLTilesManagerClient: initialize, sSharedTilesManagerClient


info: [INST STDERR] 2013-12-20 14:01:17.725 ScriptAgent[1139:2e07] CLTilesManagerClient: init
2013-12-20 14:01:17.725 ScriptAgent[1139:2e07] CLTilesManagerClient: reconnecting, 0xa13a400


info: [INSTSERVER] Instruments is ready to receive commands

debug: Sending command to instruments: au.bundleId()

info: Instruments launched. Starting poll loop for new commands.
info: Pushing command to appium work queue: "au.bundleId()"

info: [INSTSERVER] Socket data received (15 bytes)
info: [INSTSERVER] Socket data being routed for 'cmd' event
info: [INSTSERVER] Sending command to instruments: au.bundleId()

info: [INSTSERVER] Socket data received (68 bytes)

debug: Sending command to instruments: au.setScreenOrientation('PORTRAIT')

info: [INSTSERVER] Socket data being routed for 'cmd' event
info: [INSTSERVER] Got result from instruments: {"status":0,"value":"com.accela.inspector"}
info: Bundle ID for open app is com.accela.inspector
info: Setting initial orientation to PORTRAIT
info: Pushing command to appium work queue: "au.setScreenOrientation('PORTRAIT')"
info: [INSTSERVER] Sending command to instruments: au.setScreenOrientation('PORTRAIT')

info: [INSTSERVER] Socket data received (56 bytes)

info: [INSTSERVER] Socket data being routed for 'cmd' event
info: [INSTSERVER] Got result from instruments: {"status":0,"value":"PORTRAIT"}
info: Device launched! Ready for commands (will time out in 60secs)
info: Appium session started with sessionId 0b708449-5477-424b-ba90-15f26df3cf66

POST /wd/hub/session 303 10873ms - 9b

debug: Appium request initiated at /wd/hub/session/0b708449-5477-424b-ba90-15f26df3cf66

info: Responding to client with success: {"status":0,"value":{"version":"7.0","webStorageEnabled":false,"locationContextEnabled":false,"browserName":"iOS","platform":"Mac","javascriptEnabled":true,"databaseEnabled":false,"takesScreenshot":true,"app":"/Users/DEV/Library/Developer/Xcode/DerivedData/Inspector-dldvhbusyfhhaifiqsmclsjgisxy/Build/Products/Debug-iphonesimulator/Inspector.app"},"sessionId":"0b708449-5477-424b-ba90-15f26df3cf66"}
GET /wd/hub/session/0b708449-5477-424b-ba90-15f26df3cf66 200 2ms - 470b

debug: Request received with params: {}

debug: Appium request initiated at /wd/hub/session/0b708449-5477-424b-ba90-15f26df3cf66/timeouts/implicit_wait

info: Set iOS implicit wait to 60000ms

debug: Request received with params: {"ms":60000}
debug: Appium request initiated at /wd/hub/session/0b708449-5477-424b-ba90-15f26df3cf66/elements
debug: Request received with params: {"using":"tag name","value":"UIATextField"}

info: Responding to client with success: {"status":0,"value":null,"sessionId":"0b708449-5477-424b-ba90-15f26df3cf66"}
POST /wd/hub/session/0b708449-5477-424b-ba90-15f26df3cf66/timeouts/implicit_wait 200 3ms - 89b
info: Pushing command to appium work queue: "au.getElementsByType('UIATextField')"
info: [INSTSERVER] Sending command to instruments: au.getElementsByType('UIATextField')

debug: Sending command to instruments: au.getElementsByType('UIATextField')

info: [INSTSERVER] Socket data received (79 bytes)

info: [INSTSERVER] Socket data being routed for 'cmd' event
info: [INSTSERVER] Got result from instruments: {"status":0,"value":[{"ELEMENT":"0"},{"ELEMENT":"1"}]}
info: Responding to client with success: {"status":0,"value":[{"ELEMENT":"0"},{"ELEMENT":"1"}],"sessionId":"0b708449-5477-424b-ba90-15f26df3cf66"}
POST /wd/hub/session/0b708449-5477-424b-ba90-15f26df3cf66/elements 200 570ms - 157b

debug: Appium request initiated at /wd/hub/session/0b708449-5477-424b-ba90-15f26df3cf66/execute

info: Pushing command to appium work queue: "au.getElement('0').setValue('123456')"
info: [INSTSERVER] Sending command to instruments: au.getElement('0').setValue('123456')

debug: Request received with params: {"args":[{"element":"0","value":"123456"}],"script":"mobile: setValue"}
debug: Sending command to instruments: au.getElement('0').setValue('123456')

info: [INSTSERVER] Socket data received (202 bytes)

info: [INSTSERVER] Socket data being routed for 'cmd' event
info: [INSTSERVER] Got result from instruments: {"status":17,"value":"Unexpected error in -[UIATextField_0xa384660 setValue:], /SourceCache/UIAutomation_Sim/UIAutomation-365/Framework/UIAElement.m line 1061, kAXErrorFailure"}
info: Responding to client with error: {"status":17,"value":{"message":"An error occurred while executing user supplied JavaScript.","origValue":"Unexpected error in -[UIATextField_0xa384660 setValue:], /SourceCache/UIAutomation_Sim/UIAutomation-365/Framework/UIAElement.m line 1061, kAXErrorFailure"},"sessionId":"0b708449-5477-424b-ba90-15f26df3cf66"}
POST /wd/hub/session/0b708449-5477-424b-ba90-15f26df3cf66/execute 500 216ms - 342b


共收到 38 条回复 时间 点赞

@seveniruby 你好,我已经能够获取到指定页面控件,但是始终传值失败,我也看过您这篇http://www.testerhome.com/topics/167 ,我能够获取到指定控件就是看这篇文章的,但是却无法成功传值,请问您个人认为是什么原因呢? 我能想到的办法都试过了,始终不成功。

#1 楼 @dippa 贴代码和 log 别截图了

#2 楼 @seveniruby 代码跟 log 已放上去。

@lihuazhang 能帮我看看是什么问题吗?

@spikeshen 能帮我看看是什么问题吗?

#5 楼 @dippa 传值失效?你看下你的 list 里到底找到多少个元素,一个个尝试下,也许你找到的不是你要输入值得那个。 看你报错。。。你的 app 启动都失败了啊。。

#6 楼 @spikeshen 可以成功启动的,但是传值失效,通过上面的 java 代码已经能够获取到,该控件,因为源代码里没有加 Attribute ,所以只能遍历然后获取控件。

#6 楼 @spikeshen 我重新运行一遍,跟新了 Log。

#6 楼 @spikeshen 可以帮我看看吗?我确实找不到哪里错了

  1. eclipse 可以 debug 的吧? 试试看
  2. 试试看 setValue,不用 sendKeys。从 ios instuments uiautomaiton 的角度来看, setValue 比较可靠

#10 楼 @lihuazhang 有 setValue 这个函数的?没提示的呀

#11 楼 @dippa 有。。。ios 支持,android 不支持=。= 而且据说用 setValue 弄中文没问题

#13 楼 @spikeshen 那 Java 没有对应的函数吗? 好,那我试试看

#14 楼 @dippa

HashMap inputObject = new HashMap();
inputObject.put("element", ((RemoteWebElement) we).getId());
inputObject.put("value", "测试");
js.executeScript("mobile: setValue", inputObject);

大概是这样 we 就是你要填值的那个元素

#13 楼 @spikeshen 是的。 中文没问题,因为 IOS instruments 里面是支持的。 appium 调用的就是 instruments

比如

this.app().alert().images()[0].textFields()[0].setValue("你好");

#15 楼 @spikeshen 请问 js.executeScript("mobile: setValue", inputObject); 这句代码怎么实现呢? js 是什么类型的?

#17 楼 @dippa JavascriptExecutor js = (JavascriptExecutor) wd;
wd 是 WebDriver 对象,你可以先看看 web driver 相关的文章学习下。

#18 楼 @spikeshen 可以直接调用 RemoteWebDriver 这个类型的吗?

#19 楼 @dippa 没试过,强转之后不知道会有啥问题。。。

#20 楼 @spikeshen 还是不行,输入失效。唉。。

#20 楼 @spikeshen
List elems = wd.findElements(By.tagName("UIATextField"));

for(WebElement e:elems){
HashMap inputObject = new HashMap();
inputObject.put("element", ((RemoteWebElement) e).getId());
inputObject.put("value", "123456");
JavascriptExecutor js = (JavascriptExecutor) wd;
js.executeScript("mobile: setValue", inputObject);
}

#20 楼 @spikeshen 这是那段运行的代码,Log 我也跟新在上面

@dippa 代码片段 用代码块扩起来吧。可以把每个 element 打印出来看看不

UIAWindow

UIAScrollView

UIAImage
login_bg_i5.png
UIAImage

UIAButton

UIAImage
app_logo.png
UIAStaticText

UIATableView
Empty list
UIATableCell
Agency
UIAStaticText
Agency
UIATextField

UIATableCell
User Name
UIAStaticText
User Name
UIATextField

UIATableCell
Password
UIAStaticText
Password
UIASecureTextField

UIAButton
Additional Settings
UIAButton
Sign In
UIAButton
Preview
UIAImage
accela_logo.png
UIAImage

UIAWindow

UIAKeyboard

UIAKey
q
UIAKey
w
UIAKey
e
UIAKey
r
UIAKey
t
UIAKey
y
UIAKey
u
UIAKey
i
UIAKey
o
UIAKey
p
UIAKey
a
UIAKey
s
UIAKey
d
UIAKey
f
UIAKey
g
UIAKey
h
UIAKey
j
UIAKey
k
UIAKey
l
UIAButton
shift
UIAKey
z
UIAKey
x
UIAKey
c
UIAKey
v
UIAKey
b
UIAKey
n
UIAKey
m
UIAKey
Delete
UIAKey
more, numbers
UIAButton
Next keyboard
UIAButton
Dictate
UIAKey
space
UIAButton
Return
UIAWindow

UIAStatusBar

UIAElement
Swipe down with three fingers to reveal the notification center., Swipe up with three fingers to reveal the control center, Double-tap to scroll to top
UIAElement
3 of 3 Wi-Fi bars
UIAElement
2:28 PM
UIAElement
100% battery power

//遍历所有对象

List elements = wd.findElementsByXPath("//*");
for(WebElement e:elements){
System.out.println(e.getTagName());
System.out.println(e.getAttribute("name"));
}

#24 楼 @lihuazhang 我用的是上面那段代码 打印所有的 element

#24 楼 @lihuazhang 就是一个登陆界面

#12 楼 @lihuazhang 坛子里在 MAC 上用 inspector 测试安卓的教程好像比较少, 我想问下该如何添加安卓的 app path ,我试过直接吧 apk 放上去,也不行,然后把工程文件压缩放上去也不行,请问是用什么放上去呢?

#29 楼 @dippa 那个 inspector 还是尽量少用吧, 他本身写的就不太好, 很多因素没考虑到, 基本全按照 ios 的标准来设计的, 你要是用他就会很多坑了.

遇到的问题, 可以通过调试 appium 来解决

9楼 已删除

List<WebElement> elems = wd.findElements(By.tagName("UIASecureTextField"));

for(WebElement e:elems){
         System.out.println(e.getTagName());
System.out.println(e.getAttribute("name"));
}   

打印这个看看?

#31 楼 @lihuazhang 我发现用 findElements 经常找出来的元素比我从 ui dump 下来的要多的多。。。

#31 楼 @lihuazhang

UIASecureTextField

#31 楼 @lihuazhang 这是打印出来的结果。只能打出 Tagname 。

#30 楼 @seveniruby 请问调试 appium 是什么意思呢?在黑框里写代码吗?

#35 楼 @dippa 我是说 debug java 代码

#36 楼 @lihuazhang debug 是要输出什么?

#36 楼 @lihuazhang 不好意思,我不是很懂什么意思,我知道 debug 是什么,但是不是很懂 debug java 代码是什么意思

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册