XCUIElement API
2015-06-23 17:52
459 查看
XCUIElement 继承自
NSObject,XCUIElementAttributes(定义了一些控件元素属性,比如value,title等),XCUIElementTypeQueryProvider(一些元素集合的抽象,比如代表按钮的buttons),代表控件对象
目标App为WWDC上的演示的Lister
上面的信息中包含了我们查找textField的过程中所用的整个信息,信息分三部分
包含被查找控件的内存地址(0x7fbf6aeaad40),traits(146029150208),起始坐标、长和宽({{54.0, 120.0}, {306.0, 20.0}}),value值(Hello)
详细列出了找到该控件的路线,从Application->Window->…(多个Unknow的父控件)->Table->Cell->TextField
这一部分描述了是如何一步一步查询到当前控件的,根据case的写法会有不同的过程,其中有一些标识符很关键:
Find:表示操作目的
Input:输入,数据源
Ouput:输出,找到的对象
比如下面的一段就表示我们试图从Application的子孙中找寻Table控件,然后我们找到了Tabel 0x7fbf6aeb03b0对象。
NSObject,XCUIElementAttributes(定义了一些控件元素属性,比如value,title等),XCUIElementTypeQueryProvider(一些元素集合的抽象,比如代表按钮的buttons),代表控件对象
目标App为WWDC上的演示的Lister
方法
descendantsMatchingType
从该控件的后代控件中找到符合指定类型的控件(子子孙孙都认),需要传入XCUIElementType类型的参数,返回XCUIElementType类型的对象。childrenMatchingType
只从该控件的孩子节点中找到符合指定类型的控件(只认儿子),需要传入XCUIElementType类型的参数,返回XCUIElementType类型的对象。属性
exists
判断控件对象是否存在。BOOL类型。debugDescription
保存某控件的debug信息,这些信息只能用于case的调试,方便我们写case,不能作为测试的数据。NSString类型。扩展XCUIElement
无论OC和Swift都是在XCUIElement的基础上扩展如下方法tap
单击doubleTap
双击twoFingerTap
双指单击pressForDuration(duration: NSTimeInterval)
长按(Swift写法),时间由传入的参数定义,单位为秒pressForDuration(duration: NSTimeInterval, thenDragToElement otherElement: XCUIElement)
长按拖拽(Swift写法)。在控件上长按后,拖拽到另外一个控件。传入2个参数:长按时间和拖拽到目标控件。swipeUp
控件上滑动。从下划到上swipeDown
控件上滑动。从上滑到上swipeLeft
控件上滑动。从右滑到左swipeRight
控件上滑动。从左滑到右typeText
输入字符。需要一个参数:NSString实例
Swift版本
func testXCUIElementAPI() { // Use recording to get started writing UI tests. // Use XCTAssert and related functions to verify your tests produce the correct results. let app = XCUIApplication() //向上滑动 app.swipeUp() //向下滑动 app.swipeDown() //点击“Groceries”列进入子目录 app.tables.staticTexts["Groceries"].tap() //获取当前界面的表格对象 let tables = app.tables //定位到编辑框"Add Item" let addItemTextField = tables.textFields["Add Item"] //点击,焦点定位到编辑框 addItemTextField.tap() //输入Hello addItemTextField.typeText("Hello") //回车键 app.typeText("\r") //获取表格中的Cell对象,每一个表格单元都是一个Cell对象 let cells = tables.childrenMatchingType(.Cell) //获取第二个单元,跳过了输入框所在的行,XCUIElement对象 let cell = cells.elementAtIndex(1) cell.swipeLeft() cell.swipeRight() //从第一个单元中找到文本框控件集合,XCUIElementQuery对象 let textFields = cell.childrenMatchingType(.TextField) //let textFields = cell.descendantsMatchingType(.TextField) //获取第一个文本框控件,XCUIElement对象 let textField = textFields.elementAtIndex(0) if textField.exists{ //左滑然后右滑 textField.swipeLeft() textField.swipeRight() } //长按5.5秒 textField.pressForDuration(5.5) //打印debug的描述信息,也就是case执行过程中的查找过程 print(textFields.debugDescription) }
OC版本
-(void)testXCUIElementAPI { XCUIApplication *app = [[XCUIApplication alloc] init]; //向上滑动 [app swipeUp]; //向下滑动 [app swipeDown]; //点击“Groceries”列进入子目录 [app.tables.staticTexts[@"Groceries"] tap]; //获取当前界面的表格对象 XCUIElementQuery *tables = app.tables; //定位到编辑框"Add Item" XCUIElement *addItemTextField = tables.textFields[@"Add Item"]; //点击,焦点定位到编辑框 [addItemTextField tap]; //输入Hello [addItemTextField typeText:@"Hello"]; //回车键 [app typeText:@"\r"]; //获取表格中的Cell对象,每一个表格单元都是一个Cell对象 XCUIElementQuery *cells = [tables childrenMatchingType:XCUIElementTypeCell]; //获取第二个单元,跳过了输入框所在的行,XCUIElement对象 XCUIElement *cell = [cells elementAtIndex:1]; [cell swipeLeft]; [cell swipeRight]; //从第一个单元中找到文本框控件集合,XCUIElementQuery对象 XCUIElementQuery *textFields = [cell childrenMatchingType:XCUIElementTypeTextField]; //XCUIElementQuery *textFields = [cell descendantsMatchingType:XCUIElementTypeTextField]; //获取第一个文本框控件,XCUIElement对象 XCUIElement *textField = [textFields elementAtIndex:0]; if ([textField exists]) { //左滑然后右滑 [textField swipeLeft]; [textField swipeRight]; } //长按5.5秒 [textField pressForDuration:5.5]; //打印debug的描述信息,也就是case执行过程中的查找过程 NSLog(@" %@ ",[textField debugDescription]); }
源码
Swift版本
@available(iOS 9.0, *) class XCUIElement : NSObject, XCUIElementAttributes, XCUIElementTypeQueryProvider { var exists: Bool { get } func descendantsMatchingType(type: XCUIElementType) -> XCUIElementQuery func childrenMatchingType(type: XCUIElementType) -> XCUIElementQuery var debugDescription: String { get } } extension XCUIElement { func tap() func doubleTap() func twoFingerTap() func pressForDuration(duration: NSTimeInterval) func pressForDuration(duration: NSTimeInterval, thenDragToElement otherElement: XCUIElement) func swipeUp() func swipeDown() func swipeLeft() func swipeRight() func typeText(text: String) }
OC版本
NS_CLASS_AVAILABLE(10_11, 9_0) @interface XCUIElement : NSObject <XCUIElementAttributes, XCUIElementTypeQueryProvider> @property (readonly) BOOL exists; - (XCUIElementQuery *)descendantsMatchingType:(XCUIElementType)type; - (XCUIElementQuery *)childrenMatchingType:(XCUIElementType)type; @property (readonly, copy) NSString *debugDescription; @end #pragma mark - Event Synthesis @interface XCUIElement (XCUIElementEventSynthesis) #if TARGET_OS_IPHONE - (void)tap; - (void)doubleTap; - (void)twoFingerTap; - (void)pressForDuration:(NSTimeInterval)duration; - (void)pressForDuration:(NSTimeInterval)duration thenDragToElement:(XCUIElement *)otherElement; - (void)swipeUp; - (void)swipeDown; - (void)swipeLeft; - (void)swipeRight; - (void)typeText:(NSString *)text; #else - (void)hover; - (void)click; - (void)doubleClick; - (void)rightClick; - (void)clickForDuration:(NSTimeInterval)duration thenDragToElement:(XCUIElement *)otherElement; + (void)performWithKeyModifiers:(XCUIKeyModifierFlags)flags block:(void (^)(void))block; - (void)typeText:(NSString *)text; - (void)typeKey:(NSString *)key modifierFlags:(XCUIKeyModifierFlags)flags; - (void)scrollByDeltaX:(CGFloat)deltaX deltaY:(CGFloat)deltaY; #endif @end
其他
OC中调用debugDescription信息说明
实例中调用debugDescription打印的信息如下:
Attributes: TextField 0x7fbf6aeaad40: traits: 146029150208, {{54.0, 120.0}, {306.0, 20.0}}, value: Hello Element subtree: →TextField 0x7fbf6aeaad40: traits: 146029150208, {{54.0, 120.0}, {306.0, 20.0}}, value: Hello Path to element: →Application 0x7fbf6ae8c9f0: {{0.0, 0.0}, {375.0, 667.0}}, title: 'Lister', label: 'Lister' ↳Window 0x7fbf6d028210: Main Window, {{0.0, 0.0}, {375.0, 667.0}} ↳Unknown 0x7fbf6d028880: {{0.0, 0.0}, {375.0, 667.0}} ↳Unknown 0x7fbf6d029790: {{0.0, 0.0}, {375.0, 667.0}} ↳Unknown 0x7fbf6aea8d50: {{0.0, 0.0}, {375.0, 667.0}} ↳Unknown 0x7fbf6aea57f0: {{0.0, 0.0}, {375.0, 667.0}} ↳Unknown 0x7fbf6aeb1500: {{0.0, 0.0}, {375.0, 667.0}} ↳Unknown 0x7fbf6aeb5fa0: {{0.0, 0.0}, {375.0, 667.0}} ↳Unknown 0x7fbf6aeb3080: {{0.0, 0.0}, {375.0, 667.0}} ↳Table 0x7fbf6aeb03b0: traits: 35192962023424, {{0.0, 0.0}, {375.0, 667.0}} ↳Cell 0x7fbf6aead2b0: traits: 8589934592, {{0.0, 108.0}, {375.0, 44.0}} ↳TextField 0x7fbf6aeaad40: traits: 146029150208, {{54.0, 120.0}, {306.0, 20.0}}, value: Hello Query chain: →Find: Target Application ↪︎Find: Descendants matching type Table Input: { Application 0x7fbf6ae8c9f0: {{0.0, 0.0}, {375.0, 667.0}}, title: 'Lister', label: 'Lister' } Output: { Table 0x7fbf6aeb03b0: traits: 35192962023424, {{0.0, 0.0}, {375.0, 667.0}} } ↪︎Find: Children matching type Cell Input: { Table 0x7fbf6aeb03b0: traits: 35192962023424, {{0.0, 0.0}, {375.0, 667.0}} } Output: { Cell 0x7fbf6aca03a0: traits: 8589934592, {{0.0, 64.0}, {375.0, 44.0}} Cell 0x7fbf6aead2b0: traits: 8589934592, {{0.0, 108.0}, {375.0, 44.0}} Cell 0x7fbf6aea8020: traits: 8589934592, {{0.0, 152.0}, {375.0, 44.0}} Cell 0x7fbf6aea6940: traits: 8589934592, {{0.0, 196.0}, {375.0, 44.0}} Cell 0x7fbf6acb98a0: traits: 8589934592, {{0.0, 240.0}, {375.0, 44.0}} Cell 0x7fbf6ac7ed80: traits: 8589934592, {{0.0, 284.0}, {375.0, 44.0}} Cell 0x7fbf6ac7d490: traits: 8589934592, {{0.0, 328.0}, {375.0, 44.0}} Cell 0x7fbf6ac82a40: traits: 8589934592, {{0.0, 372.0}, {375.0, 44.0}} Cell 0x7fbf6ac9ab00: traits: 8589934592, {{0.0, 416.0}, {375.0, 44.0}} Cell 0x7fbf6ac9b0b0: traits: 8589934592, {{0.0, 460.0}, {375.0, 44.0}} Cell 0x7fbf6ac8cc90: traits: 8589934592, {{0.0, 504.0}, {375.0, 44.0}} Cell 0x7fbf6acb9dd0: traits: 8589934592, {{0.0, 548.0}, {375.0, 44.0}} Cell 0x7fbf6acbeab0: traits: 8589934592, {{0.0, 592.0}, {375.0, 44.0}} Cell 0x7fbf6acc4890: traits: 8589934592, {{0.0, 636.0}, {375.0, 44.0}} Cell 0x7fbf6aca8a00: traits: 8589934592, {{0.0, 680.0}, {375.0, 44.0}} Cell 0x7fbf6acbb820: traits: 8589934592, {{0.0, 724.0}, {375.0, 44.0}} } ↪︎Find: elementAtIndex Input: { Cell 0x7fbf6aca03a0: traits: 8589934592, {{0.0, 64.0}, {375.0, 44.0}} Cell 0x7fbf6aead2b0: traits: 8589934592, {{0.0, 108.0}, {375.0, 44.0}} Cell 0x7fbf6aea8020: traits: 8589934592, {{0.0, 152.0}, {375.0, 44.0}} Cell 0x7fbf6aea6940: traits: 8589934592, {{0.0, 196.0}, {375.0, 44.0}} Cell 0x7fbf6acb98a0: traits: 8589934592, {{0.0, 240.0}, {375.0, 44.0}} Cell 0x7fbf6ac7ed80: traits: 8589934592, {{0.0, 284.0}, {375.0, 44.0}} Cell 0x7fbf6ac7d490: traits: 8589934592, {{0.0, 328.0}, {375.0, 44.0}} Cell 0x7fbf6ac82a40: traits: 8589934592, {{0.0, 372.0}, {375.0, 44.0}} Cell 0x7fbf6ac9ab00: traits: 8589934592, {{0.0, 416.0}, {375.0, 44.0}} Cell 0x7fbf6ac9b0b0: traits: 8589934592, {{0.0, 460.0}, {375.0, 44.0}} Cell 0x7fbf6ac8cc90: traits: 8589934592, {{0.0, 504.0}, {375.0, 44.0}} Cell 0x7fbf6acb9dd0: traits: 8589934592, {{0.0, 548.0}, {375.0, 44.0}} Cell 0x7fbf6acbeab0: traits: 8589934592, {{0.0, 592.0}, {375.0, 44.0}} Cell 0x7fbf6acc4890: traits: 8589934592, {{0.0, 636.0}, {375.0, 44.0}} Cell 0x7fbf6aca8a00: traits: 8589934592, {{0.0, 680.0}, {375.0, 44.0}} Cell 0x7fbf6acbb820: traits: 8589934592, {{0.0, 724.0}, {375.0, 44.0}} } Output: { Cell 0x7fbf6aead2b0: traits: 8589934592, {{0.0, 108.0}, {375.0, 44.0}} } ↪︎Find: Children matching type TextField Input: { Cell 0x7fbf6aead2b0: traits: 8589934592, {{0.0, 108.0}, {375.0, 44.0}} } Output: { TextField 0x7fbf6aeaad40: traits: 146029150208, {{54.0, 120.0}, {306.0, 20.0}}, value: Hello } ↪︎Find: elementAtIndex Input: { TextField 0x7fbf6aeaad40: traits: 146029150208, {{54.0, 120.0}, {306.0, 20.0}}, value: Hello } Output: { TextField 0x7fbf6aeaad40: traits: 146029150208, {{54.0, 120.0}, {306.0, 20.0}}, value: Hello }
上面的信息中包含了我们查找textField的过程中所用的整个信息,信息分三部分
第一部分:Attributes
Attributes: TextField 0x7fbf6aeaad40: traits: 146029150208, {{54.0, 120.0}, {306.0, 20.0}}, value: Hello
包含被查找控件的内存地址(0x7fbf6aeaad40),traits(146029150208),起始坐标、长和宽({{54.0, 120.0}, {306.0, 20.0}}),value值(Hello)
第二部分:Path to element
Path to element: →Application 0x7fbf6ae8c9f0: {{0.0, 0.0}, {375.0, 667.0}}, title: 'Lister', label: 'Lister' ↳Window 0x7fbf6d028210: Main Window, {{0.0, 0.0}, {375.0, 667.0}} ↳Unknown 0x7fbf6d028880: {{0.0, 0.0}, {375.0, 667.0}} ↳Unknown 0x7fbf6d029790: {{0.0, 0.0}, {375.0, 667.0}} ↳Unknown 0x7fbf6aea8d50: {{0.0, 0.0}, {375.0, 667.0}} ↳Unknown 0x7fbf6aea57f0: {{0.0, 0.0}, {375.0, 667.0}} ↳Unknown 0x7fbf6aeb1500: {{0.0, 0.0}, {375.0, 667.0}} ↳Unknown 0x7fbf6aeb5fa0: {{0.0, 0.0}, {375.0, 667.0}} ↳Unknown 0x7fbf6aeb3080: {{0.0, 0.0}, {375.0, 667.0}} ↳Table 0x7fbf6aeb03b0: traits: 35192962023424, {{0.0, 0.0}, {375.0, 667.0}} ↳Cell 0x7fbf6aead2b0: traits: 8589934592, {{0.0, 108.0}, {375.0, 44.0}} ↳TextField 0x7fbf6aeaad40: traits: 146029150208, {{54.0, 120.0}, {306.0, 20.0}}, value: Hello
详细列出了找到该控件的路线,从Application->Window->…(多个Unknow的父控件)->Table->Cell->TextField
第三部分:Query chain
这一部分Swift中debugDescription方法也能得到。
这一部分描述了是如何一步一步查询到当前控件的,根据case的写法会有不同的过程,其中有一些标识符很关键:
Find:表示操作目的
Input:输入,数据源
Ouput:输出,找到的对象
比如下面的一段就表示我们试图从Application的子孙中找寻Table控件,然后我们找到了Tabel 0x7fbf6aeb03b0对象。
↪︎Find: Descendants matching type Table Input: { Application 0x7fbf6ae8c9f0: {{0.0, 0.0}, {375.0, 667.0}}, title: 'Lister', label: 'Lister' } Output: { Table 0x7fbf6aeb03b0: traits: 35192962023424, {{0.0, 0.0}, {375.0, 667.0}} }
相关文章推荐
- HUE 3.7.0 安装与配置
- iOS学习笔记(1)UILable详解
- easyui datagrid 弹出窗口
- 细数AutoLayout以来UIView和UIViewController新增的相关API
- Control Arduino with TP-Link TL-WR1043ND Router
- java中gui实现跟踪鼠标
- apkbuilder
- java中gui编程ActionListener和itemListener
- java中的gui实现事件监听
- hbulider mui框架
- Azure Queue队列存储(2)
- QuickFIX/N入门:二、发送消息及接收消息
- IOS-- UIView中的坐标转换
- QuickFIX/N入门:一、如何创建一个QuickFIX/N的应用程序
- QuickFIX/N入门:使用消息循环分组
- QuickFIX/N入门:如何自定义FIX
- mysql sequence
- UIScroll View 和 AutoLayout
- 8_Ueditor编辑器和Echarts的使用
- UE4 AI入门