如何在不使用坐标方法的情况下在 XCode UI 测试中点击字符串语句的特定部分/单词
Posted
技术标签:
【中文标题】如何在不使用坐标方法的情况下在 XCode UI 测试中点击字符串语句的特定部分/单词【英文标题】:How to tap on specific part/Words of a string statement in XCode UI Tests without using coordinate method 【发布时间】:2017-02-16 07:30:56 【问题描述】:我想在我的应用程序中点击以下行中的“条款和条件”:
“我同意条款和条件和隐私政策”
上一行中的“条款和条件”字符串不是链接,它作为整个TextView
的一部分存在,我想点击特定的“条款和条件”。虽然我可以使用以下代码行提取字符串语句:
let app = XCUIApplication()
let strValue = app.textViews.element(boundBy: 0).value as! String
print(strValue)
【问题讨论】:
【参考方案1】:这是我使用的 [Objective-C] 示例:
text = @"I agree to the Terms & Conditions and Privacy Policy"
- (void)setText:(NSString *)text forLabel:(UILabel *)label
NSString *wholeNoteText = text;
termsRange = [text rangeOfString:@"Terms & Conditions"];
policyRange = [text rangeOfString:@"Privacy Policy")];
NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:wholeNoteText attributes:nil];
NSDictionary *linkAttributes = @
NSForegroundColorAttributeName: YourAppColor,
NSFontAttributeName: YourFavouriteFont
;
[attributedString setAttributes:linkAttributes range:termsRange];
[attributedString setAttributes:linkAttributes range:policyRange];
label.attributedText = attributedString;
[label addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTapOnLabel:)]];
[label setUserInteractionEnabled:YES];
// Create instances of NSLayoutManager, NSTextContainer and NSTextStorage
layoutManager = [[NSLayoutManager alloc] init];
textContainer = [[NSTextContainer alloc] initWithSize:CGSizeZero];
textStorage = [[NSTextStorage alloc] initWithAttributedString:attributedString];
// Configure layoutManager and textStorage
[layoutManager addTextContainer:textContainer];
[textStorage addLayoutManager:layoutManager];
// Configure textContainer
textContainer.lineFragmentPadding = 0.0;
textContainer.lineBreakMode = label.lineBreakMode;
textContainer.maximumNumberOfLines = label.numberOfLines;
- (void)handleTapOnLabel:(UITapGestureRecognizer *)tapGestureOnLabel
CGPoint locationOfTouchInLabel = [tapGestureOnLabel locationInView:tapGestureOnLabel.view];
CGSize labelSize = tapGestureOnLabel.view.frame.size;
CGRect textBoundingBox = [layoutManager usedRectForTextContainer:textContainer];
CGPoint textContainerOffset = CGPointMake((labelSize.width - textBoundingBox.size.width) * 0.5 - textBoundingBox.origin.x,
(labelSize.height - textBoundingBox.size.height) * 0.5 - textBoundingBox.origin.y);
CGPoint locationOfTouchInTextContainer = CGPointMake(locationOfTouchInLabel.x - textContainerOffset.x,
locationOfTouchInLabel.y - textContainerOffset.y);
locationOfTouchInTextContainer.y -= 10; // WARNING magic number
NSInteger indexOfCharacter = [layoutManager characterIndexForPoint:locationOfTouchInTextContainer
inTextContainer:textContainer
fractionOfDistanceBetweenInsertionPoints:nil];
UIViewController *controller = [[TermsOfServiceVC alloc] init];
if (NSLocationInRange(indexOfCharacter, termsRange))
controller = [[PolicyVC alloc] init];
[self.navigationController pushViewController:controller animated:YES];
希望它会有所帮助。
【讨论】:
【参考方案2】:如果您的应用程序的功能是点击“条款和条件”可以执行某些操作,但点击字符串的其他部分没有执行操作,则可能会有另一个视图不是 UILabel (staticText),它只跨越部分文本显示“条款和条件”。寻找那个视图而不是 staticText。
我的猜测是它要么是一个普通的 UIView (otherElement) 要么是一个按钮。为其添加一个可访问性标识符,然后点击该视图,而不是尝试查找 UILabel 的特定部分。
【讨论】:
实际上从开发人员的角度来看,它基于“静态文本的范围”,在该范围内调用了一个事件。从自动化的角度来看,我能够获得“条款和条件”的范围,但无法利用它。以上是关于如何在不使用坐标方法的情况下在 XCode UI 测试中点击字符串语句的特定部分/单词的主要内容,如果未能解决你的问题,请参考以下文章
有没有办法在不使用 jQuery UI 和 jQuery Mobile 的情况下在 jQuery 中左右滑动 [重复]
如何在不中断删除的情况下在 SwiftUI 中实现 TextField 列表
如何在不使用 Api 的情况下在 uitableview 中进行分页?
如何在不连接它们的情况下在 MapView 上绘制两个 MKPolygons?
有没有一种方法可以在不使用 Xcode 11 在 iPhone 上构建 UI 的情况下测量 Swift 的性能? [关闭]