Skip to content

Commit

Permalink
fix(ios): support new RCTParagraphComponentView component.
Browse files Browse the repository at this point in the history
  • Loading branch information
asafkorem committed Dec 22, 2024
1 parent f458c49 commit d8a5d9c
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 38 deletions.
56 changes: 40 additions & 16 deletions detox/ios/Detox/Invocation/Predicate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -65,20 +65,32 @@ class Predicate : CustomStringConvertible, CustomDebugStringConvertible {
if ReactNativeSupport.isReactNativeApp == false {
return ValuePredicate(kind: kind, modifiers: modifiers, value: label, requiresAccessibilityElement: true, isRegex: isRegex)
} else {
//Will crash if RN app and neither class exists
let RCTTextViewClass : AnyClass = NSClassFromString("RCTText") ?? NSClassFromString("RCTTextView")!

let descendantPredicate = DescendantPredicate(predicate: AndCompoundPredicate(predicates: [
try KindOfPredicate(kind: Kind.type, modifiers: [], className: NSStringFromClass(RCTTextViewClass)),
ValuePredicate(kind: kind, modifiers: modifiers, value: label, requiresAccessibilityElement: true, isRegex: isRegex)
], modifiers: []), modifiers: [Modifier.not])
descendantPredicate.hidden = true

return AndCompoundPredicate(predicates: [
ValuePredicate(kind: kind, modifiers: modifiers, value: label, requiresAccessibilityElement: true, isRegex: isRegex),
descendantPredicate
], modifiers: [])
let possibleRNClasses: [AnyClass] = [
NSClassFromString("RCTParagraphComponentView"),
NSClassFromString("RCTText"),
NSClassFromString("RCTTextView")
].compactMap { $0 }

guard !possibleRNClasses.isEmpty else {
fatalError("No React Native text component classes found")
}

let typePredicates = possibleRNClasses.map { rnClass in
try! KindOfPredicate(kind: Kind.type, modifiers: [], className: NSStringFromClass(rnClass))
}

let descendantPredicate = DescendantPredicate(predicate: AndCompoundPredicate(predicates: [
OrCompoundPredicate(predicates: typePredicates, modifiers: []),
ValuePredicate(kind: kind, modifiers: modifiers, value: label, requiresAccessibilityElement: true, isRegex: isRegex)
], modifiers: []), modifiers: [Modifier.not])
descendantPredicate.hidden = true

return AndCompoundPredicate(predicates: [
ValuePredicate(kind: kind, modifiers: modifiers, value: label, requiresAccessibilityElement: true, isRegex: isRegex),
descendantPredicate
], modifiers: [])
}

case Kind.text:
let text = dictionaryRepresentation[Keys.value] as! String
var orPredicates = [
Expand All @@ -88,9 +100,21 @@ class Predicate : CustomStringConvertible, CustomDebugStringConvertible {
]

if ReactNativeSupport.isReactNativeApp == true {
//Will crash if RN app and neither class exists
let RCTTextViewClass : AnyClass = NSClassFromString("RCTText") ?? NSClassFromString("RCTTextView")!
orPredicates.append(try KindOfPredicate(kind: Kind.type, modifiers: [], className: NSStringFromClass(RCTTextViewClass)))
let possibleRNClasses: [AnyClass] = [
NSClassFromString("RCTParagraphComponentView"),
NSClassFromString("RCTText"),
NSClassFromString("RCTTextView")
].compactMap { $0 }

guard !possibleRNClasses.isEmpty else {
fatalError("No React Native text component classes found")
}

possibleRNClasses.forEach { rnClass in
let predicate = try! KindOfPredicate(kind: Kind.type, modifiers: [], className: NSStringFromClass(rnClass))

orPredicates.append(predicate)
}
}

let orCompoundPredicate = OrCompoundPredicate(predicates: orPredicates, modifiers: [])
Expand Down
60 changes: 38 additions & 22 deletions detox/ios/Detox/Utilities/NSObject+DontCrash.m
Original file line number Diff line number Diff line change
Expand Up @@ -11,32 +11,48 @@ @implementation NSObject (DontCrash)

- (id)_dtx_text
{
if([self respondsToSelector:@selector(text)])
{
return [(UITextView*)self text];
}

static Class RCTTextView;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
RCTTextView = NSClassFromString(@"RCTTextView");
});
if(RCTTextView != nil && [self isKindOfClass:RCTTextView])
{
return [(NSTextStorage*)[self valueForKey:@"textStorage"] string];
}

return nil;
if([self respondsToSelector:@selector(text)])
{
return [(UITextView*)self text];
}

static Class RCTParagraphComponentViewClass;
static Class RCTTextClass;
static Class RCTTextViewClass;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
RCTParagraphComponentViewClass = NSClassFromString(@"RCTParagraphComponentView");
RCTTextClass = NSClassFromString(@"RCTText");
RCTTextViewClass = NSClassFromString(@"RCTTextView");
});

if(RCTParagraphComponentViewClass != nil && [self isKindOfClass:RCTParagraphComponentViewClass])
{
NSAttributedString *attributedText = [self valueForKey:@"attributedText"];
return [attributedText string];
}

if(RCTTextClass != nil && [self isKindOfClass:RCTTextClass])
{
return [(NSTextStorage*)[self valueForKey:@"textStorage"] string];
}

if(RCTTextViewClass != nil && [self isKindOfClass:RCTTextViewClass])
{
return [(NSTextStorage*)[self valueForKey:@"textStorage"] string];
}

return nil;
}

- (id)_dtx_placeholder
{
if([self respondsToSelector:@selector(placeholder)])
{
return [(UITextField*)self placeholder];
}
return nil;
if([self respondsToSelector:@selector(placeholder)])
{
return [(UITextField*)self placeholder];
}

return nil;
}

@end

0 comments on commit d8a5d9c

Please sign in to comment.