【问题标题】:Can I check if a view exists on the screen with KIF?我可以使用 KIF 检查屏幕上是否存在视图吗?
【发布时间】:2013-09-18 15:46:39
【问题描述】:

我正在做一个“在每个步骤之前”,并且我想做一些步骤来注销。在尝试触摸元素之前,我找不到任何有关检查元素是否存在的信息,然后如果它不存在,请执行其他操作。是否可以在不引用我要检查的对象的情况下使用 KIF 执行此操作?

类似:

if([tester elementExistsWithAccesibilityLabel:@"backButton"])
{
    [tester tapViewWithAccessibilityLabel:@"backButton"];
}
else
{
    [tester tapViewwithAccesibilityLabel:@"Logout"];
}

【问题讨论】:

    标签: ios kif


    【解决方案1】:

    如果使用 Swift 你可以简单地使用viewTester().tryFindingView():

    if viewTester().usingLabel("backButton").tryFindingView() {
        // back button exists
        viewTester().usingLabel("backButton").tap()
    } else {
        // back button does not exist
        viewTester().usingLabel("Logout").tap()
    }
    

    【讨论】:

      【解决方案2】:

      对于 Swift 3:

      /** return true when the view is found */
      func searchForElement(_ label:String) -> Bool{
          do {
              try tester().tryFindingView(withAccessibilityLabel: label)
              return true
          } catch {
              return false
      
          }
      }
      

      【讨论】:

        【解决方案3】:

        如果有人仍在寻找答案,KIF 中有一系列方法可以做到这一点KIFUITestActor-ConditionalTests.h

        - (BOOL)tryFindingViewWithAccessibilityLabel:(NSString *)label error:(out NSError **)error;
        
        - (BOOL)tryFindingViewWithAccessibilityLabel:(NSString *)label traits:(UIAccessibilityTraits)traits error:(out NSError **)error;
        
        - (BOOL)tryFindingViewWithAccessibilityLabel:(NSString *)label value:(NSString *)value traits:(UIAccessibilityTraits)traits error:(out NSError **)error;
        
        - (BOOL)tryFindingTappableViewWithAccessibilityLabel:(NSString *)label error:(out NSError **)error;
        
        - (BOOL)tryFindingTappableViewWithAccessibilityLabel:(NSString *)label traits:(UIAccessibilityTraits)traits error:(out NSError **)error;
        
        - (BOOL)tryFindingTappableViewWithAccessibilityLabel:(NSString *)label value:(NSString *)value traits:(UIAccessibilityTraits)traits error:(out NSError **)error;
        
        - (BOOL)tryFindingAccessibilityElement:(out UIAccessibilityElement **)element view:(out UIView **)view withIdentifier:(NSString *)identifier tappable:(BOOL)mustBeTappable error:(out NSError **)error;
        
        - (BOOL)tryFindingAccessibilityElement:(out UIAccessibilityElement **)element view:(out UIView **)view withElementMatchingPredicate:(NSPredicate *)predicate tappable:(BOOL)mustBeTappable error:(out NSError **)error;
        

        如果您使用辅助功能标识符添加 (pod 'KIF/IdentifierTests'),还有非常方便的等效方法: - (BOOL) tryFindingViewWithAccessibilityIdentifier:(NSString *) accessibilityIdentifier;

        【讨论】:

          【解决方案4】:

          这些方法可以解决问题。将它们添加到 KIFUITestActor 的类别中。

          #import "UIApplication-KIFAdditions.h" 
          #import "UIAccessibilityElement-KIFAdditions.h"
          #import "NSError-KIFAdditions.h"
          
          - (BOOL)existsViewWithAccessibilityLabel:(NSString *)label
          {
              UIView *view = nil;
              UIAccessibilityElement *element = nil;
              return [self existsAccessibilityElement:&element view:&view withLabel:label value:nil traits:UIAccessibilityTraitNone tappable:YES];
          }
          
          - (BOOL)existsAccessibilityElement:(UIAccessibilityElement **)element view:(out UIView **)view withLabel:(NSString *)label value:(NSString *)value traits:(UIAccessibilityTraits)traits tappable:(BOOL)mustBeTappable
          {
              KIFTestStepResult (^executionBlock)(NSError **) = ^(NSError **error) {
                  return [UIAccessibilityElement accessibilityElement:element view:view withLabel:label value:value traits:traits tappable:mustBeTappable error:error] ? KIFTestStepResultSuccess : KIFTestStepResultWait;
              };
          
              NSDate *startDate = [NSDate date];
              KIFTestStepResult result;
              NSError *error = nil;
              NSTimeInterval timeout = 10.0;
          
              while ((result = executionBlock(&error)) == KIFTestStepResultWait && -[startDate timeIntervalSinceNow] < timeout) {
                  CFRunLoopRunInMode([[UIApplication sharedApplication] currentRunLoopMode] ?: kCFRunLoopDefaultMode, 0.1, false);
              }
          
              if (result == KIFTestStepResultWait) {
                  error = [NSError KIFErrorWithUnderlyingError:error format:@"The step timed out after %.2f seconds: %@", timeout, error.localizedDescription];
                  result = KIFTestStepResultFailure;
              }
          
              return (result == KIFTestStepResultSuccess) ? YES : NO;
          }
          

          它非常适合我。

          【讨论】:

          • 这对我有用,但记得把它放在@autorelease{ ... }中。
          • 添加了必要的头文件导入以使代码正确编译。
          【解决方案5】:

          我建议尝试这种方法:

          if([[[UIApplication sharedApplication] keyWindow] accessibilityElementWithLabel:@"backButton"] != nil) {
               [tester tapViewWithAccessibilityLabel:@"backButton"];
          } else {
               [tester tapViewWithAccessibilityLabel:@"Logout"];
          }
          

          【讨论】:

          • 如果视图在视图层次结构中但当前在另一个 VC 已呈现时在屏幕上不可见,则此方法不起作用。
          【解决方案6】:

          好吧,这些都不适合我...但是我有一个解决方案

          结帐this gist.

          我所做的是采用 KIF 的代码,只是删除了它们的错误检查 - 对我来说就像一个魅力。

          当它找不到元素时,它不会让你的测试失败!

          【讨论】:

            【解决方案7】:

            我制作的这个函数似乎可以解决问题,但如果多个集成测试同时依赖于全局默认超时,则会出现一些问题。到目前为止,似乎对我有用。

            static CGFloat CPKIFDefaultTimeout = 2
            
            - (BOOL)elementExistsWithAccessibilityLabel:(NSString *)accessibilityLabel {
                [KIFTestActor setDefaultTimeout:0.0];
                BOOL result = [tester waitForViewWithAccessibilityLabel:accessibilityLabel] ? YES : NO;
                [KIFTestActor CPKIFDefaultTimeout];
                return result;
            }
            

            【讨论】:

            • 不适用于 Xocde8.2。测试在以下行停止:tester waitForViewWithAccessibilityLabel:accessibilityLabel.
            【解决方案8】:

            你可以试试这样的:

            @try {
               if([tester waitForViewWithAccessibilityLabel:@"backButton"])
               {
                  [tester tapViewWithAccessibilityLabel:@"backButton"];
               }
            @catch (NSException *exception )
            {
               [tester tapViewwithAccesibilityLabel:@"Logout"];
            }
            @finally 
            {
               NSLOG(@"User logged out.");
            }
            

            【讨论】:

            • 这不起作用,因为异常首先由我的 KIF 代码处理,并且永远不会到达代码中的 @try 块。
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-03-20
            • 1970-01-01
            • 2023-03-26
            • 2015-03-29
            • 1970-01-01
            • 2023-03-07
            相关资源
            最近更新 更多