Make it possible to test iOS select elements, and add iPhone and iPad tests for them
authorsimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 16 Aug 2016 22:15:47 +0000 (22:15 +0000)
committersimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 16 Aug 2016 22:15:47 +0000 (22:15 +0000)
https://bugs.webkit.org/show_bug.cgi?id=160909

Reviewed by Enrica Casucci.

Source/WebKit2:

Hook up form-related UIScriptController functions, and plumb through the various
<select> pickers the ability to select a row.

* UIProcess/API/Cocoa/WKWebView.mm:
(-[WKWebView dismissFormAccessoryView]):
(-[WKWebView selectFormAccessoryPickerRow:]):
* UIProcess/API/Cocoa/WKWebViewPrivate.h:
* UIProcess/ios/WKContentViewInteraction.h:
* UIProcess/ios/WKContentViewInteraction.mm:
(-[WKContentView selectFormAccessoryPickerRow:]):
* UIProcess/ios/forms/WKFormSelectControl.h:
* UIProcess/ios/forms/WKFormSelectControl.mm:
(-[WKFormSelectControl selectRow:inComponent:extendingSelection:]):
* UIProcess/ios/forms/WKFormSelectPicker.mm:
(-[WKMultipleSelectPicker selectRow:inComponent:extendingSelection:]):
(-[WKSelectSinglePicker selectRow:inComponent:extendingSelection:]):
* UIProcess/ios/forms/WKFormSelectPopover.mm:
(-[WKSelectPopover selectRow:inComponent:extendingSelection:]):

Tools:

Add functions to UIScriptController to dismiss the form accessory view for iOS,
and to programmatically pick a row from a <select> picker.

* WebKitTestRunner/UIScriptContext/Bindings/UIScriptController.idl:
* WebKitTestRunner/UIScriptContext/UIScriptController.cpp:
(WTR::UIScriptController::dismissFormAccessoryView):
(WTR::UIScriptController::selectFormAccessoryPickerRow):
* WebKitTestRunner/UIScriptContext/UIScriptController.h:
* WebKitTestRunner/ios/UIScriptControllerIOS.mm:
(WTR::UIScriptController::dismissFormAccessoryView):
(WTR::UIScriptController::selectFormAccessoryPickerRow):

LayoutTests:

Add iPhone and iPad tests for the <select> pickers. The iPhone test has to
use a didShowKeyboardCallback to know when to select the appropriate row,
and to dismiss the picker. The iPad test can just select the row, which also
dismisses the popover.

* fast/forms/ios/choose-select-option-expected.txt: Added.
* fast/forms/ios/choose-select-option.html: Added.
* fast/forms/ios/ipad/choose-select-option-expected.txt: Added.
* fast/forms/ios/ipad/choose-select-option.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@204525 268f45cc-cd09-0410-ab3c-d52691b4dbfc

19 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/forms/ios/choose-select-option-expected.txt [new file with mode: 0644]
LayoutTests/fast/forms/ios/choose-select-option.html [new file with mode: 0644]
LayoutTests/fast/forms/ios/ipad/choose-select-option-expected.txt [new file with mode: 0644]
LayoutTests/fast/forms/ios/ipad/choose-select-option.html [new file with mode: 0644]
Source/WebKit2/ChangeLog
Source/WebKit2/UIProcess/API/Cocoa/WKWebView.mm
Source/WebKit2/UIProcess/API/Cocoa/WKWebViewPrivate.h
Source/WebKit2/UIProcess/ios/WKContentViewInteraction.h
Source/WebKit2/UIProcess/ios/WKContentViewInteraction.mm
Source/WebKit2/UIProcess/ios/forms/WKFormSelectControl.h
Source/WebKit2/UIProcess/ios/forms/WKFormSelectControl.mm
Source/WebKit2/UIProcess/ios/forms/WKFormSelectPicker.mm
Source/WebKit2/UIProcess/ios/forms/WKFormSelectPopover.mm
Tools/ChangeLog
Tools/WebKitTestRunner/UIScriptContext/Bindings/UIScriptController.idl
Tools/WebKitTestRunner/UIScriptContext/UIScriptController.cpp
Tools/WebKitTestRunner/UIScriptContext/UIScriptController.h
Tools/WebKitTestRunner/ios/UIScriptControllerIOS.mm

index 016f4a1..31c072e 100644 (file)
@@ -1,3 +1,20 @@
+2016-08-16  Simon Fraser  <simon.fraser@apple.com>
+
+        Make it possible to test iOS select elements, and add iPhone and iPad tests for them
+        https://bugs.webkit.org/show_bug.cgi?id=160909
+
+        Reviewed by Enrica Casucci.
+        
+        Add iPhone and iPad tests for the <select> pickers. The iPhone test has to 
+        use a didShowKeyboardCallback to know when to select the appropriate row,
+        and to dismiss the picker. The iPad test can just select the row, which also
+        dismisses the popover.
+
+        * fast/forms/ios/choose-select-option-expected.txt: Added.
+        * fast/forms/ios/choose-select-option.html: Added.
+        * fast/forms/ios/ipad/choose-select-option-expected.txt: Added.
+        * fast/forms/ios/ipad/choose-select-option.html: Added.
+
 2016-08-15  Simon Fraser  <simon.fraser@apple.com>
 
         [iOS] Add iPad viewport and form tests, and revert the iPad-testing part of r202132
diff --git a/LayoutTests/fast/forms/ios/choose-select-option-expected.txt b/LayoutTests/fast/forms/ios/choose-select-option-expected.txt
new file mode 100644 (file)
index 0000000..8704a35
--- /dev/null
@@ -0,0 +1,4 @@
+Tests that a basic select element works
+
+
+Successfully handled oninput, value is now "april"
diff --git a/LayoutTests/fast/forms/ios/choose-select-option.html b/LayoutTests/fast/forms/ios/choose-select-option.html
new file mode 100644 (file)
index 0000000..76a15fa
--- /dev/null
@@ -0,0 +1,84 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ useFlexibleViewport=true ] -->
+
+<html>
+<head>
+    <meta name="viewport" content="width=device-width">
+    <style>
+    </style>
+    
+    <script src="resources/zooming-test-utils.js"></script>
+    <script>
+    if (window.testRunner) {
+        testRunner.dumpAsText();
+        testRunner.waitUntilDone();
+    }
+
+    var uiScriptHasCompleted = false;
+    var oninputHasBeenHandled = false;
+
+    function getUIScript(x, y)
+    {
+        return `
+            (function() {
+                uiController.didShowKeyboardCallback = function() {
+                    uiController.selectFormAccessoryPickerRow(3);
+                    uiController.dismissFormAccessoryView();
+                    uiController.uiScriptComplete();
+                }
+                uiController.singleTapAtPoint(${x}, ${y}, function() {});
+            })();`
+    }
+
+    function checkDone()
+    {
+        if (oninputHasBeenHandled && uiScriptHasCompleted)
+            testRunner.notifyDone();
+    }
+
+    function handleValueChanged(value)
+    {
+        document.getElementById("console").textContent = "Successfully handled oninput, value is now \"" + value.toLowerCase() + "\"";
+        oninputHasBeenHandled = true;
+        checkDone();
+    }
+    
+    function doTest()
+    {
+        if (!window.testRunner || !testRunner.runUIScript)
+            return;
+
+        var targetElement = document.getElementsByTagName('select')[0];
+        var point = getPointInsideElement(targetElement, 10, 10);
+
+        testRunner.runUIScript(getUIScript(point.x, point.y), function() {
+            uiScriptHasCompleted = true;
+            checkDone();
+        });
+    }
+
+    window.addEventListener('load', doTest, false);
+    </script>
+</head>
+<body>
+
+<p>Tests that a basic select element works</p>
+
+<select oninput="handleValueChanged(this.value)">
+    <option>January</option>
+    <option>February</option>
+    <option>March</option>
+    <option>April</option>
+    <option>May</option>
+    <option>June</option>
+    <option>July</option>
+    <option>August</option>
+    <option>September</option>
+    <option>October</option>
+    <option>November</option>
+    <option>December</option>
+</select>
+
+<div id="console">Failed to handle oninput<div>
+
+</body>
+</html>
diff --git a/LayoutTests/fast/forms/ios/ipad/choose-select-option-expected.txt b/LayoutTests/fast/forms/ios/ipad/choose-select-option-expected.txt
new file mode 100644 (file)
index 0000000..8704a35
--- /dev/null
@@ -0,0 +1,4 @@
+Tests that a basic select element works
+
+
+Successfully handled oninput, value is now "april"
diff --git a/LayoutTests/fast/forms/ios/ipad/choose-select-option.html b/LayoutTests/fast/forms/ios/ipad/choose-select-option.html
new file mode 100644 (file)
index 0000000..f7352ca
--- /dev/null
@@ -0,0 +1,91 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ useFlexibleViewport=true ] -->
+
+<html>
+<head>
+    <meta name="viewport" content="width=device-width">
+    <style>
+    </style>
+    
+    <script src="../resources/zooming-test-utils.js"></script>
+    <script>
+    if (window.testRunner) {
+        testRunner.dumpAsText();
+        testRunner.waitUntilDone();
+    }
+
+    var uiScriptHasCompleted = false;
+    var oninputHasBeenHandled = false;
+
+    function getTapOnSelectUIScript(x, y)
+    {
+        return `
+            (function() {
+                uiController.singleTapAtPoint(${x}, ${y}, function() {
+                    uiController.uiScriptComplete('');
+                });
+            })();`
+    }
+
+    function getUIScriptForSelectRow()
+    {
+        return `
+            (function() {
+                uiController.selectFormAccessoryPickerRow(3);
+            })();`
+    }
+    
+    function checkDone()
+    {
+        if (oninputHasBeenHandled && uiScriptHasCompleted)
+            testRunner.notifyDone();
+    }
+
+    function handleValueChanged(value)
+    {
+        document.getElementById("console").textContent = "Successfully handled oninput, value is now \"" + value.toLowerCase() + "\"";
+        oninputHasBeenHandled = true;
+        checkDone();
+    }
+    
+    function doTest()
+    {
+        if (!window.testRunner || !testRunner.runUIScript)
+            return;
+
+        var targetElement = document.getElementsByTagName('select')[0];
+        var point = getPointInsideElement(targetElement, 10, 10);
+
+        testRunner.runUIScript(getTapOnSelectUIScript(point.x, point.y), function() {
+            testRunner.runUIScript(getUIScriptForSelectRow(), function() {
+                uiScriptHasCompleted = true;
+                checkDone();
+            });
+        });
+    }
+
+    window.addEventListener('load', doTest, false);
+    </script>
+</head>
+<body>
+
+<p>Tests that a basic select element works</p>
+
+<select oninput="handleValueChanged(this.value)">
+    <option>January</option>
+    <option>February</option>
+    <option>March</option>
+    <option>April</option>
+    <option>May</option>
+    <option>June</option>
+    <option>July</option>
+    <option>August</option>
+    <option>September</option>
+    <option>October</option>
+    <option>November</option>
+    <option>December</option>
+</select>
+
+<div id="console">Failed to handle oninput<div>
+
+</body>
+</html>
index 4060608..5d32b04 100644 (file)
@@ -1,3 +1,29 @@
+2016-08-16  Simon Fraser  <simon.fraser@apple.com>
+
+        Make it possible to test iOS select elements, and add iPhone and iPad tests for them
+        https://bugs.webkit.org/show_bug.cgi?id=160909
+
+        Reviewed by Enrica Casucci.
+        
+        Hook up form-related UIScriptController functions, and plumb through the various
+        <select> pickers the ability to select a row.
+
+        * UIProcess/API/Cocoa/WKWebView.mm:
+        (-[WKWebView dismissFormAccessoryView]):
+        (-[WKWebView selectFormAccessoryPickerRow:]):
+        * UIProcess/API/Cocoa/WKWebViewPrivate.h:
+        * UIProcess/ios/WKContentViewInteraction.h:
+        * UIProcess/ios/WKContentViewInteraction.mm:
+        (-[WKContentView selectFormAccessoryPickerRow:]):
+        * UIProcess/ios/forms/WKFormSelectControl.h:
+        * UIProcess/ios/forms/WKFormSelectControl.mm:
+        (-[WKFormSelectControl selectRow:inComponent:extendingSelection:]):
+        * UIProcess/ios/forms/WKFormSelectPicker.mm:
+        (-[WKMultipleSelectPicker selectRow:inComponent:extendingSelection:]):
+        (-[WKSelectSinglePicker selectRow:inComponent:extendingSelection:]):
+        * UIProcess/ios/forms/WKFormSelectPopover.mm:
+        (-[WKSelectPopover selectRow:inComponent:extendingSelection:]):
+
 2016-08-16  Brady Eidson  <beidson@apple.com>
 
         Cleanup WK2 platform gamepad handling.
index de9bd03..70dbd89 100644 (file)
@@ -4517,6 +4517,16 @@ static WebCore::UserInterfaceLayoutDirection toUserInterfaceLayoutDirection(UISe
     [_contentView accessoryTab:NO];
 }
 
+- (void)dismissFormAccessoryView
+{
+    [_contentView accessoryDone];
+}
+
+- (void)selectFormAccessoryPickerRow:(int)rowIndex
+{
+    [_contentView selectFormAccessoryPickerRow:rowIndex];
+}
+
 #endif // PLATFORM(IOS)
 
 #if PLATFORM(MAC)
index 2360cce..5589a42 100644 (file)
@@ -254,12 +254,16 @@ typedef NS_ENUM(NSInteger, _WKImmediateActionType) {
 @interface WKWebView (WKTesting)
 
 #if TARGET_OS_IPHONE
+
 @property (nonatomic, readonly) CGRect _contentVisibleRect WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_IOS_TBA));
 - (CGPoint)_convertPointFromContentsToView:(CGPoint)point WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_IOS_TBA));
 - (CGPoint)_convertPointFromViewToContents:(CGPoint)point WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_IOS_TBA));
 
 - (void)keyboardAccessoryBarNext WK_API_AVAILABLE(ios(WK_IOS_TBA));
 - (void)keyboardAccessoryBarPrevious WK_API_AVAILABLE(ios(WK_IOS_TBA));
+- (void)dismissFormAccessoryView WK_API_AVAILABLE(ios(WK_IOS_TBA));
+- (void)selectFormAccessoryPickerRow:(int)rowIndex WK_API_AVAILABLE(ios(WK_IOS_TBA));
+
 #endif
 
 #if !TARGET_OS_IPHONE
index be0121c..c740395 100644 (file)
@@ -223,6 +223,12 @@ struct WKAutoCorrectionData {
 - (NSArray *)_dataDetectionResults;
 @end
 
+@interface WKContentView (WKTesting)
+
+- (void)selectFormAccessoryPickerRow:(NSInteger)rowIndex;
+
+@end
+
 #if HAVE(LINK_PREVIEW)
 @interface WKContentView (WKInteractionPreview) <UIPreviewItemDelegate>
 
index 0cc4f1a..c3b0f01 100644 (file)
@@ -3797,6 +3797,16 @@ static bool isAssistableInputType(InputType type)
 
 @end
 
+@implementation WKContentView (WKTesting)
+
+- (void)selectFormAccessoryPickerRow:(NSInteger)rowIndex
+{
+    if ([_inputPeripheral isKindOfClass:[WKFormSelectControl self]])
+        [(WKFormSelectControl *)_inputPeripheral selectRow:rowIndex inComponent:0 extendingSelection:NO];
+}
+
+@end
+
 #if HAVE(LINK_PREVIEW)
 
 @implementation WKContentView (WKInteractionPreview)
@@ -4108,7 +4118,7 @@ static NSString *previewIdentifierForElementAction(_WKElementAction *action)
 
 @end
 
-#endif
+#endif // HAVE(LINK_PREVIEW)
 
 // UITextRange, UITextPosition and UITextSelectionRect implementations for WK2
 
index f81a0e7..18142e9 100644 (file)
@@ -39,6 +39,10 @@ CGFloat adjustedFontSize(CGFloat textWidth, UIFont *, CGFloat initialFontSize, c
 - (instancetype)initWithView:(WKContentView *)view;
 @end
 
+@interface WKFormSelectControl(WKTesting)
+- (void)selectRow:(NSInteger)rowIndex inComponent:(NSInteger)componentIndex extendingSelection:(BOOL)extendingSelection;
+@end
+
 @interface WKSelectPopover : WKFormRotatingAccessoryPopover<WKFormControl>
 - (instancetype)initWithView:(WKContentView *)view hasGroups:(BOOL)hasGroups;
 - (void)_userActionDismissedPopover:(id)sender;
@@ -52,5 +56,10 @@ CGFloat adjustedFontSize(CGFloat textWidth, UIFont *, CGFloat initialFontSize, c
 - (instancetype)initWithView:(WKContentView *)view;
 @end
 
+@protocol WKSelectTesting
+@optional
+- (void)selectRow:(NSInteger)rowIndex inComponent:(NSInteger)componentIndex extendingSelection:(BOOL)extendingSelection;
+@end
+
 #endif // PLATFORM(IOS)
 
index e4e8652..5bc3689 100644 (file)
@@ -58,7 +58,7 @@ CGFloat adjustedFontSize(CGFloat textWidth, UIFont *font, CGFloat initialFontSiz
 }
 
 @implementation WKFormSelectControl {
-    RetainPtr<id<WKFormControl>> _control;
+    RetainPtr<NSObject<WKFormControl>> _control;
 }
 
 - (instancetype)initWithView:(WKContentView *)view
@@ -101,4 +101,14 @@ CGFloat adjustedFontSize(CGFloat textWidth, UIFont *font, CGFloat initialFontSiz
 
 @end
 
+@implementation WKFormSelectControl(WKTesting)
+
+- (void)selectRow:(NSInteger)rowIndex inComponent:(NSInteger)componentIndex extendingSelection:(BOOL)extendingSelection
+{
+    if ([_control respondsToSelector:@selector(selectRow:inComponent:extendingSelection:)])
+        [id<WKSelectTesting>(_control.get()) selectRow:rowIndex inComponent:componentIndex extendingSelection:extendingSelection];
+}
+
+@end
+
 #endif  // PLATFORM(IOS)
index 95b29b3..adbd6bf 100644 (file)
@@ -303,6 +303,15 @@ static const float GroupOptionTextColorAlpha = 0.5;
     }
 }
 
+// WKSelectTesting
+- (void)selectRow:(NSInteger)rowIndex inComponent:(NSInteger)componentIndex extendingSelection:(BOOL)extendingSelection
+{
+    // FIXME: handle extendingSelection.
+    [self selectRow:rowIndex inComponent:0 animated:NO];
+    // Progammatic selection changes don't call the delegate, so do that manually.
+    [self.delegate pickerView:self didSelectRow:rowIndex inComponent:0];
+}
+
 @end
 
 @implementation WKSelectSinglePicker {
@@ -430,6 +439,15 @@ static const float GroupOptionTextColorAlpha = 0.5;
     _selectedIndex = row;
 }
 
+// WKSelectTesting
+- (void)selectRow:(NSInteger)rowIndex inComponent:(NSInteger)componentIndex extendingSelection:(BOOL)extendingSelection
+{
+    // FIXME: handle extendingSelection.
+    [self selectRow:rowIndex inComponent:0 animated:NO];
+    // Progammatic selection changes don't call the delegate, so do that manually.
+    [self.delegate pickerView:self didSelectRow:rowIndex inComponent:0];
+}
+
 @end
 
 #endif  // PLATFORM(IOS)
index 9afb8ec..ffdf697 100644 (file)
@@ -448,4 +448,16 @@ static NSString *stringWithWritingDirection(NSString *string, UITextWritingDirec
 
 @end
 
+@implementation WKSelectPopover(WKTesting)
+
+- (void)selectRow:(NSInteger)rowIndex inComponent:(NSInteger)componentIndex extendingSelection:(BOOL)extendingSelection
+{
+    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:rowIndex inSection:componentIndex];
+    [[_tableViewController tableView] selectRowAtIndexPath:indexPath animated:NO scrollPosition:UITableViewScrollPositionMiddle];
+    // Inform the delegate, since -selectRowAtIndexPath:... doesn't do that.
+    [_tableViewController tableView:[_tableViewController tableView] didSelectRowAtIndexPath:indexPath];
+}
+
+@end
+
 #endif  // PLATFORM(IOS)
index f51e318..840d683 100644 (file)
@@ -1,3 +1,22 @@
+2016-08-16  Simon Fraser  <simon.fraser@apple.com>
+
+        Make it possible to test iOS select elements, and add iPhone and iPad tests for them
+        https://bugs.webkit.org/show_bug.cgi?id=160909
+
+        Reviewed by Enrica Casucci.
+        
+        Add functions to UIScriptController to dismiss the form accessory view for iOS,
+        and to programmatically pick a row from a <select> picker.
+
+        * WebKitTestRunner/UIScriptContext/Bindings/UIScriptController.idl:
+        * WebKitTestRunner/UIScriptContext/UIScriptController.cpp:
+        (WTR::UIScriptController::dismissFormAccessoryView):
+        (WTR::UIScriptController::selectFormAccessoryPickerRow):
+        * WebKitTestRunner/UIScriptContext/UIScriptController.h:
+        * WebKitTestRunner/ios/UIScriptControllerIOS.mm:
+        (WTR::UIScriptController::dismissFormAccessoryView):
+        (WTR::UIScriptController::selectFormAccessoryPickerRow):
+
 2016-08-15  Simon Fraser  <simon.fraser@apple.com>
 
         [iOS] Add iPad viewport and form tests, and revert the iPad-testing part of r202132
index 3bc5a6b..1eb810d 100644 (file)
@@ -42,9 +42,16 @@ interface UIScriptController {
     void keyDownUsingHardwareKeyboard(DOMString character, object callback);
     void keyUpUsingHardwareKeyboard(DOMString character, object callback);
 
+    // Equivalent of pressing the Done button in the form accessory bar.
+    void dismissFormAccessoryView();
+
+    // <select> picker
+    void selectFormAccessoryPickerRow(long rowIndex);
+
     void keyboardAccessoryBarNext();
     void keyboardAccessoryBarPrevious();
 
+    // These callbacks also work for the form accessory views.
     attribute object didShowKeyboardCallback;
     attribute object didHideKeyboardCallback;
 
index f327bf9..1bf44cb 100644 (file)
@@ -150,6 +150,14 @@ void UIScriptController::keyDownUsingHardwareKeyboard(JSStringRef, JSValueRef)
 {
 }
 
+void UIScriptController::dismissFormAccessoryView()
+{
+}
+
+void UIScriptController::selectFormAccessoryPickerRow(long)
+{
+}
+
 void UIScriptController::keyboardAccessoryBarNext()
 {
 }
index eb05089..07717ae 100644 (file)
@@ -59,6 +59,9 @@ public:
 
     void keyboardAccessoryBarNext();
     void keyboardAccessoryBarPrevious();
+    
+    void dismissFormAccessoryView();
+    void selectFormAccessoryPickerRow(long);
 
     void setWillBeginZoomingCallback(JSValueRef);
     JSValueRef willBeginZoomingCallback() const;
index 76d8e6f..b479b93 100644 (file)
@@ -175,6 +175,18 @@ void UIScriptController::keyUpUsingHardwareKeyboard(JSStringRef character, JSVal
     }];
 }
 
+void UIScriptController::dismissFormAccessoryView()
+{
+    TestRunnerWKWebView *webView = TestController::singleton().mainWebView()->platformView();
+    [webView dismissFormAccessoryView];
+}
+
+void UIScriptController::selectFormAccessoryPickerRow(long rowIndex)
+{
+    TestRunnerWKWebView *webView = TestController::singleton().mainWebView()->platformView();
+    [webView selectFormAccessoryPickerRow:rowIndex];
+}
+
 void UIScriptController::keyboardAccessoryBarNext()
 {
     TestRunnerWKWebView *webView = TestController::singleton().mainWebView()->platformView();