如何在不使用坐标方法的情况下在 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 的性能? [关闭]

如何在不使用数据透视和反透视的情况下在 SQL Server 中水平显示数据?