您的位置:首页 > 产品设计 > UI/UE

XCUIElement API

2015-06-23 17:52 459 查看
XCUIElement 继承自

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}}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: