Skip to content

Commit

Permalink
[iOS] Several API tests fail when run against an iPhone 12 simulator
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=256860
rdar://109230218

Reviewed by Aditya Keerthi.

Adjust several API tests and test infrastructure to be more robust to underlying platform changes,
and also ensure consistent test results when running a subset of API tests against notchless vs.
notched iPhone models when using `TestWKWebView`, by normalizing the safe area insets to 0 by
default.

* Tools/TestWebKitAPI/Tests/WebKitCocoa/RestoreScrollPosition.mm:
(-[RestoreScrollPositionWithLargeContentInsetWebView safeAreaInsets]): Deleted.

Remove this subclass entirely, and instead use the new `-setOverrideTopSafeAreaInset:` helper.

* Tools/TestWebKitAPI/Tests/ios/KeyboardInputTestsIOS.mm:
(-[TestWKWebView waitForCaretVisibility:]):

Make this test robust against platform differences on iOS in caret UI and whether or not we zoom
upon focusing an element, by making these tests check for the presence or absence of the caret
rather than specific caret rects. This was the original intent of the API test added in 203447@main,
anyways.

(-[TestWKWebView waitForCaretViewFrameToBecome:]): Deleted.
* Tools/TestWebKitAPI/cocoa/TestWKWebView.h:
* Tools/TestWebKitAPI/cocoa/TestWKWebView.mm:
(-[TestWKWebView initWithFrame:configuration:addToWindow:]):
(-[TestWKWebView overrideSafeAreaInset]):
(-[TestWKWebView setOverrideSafeAreaInset:]):
(-[TestWKWebView safeAreaInsets]):

Canonical link: https://commits.webkit.org/264150@main
  • Loading branch information
whsieh committed May 17, 2023
1 parent 517a80a commit 90f6849
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 27 deletions.
15 changes: 2 additions & 13 deletions Tools/TestWebKitAPI/Tests/WebKitCocoa/RestoreScrollPosition.mm
Expand Up @@ -32,18 +32,6 @@
#import <WebKit/WKWebViewPrivate.h>
#import <WebKit/_WKProcessPoolConfiguration.h>

#if PLATFORM(IOS_FAMILY)
@interface RestoreScrollPositionWithLargeContentInsetWebView : TestWKWebView
@end

@implementation RestoreScrollPositionWithLargeContentInsetWebView
- (UIEdgeInsets)safeAreaInsets
{
return UIEdgeInsetsMake(141, 0, 0, 0);
}
@end
#endif

namespace TestWebKitAPI {

#if PLATFORM(IOS_FAMILY)
Expand All @@ -52,7 +40,8 @@ - (UIEdgeInsets)safeAreaInsets
{
auto topInset = 1165;

auto webView = adoptNS([[RestoreScrollPositionWithLargeContentInsetWebView alloc] initWithFrame:CGRectMake(0, 0, 375, 1024)]);
auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 375, 1024)]);
[webView setOverrideSafeAreaInset:UIEdgeInsetsMake(141, 0, 0, 0)];

[webView synchronouslyLoadTestPageNamed:@"simple-tall"];

Expand Down
30 changes: 16 additions & 14 deletions Tools/TestWebKitAPI/Tests/ios/KeyboardInputTestsIOS.mm
Expand Up @@ -42,6 +42,12 @@
#import <WebKitLegacy/WebEvent.h>
#import <cmath>

namespace TestWebKitAPI {

enum class CaretVisibility : bool { Hidden, Visible };

}

@interface WKContentView ()
@property (nonatomic, readonly) NSUndoManager *undoManagerForWebView;
- (BOOL)_shouldSimulateKeyboardInputOnTextInsertion;
Expand Down Expand Up @@ -109,20 +115,20 @@ static CGRect rounded(CGRect rect)
return CGRectMake(std::round(rect.origin.x), std::round(rect.origin.y), std::round(rect.size.width), std::round(rect.size.height));
}

- (void)waitForCaretViewFrameToBecome:(CGRect)frame
- (void)waitForCaretVisibility:(TestWebKitAPI::CaretVisibility)visibility
{
BOOL hasEmittedWarning = NO;
NSTimeInterval secondsToWaitUntilWarning = 2;
NSTimeInterval startTime = [NSDate timeIntervalSinceReferenceDate];
while ([[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantPast]]) {
CGRect currentFrame = rounded(self.caretViewRectInContentCoordinates);
if (CGRectEqualToRect(currentFrame, frame))
BOOL sizeIsEmpty = CGSizeEqualToSize(self.caretViewRectInContentCoordinates.size, CGSizeZero);
if ((visibility == TestWebKitAPI::CaretVisibility::Hidden) == sizeIsEmpty)
break;

if (hasEmittedWarning || startTime + secondsToWaitUntilWarning >= [NSDate timeIntervalSinceReferenceDate])
continue;

NSLog(@"Expected a caret rect of %@, but still observed %@", NSStringFromCGRect(frame), NSStringFromCGRect(currentFrame));
NSLog(@"Expected the caret to %s", visibility == TestWebKitAPI::CaretVisibility::Hidden ? "disappear" : "appear");
hasEmittedWarning = YES;
}
}
Expand Down Expand Up @@ -477,19 +483,17 @@ - (NSUndoManager *)undoManager

TEST(KeyboardInputTests, CaretSelectionRectAfterRestoringFirstResponderWithRetainActiveFocusedState)
{
// This difference in caret width is due to the fact that we don't zoom in to the input field on iPad, but do on iPhone.
auto expectedCaretRect = CGRectMake(14, 11, UIDevice.currentDevice.userInterfaceIdiom == UIUserInterfaceIdiomPad ? 3 : 2, 15);
auto [webView, inputDelegate] = webViewAndInputDelegateWithAutofocusedInput();
EXPECT_WK_STREQ("INPUT", [webView stringByEvaluatingJavaScript:@"document.activeElement.tagName"]);
[webView waitForCaretViewFrameToBecome:expectedCaretRect];
[webView waitForCaretVisibility:CaretVisibility::Visible];

dispatch_block_t restoreActiveFocusState = [webView _retainActiveFocusedState];
[webView resignFirstResponder];
restoreActiveFocusState();
[webView waitForCaretViewFrameToBecome:CGRectZero];
[webView waitForCaretVisibility:CaretVisibility::Hidden];

[webView becomeFirstResponder];
[webView waitForCaretViewFrameToBecome:expectedCaretRect];
[webView waitForCaretVisibility:CaretVisibility::Visible];
}

TEST(KeyboardInputTests, RangedSelectionRectAfterRestoringFirstResponderWithRetainActiveFocusedState)
Expand All @@ -513,17 +517,15 @@ - (NSUndoManager *)undoManager

TEST(KeyboardInputTests, CaretSelectionRectAfterRestoringFirstResponder)
{
// This difference in caret width is due to the fact that we don't zoom in to the input field on iPad, but do on iPhone.
auto expectedCaretRect = CGRectMake(14, 11, UIDevice.currentDevice.userInterfaceIdiom == UIUserInterfaceIdiomPad ? 3 : 2, 15);
auto [webView, inputDelegate] = webViewAndInputDelegateWithAutofocusedInput();
EXPECT_WK_STREQ("INPUT", [webView stringByEvaluatingJavaScript:@"document.activeElement.tagName"]);
[webView waitForCaretViewFrameToBecome:expectedCaretRect];
[webView waitForCaretVisibility:CaretVisibility::Visible];

[webView resignFirstResponder];
[webView waitForCaretViewFrameToBecome:CGRectZero];
[webView waitForCaretVisibility:CaretVisibility::Hidden];

[webView becomeFirstResponder];
[webView waitForCaretViewFrameToBecome:expectedCaretRect];
[webView waitForCaretVisibility:CaretVisibility::Visible];
}

TEST(KeyboardInputTests, RangedSelectionRectAfterRestoringFirstResponder)
Expand Down
1 change: 1 addition & 0 deletions Tools/TestWebKitAPI/cocoa/TestWKWebView.h
Expand Up @@ -124,6 +124,7 @@
@end

@interface TestWKWebView (IOSOnly)
@property (nonatomic) UIEdgeInsets overrideSafeAreaInset;
@property (nonatomic, readonly) CGRect caretViewRectInContentCoordinates;
@property (nonatomic, readonly) NSArray<NSValue *> *selectionViewRectsInContentCoordinates;
- (_WKActivatedElementInfo *)activatedElementAtPosition:(CGPoint)position;
Expand Down
19 changes: 19 additions & 0 deletions Tools/TestWebKitAPI/cocoa/TestWKWebView.mm
Expand Up @@ -476,6 +476,7 @@ @implementation TestWKWebView {
#if PLATFORM(IOS_FAMILY)
std::unique_ptr<ClassMethodSwizzler> _sharedCalloutBarSwizzler;
InputSessionChangeCount _inputSessionChangeCount;
UIEdgeInsets _overrideSafeAreaInset;
#endif
#if PLATFORM(MAC)
BOOL _forceWindowToBecomeKey;
Expand Down Expand Up @@ -516,6 +517,9 @@ - (instancetype)initWithFrame:(CGRect)frame configuration:(WKWebViewConfiguratio
// FIXME: Remove this workaround once <https://webkit.org/b/175204> is fixed.
_sharedCalloutBarSwizzler = makeUnique<ClassMethodSwizzler>([UICalloutBar class], @selector(sharedCalloutBar), reinterpret_cast<IMP>(suppressUICalloutBar));
_inputSessionChangeCount = 0;
// We suppress safe area insets by default in order to ensure consistent results when running against device models
// that may or may not have safe area insets, have insets with different values (e.g. iOS devices with a notch).
_overrideSafeAreaInset = UIEdgeInsetsZero;
#endif

return self;
Expand Down Expand Up @@ -760,6 +764,21 @@ - (void)evaluateJavaScriptAndWaitForInputSessionToChange:(NSString *)script
}
}

- (UIEdgeInsets)overrideSafeAreaInset
{
return _overrideSafeAreaInset;
}

- (void)setOverrideSafeAreaInset:(UIEdgeInsets)inset
{
_overrideSafeAreaInset = inset;
}

- (UIEdgeInsets)safeAreaInsets
{
return _overrideSafeAreaInset;
}

- (CGRect)caretViewRectInContentCoordinates
{
UIView *caretView = nil;
Expand Down

0 comments on commit 90f6849

Please sign in to comment.