ios - ¿Puedo verificar si existe una vista en la pantalla con KIF?
(7)
Estoy haciendo un paso "antes de cada" y deseo hacer pasos para cerrar la sesión. No puedo encontrar nada acerca de verificar si existe un elemento antes de intentar tocarlo, luego, si no existe, haga otra cosa. ¿Es posible hacer esto con KIF sin tener una referencia al objeto que quiero verificar?
Algo como:
if([tester elementExistsWithAccesibilityLabel:@"backButton"])
{
[tester tapViewWithAccessibilityLabel:@"backButton"];
}
else
{
[tester tapViewwithAccesibilityLabel:@"Logout"];
}
Bien, ninguno de estos funcionó para mí ... Sin embargo, tengo una solución
Echa un vistazo a esta esencia.
Lo que he hecho es tomar el código de KIF y eliminar su comprobación de errores, funciona como un encanto para mí.
¡Esto no fallará en tus pruebas cuando no pueda encontrar un elemento!
En caso de que alguien todavía esté buscando una respuesta, hay una familia de métodos en KIF que hace precisamente eso 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;
Si está utilizando las adiciones del Identificador de accesibilidad ( pod ''KIF/IdentifierTests''
), también hay un método equivalente muy útil: - (BOOL) tryFindingViewWithAccessibilityIdentifier:(NSString *) accessibilityIdentifier;
Estos métodos hacen el truco. Agréguelos a una categoría para 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;
}
Me funciona muy bien.
Hice esta función que parece hacer el truco en un apuro, pero tendría algunos problemas si múltiples pruebas de integración dependieran simultáneamente del tiempo de espera predeterminado global. Hasta ahora, parece funcionar para mí.
static CGFloat CPKIFDefaultTimeout = 2
- (BOOL)elementExistsWithAccessibilityLabel:(NSString *)accessibilityLabel {
[KIFTestActor setDefaultTimeout:0.0];
BOOL result = [tester waitForViewWithAccessibilityLabel:accessibilityLabel] ? YES : NO;
[KIFTestActor CPKIFDefaultTimeout];
return result;
}
Para 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
}
}
Podrías probar algo como esto:
@try {
if([tester waitForViewWithAccessibilityLabel:@"backButton"])
{
[tester tapViewWithAccessibilityLabel:@"backButton"];
}
@catch (NSException *exception )
{
[tester tapViewwithAccesibilityLabel:@"Logout"];
}
@finally
{
NSLOG(@"User logged out.");
}
Sugeriría probar este enfoque:
if([[[UIApplication sharedApplication] keyWindow] accessibilityElementWithLabel:@"backButton"] != nil) {
[tester tapViewWithAccessibilityLabel:@"backButton"];
} else {
[tester tapViewWithAccessibilityLabel:@"Logout"];
}