Title: [253029] trunk
Revision
253029
Author
carlo...@webkit.org
Date
2019-12-03 01:32:14 -0800 (Tue, 03 Dec 2019)

Log Message

WebDriver: most of the clear tests are failing
https://bugs.webkit.org/show_bug.cgi?id=180404

Reviewed by Brian Burg.

Source/WebDriver:

Implement the element clear command following the spec.
https://w3c.github.io/webdriver/#element-clear

* Session.cpp:
(WebDriver::Session::elementIsEditable): Helper function to check if the element is editable.
(WebDriver::Session::elementClear): Check if the element is editable and interactable before executing the clear atom.
* Session.h:

Source/WebKit:

Update the FormElementClear atom to follow the spec.

* UIProcess/Automation/atoms/FormElementClear.js:
(isEditable):
(isResettableElementEmpty):

WebDriverTests:

Remove expectations for tests that are now passing.

* TestExpectations.json:

Modified Paths

Diff

Modified: trunk/Source/WebDriver/ChangeLog (253028 => 253029)


--- trunk/Source/WebDriver/ChangeLog	2019-12-03 09:30:19 UTC (rev 253028)
+++ trunk/Source/WebDriver/ChangeLog	2019-12-03 09:32:14 UTC (rev 253029)
@@ -1,3 +1,18 @@
+2019-12-03  Carlos Garcia Campos  <cgar...@igalia.com>
+
+        WebDriver: most of the clear tests are failing
+        https://bugs.webkit.org/show_bug.cgi?id=180404
+
+        Reviewed by Brian Burg.
+
+        Implement the element clear command following the spec.
+        https://w3c.github.io/webdriver/#element-clear
+
+        * Session.cpp:
+        (WebDriver::Session::elementIsEditable): Helper function to check if the element is editable.
+        (WebDriver::Session::elementClear): Check if the element is editable and interactable before executing the clear atom.
+        * Session.h:
+
 2019-11-22  Carlos Garcia Campos  <cgar...@igalia.com>
 
         Unreviewed. Fix GTK/WPE debug build after r252770

Modified: trunk/Source/WebDriver/Session.cpp (253028 => 253029)


--- trunk/Source/WebDriver/Session.cpp	2019-12-03 09:30:19 UTC (rev 253028)
+++ trunk/Source/WebDriver/Session.cpp	2019-12-03 09:32:14 UTC (rev 253029)
@@ -1595,6 +1595,53 @@
     });
 }
 
+void Session::elementIsEditable(const String& elementID, Function<void (CommandResult&&)>&& completionHandler)
+{
+    RefPtr<JSON::Array> arguments = JSON::Array::create();
+    arguments->pushString(createElement(elementID)->toJSONString());
+
+    static const char isEditableScript[] =
+        "function(element) {"
+        "    if (element.disabled || element.readOnly)"
+        "        return false;"
+        "    var tagName = element.tagName.toLowerCase();"
+        "    if (tagName === 'textarea' || element.isContentEditable)"
+        "        return true;"
+        "    if (tagName != 'input')"
+        "        return false;"
+        "    switch (element.type) {"
+        "    case 'color': case 'date': case 'datetime-local': case 'email': case 'file': case 'month': case 'number': "
+        "    case 'password': case 'range': case 'search': case 'tel': case 'text': case 'time': case 'url': case 'week':"
+        "        return true;"
+        "    }"
+        "    return false;"
+        "}";
+
+    RefPtr<JSON::Object> parameters = JSON::Object::create();
+    parameters->setString("browsingContextHandle"_s, m_toplevelBrowsingContext.value());
+    if (m_currentBrowsingContext)
+        parameters->setString("frameHandle"_s, m_currentBrowsingContext.value());
+    parameters->setString("function"_s, isEditableScript);
+    parameters->setArray("arguments"_s, WTFMove(arguments));
+    m_host->sendCommandToBackend("evaluateJavaScriptFunction"_s, WTFMove(parameters), [this, protectedThis = makeRef(*this), completionHandler = WTFMove(completionHandler)](SessionHost::CommandResponse&& response) {
+        if (response.isError || !response.responseObject) {
+            completionHandler(CommandResult::fail(WTFMove(response.responseObject)));
+            return;
+        }
+        String valueString;
+        if (!response.responseObject->getString("result"_s, valueString)) {
+            completionHandler(CommandResult::fail(CommandResult::ErrorCode::UnknownError));
+            return;
+        }
+        RefPtr<JSON::Value> resultValue;
+        if (!JSON::Value::parseJSON(valueString, resultValue)) {
+            completionHandler(CommandResult::fail(CommandResult::ErrorCode::UnknownError));
+            return;
+        }
+        completionHandler(CommandResult::success(WTFMove(resultValue)));
+    });
+}
+
 void Session::elementClear(const String& elementID, Function<void (CommandResult&&)>&& completionHandler)
 {
     if (!m_toplevelBrowsingContext) {
@@ -1608,21 +1655,45 @@
             return;
         }
 
-        RefPtr<JSON::Array> arguments = JSON::Array::create();
-        arguments->pushString(createElement(elementID)->toJSONString());
+        elementIsEditable(elementID, [this, protectedThis = protectedThis.copyRef(), elementID, completionHandler = WTFMove(completionHandler)](CommandResult&& result) mutable {
+            if (result.isError()) {
+                completionHandler(WTFMove(result));
+                return;
+            }
 
-        RefPtr<JSON::Object> parameters = JSON::Object::create();
-        parameters->setString("browsingContextHandle"_s, m_toplevelBrowsingContext.value());
-        if (m_currentBrowsingContext)
-            parameters->setString("frameHandle"_s, m_currentBrowsingContext.value());
-        parameters->setString("function"_s, String(FormElementClearJavaScript, sizeof(FormElementClearJavaScript)));
-        parameters->setArray("arguments"_s, WTFMove(arguments));
-        m_host->sendCommandToBackend("evaluateJavaScriptFunction"_s, WTFMove(parameters), [protectedThis = protectedThis.copyRef(), completionHandler = WTFMove(completionHandler)](SessionHost::CommandResponse&& response) {
-            if (response.isError) {
-                completionHandler(CommandResult::fail(WTFMove(response.responseObject)));
+            bool isEditable;
+            if (!result.result()->asBoolean(isEditable) || !isEditable) {
+                completionHandler(CommandResult::fail(CommandResult::ErrorCode::InvalidElementState));
                 return;
             }
-            completionHandler(CommandResult::success());
+
+            OptionSet<ElementLayoutOption> options = { ElementLayoutOption::ScrollIntoViewIfNeeded };
+            computeElementLayout(elementID, options, [this, protectedThis = protectedThis.copyRef(), elementID, completionHandler = WTFMove(completionHandler)](Optional<Rect>&& rect, Optional<Point>&& inViewCenter, bool, RefPtr<JSON::Object>&& error) mutable {
+                if (!rect || error) {
+                    completionHandler(CommandResult::fail(WTFMove(error)));
+                    return;
+                }
+                if (!inViewCenter) {
+                    completionHandler(CommandResult::fail(CommandResult::ErrorCode::ElementNotInteractable));
+                    return;
+                }
+                RefPtr<JSON::Array> arguments = JSON::Array::create();
+                arguments->pushString(createElement(elementID)->toJSONString());
+
+                RefPtr<JSON::Object> parameters = JSON::Object::create();
+                parameters->setString("browsingContextHandle"_s, m_toplevelBrowsingContext.value());
+                if (m_currentBrowsingContext)
+                    parameters->setString("frameHandle"_s, m_currentBrowsingContext.value());
+                parameters->setString("function"_s, String(FormElementClearJavaScript, sizeof(FormElementClearJavaScript)));
+                parameters->setArray("arguments"_s, WTFMove(arguments));
+                m_host->sendCommandToBackend("evaluateJavaScriptFunction"_s, WTFMove(parameters), [protectedThis = protectedThis.copyRef(), completionHandler = WTFMove(completionHandler)](SessionHost::CommandResponse&& response) {
+                    if (response.isError) {
+                        completionHandler(CommandResult::fail(WTFMove(response.responseObject)));
+                        return;
+                    }
+                    completionHandler(CommandResult::success());
+                });
+            });
         });
     });
 }

Modified: trunk/Source/WebDriver/Session.h (253028 => 253029)


--- trunk/Source/WebDriver/Session.h	2019-12-03 09:30:19 UTC (rev 253028)
+++ trunk/Source/WebDriver/Session.h	2019-12-03 09:32:14 UTC (rev 253029)
@@ -146,6 +146,7 @@
     RefPtr<JSON::Object> extractElement(JSON::Value&);
     String extractElementID(JSON::Value&);
     RefPtr<JSON::Value> handleScriptResult(RefPtr<JSON::Value>&&);
+    void elementIsEditable(const String& elementID, Function<void (CommandResult&&)>&&);
 
     struct Point {
         int x { 0 };

Modified: trunk/Source/WebKit/ChangeLog (253028 => 253029)


--- trunk/Source/WebKit/ChangeLog	2019-12-03 09:30:19 UTC (rev 253028)
+++ trunk/Source/WebKit/ChangeLog	2019-12-03 09:32:14 UTC (rev 253029)
@@ -1,5 +1,18 @@
 2019-12-03  Carlos Garcia Campos  <cgar...@igalia.com>
 
+        WebDriver: most of the clear tests are failing
+        https://bugs.webkit.org/show_bug.cgi?id=180404
+
+        Reviewed by Brian Burg.
+
+        Update the FormElementClear atom to follow the spec.
+
+        * UIProcess/Automation/atoms/FormElementClear.js:
+        (isEditable):
+        (isResettableElementEmpty):
+
+2019-12-03  Carlos Garcia Campos  <cgar...@igalia.com>
+
         [PSON] Tooltips from previous page shown on new page
         https://bugs.webkit.org/show_bug.cgi?id=204735
 

Modified: trunk/Source/WebKit/UIProcess/Automation/atoms/FormElementClear.js (253028 => 253029)


--- trunk/Source/WebKit/UIProcess/Automation/atoms/FormElementClear.js	2019-12-03 09:30:19 UTC (rev 253028)
+++ trunk/Source/WebKit/UIProcess/Automation/atoms/FormElementClear.js	2019-12-03 09:32:14 UTC (rev 253029)
@@ -26,34 +26,69 @@
 function(element) {
     "use strict";
 
-    if (element.disabled || element.readOnly)
-        throw {name: "InvalidElementState", message: "Element must be user-editable in order to clear."};
+    function isEditable(element) {
+        if (element.disabled || element.readOnly)
+            return false;
 
-    if (element instanceof HTMLTextAreaElement || element instanceof HTMLSelectElement) {
-        element.value = "";
-        return;
-    }
+        if (element instanceof HTMLTextAreaElement)
+            return true;
 
-    if (element instanceof HTMLInputElement) {
-        switch (element.type) {
-        case "button":
-        case "submit":
-        case "reset":
-            return;
+        if (element.isContentEditable)
+            return true;
 
-        case "radio":
-        case "checkbox":
-            element.checked = false;
-            return;
+        if (element.tagName.toUpperCase() != "INPUT")
+            return false;
 
-        default:
-            element.value = "";
-            return;
+        switch (element.type) {
+        case "color":
+        case "date":
+        case "datetime-local":
+        case "email":
+        case "file":
+        case "month":
+        case "number":
+        case "password":
+        case "range":
+        case "search":
+        case "tel":
+        case "text":
+        case "time":
+        case "url":
+        case "week":
+            return true;
         }
+
+        return false;
     }
 
+    if (!isEditable(element))
+        throw {name: "InvalidElementState", message: "Element must be user-editable in order to clear."};
+
+    // Clear a content editable element.
     if (element.isContentEditable) {
+        if (element.innerHTML === "")
+            return;
+
+        element.focus();
         element.innerHTML = "";
+        element.blur();
         return;
     }
+
+    // Clear a resettable element.
+    function isResettableElementEmpty(element) {
+        if (element instanceof HTMLInputElement && element.type == "file")
+            return element.files.length == 0;
+        return element.value === "";
+    }
+
+    if (element.validity.valid && isResettableElementEmpty(element))
+        return;
+
+    element.focus();
+    element.value = "";
+    var event = document.createEvent("Event");
+    event.initEvent("change", true, true);
+    element.dispatchEvent(event);
+    element.blur();
 }

Modified: trunk/WebDriverTests/ChangeLog (253028 => 253029)


--- trunk/WebDriverTests/ChangeLog	2019-12-03 09:30:19 UTC (rev 253028)
+++ trunk/WebDriverTests/ChangeLog	2019-12-03 09:32:14 UTC (rev 253029)
@@ -1,3 +1,14 @@
+2019-12-03  Carlos Garcia Campos  <cgar...@igalia.com>
+
+        WebDriver: most of the clear tests are failing
+        https://bugs.webkit.org/show_bug.cgi?id=180404
+
+        Reviewed by Brian Burg.
+
+        Remove expectations for tests that are now passing.
+
+        * TestExpectations.json:
+
 2019-11-13  Carlos Garcia Campos  <cgar...@igalia.com>
 
         Unreviewed gardening. Skip imported/w3c/webdriver/tests/send_alert_text/send.py::test_alert_unsupported_operation.

Modified: trunk/WebDriverTests/TestExpectations.json (253028 => 253029)


--- trunk/WebDriverTests/TestExpectations.json	2019-12-03 09:30:19 UTC (rev 253028)
+++ trunk/WebDriverTests/TestExpectations.json	2019-12-03 09:32:14 UTC (rev 253029)
@@ -595,136 +595,6 @@
     "imported/w3c/webdriver/tests/element_send_keys/content_editable.py": {
         "expected": {"all": {"status": ["FAIL"], "bug": "webkit.org/b/180403"}}
     },
-    "imported/w3c/webdriver/tests/element_clear/clear.py": {
-        "subtests": {
-            "test_pointer_interactable": {
-                "expected": {"all": {"status": ["FAIL"], "bug": "webkit.org/b/180404"}}
-            },
-            "test_input[number-42-]": {
-                "expected": {"all": {"status": ["FAIL"], "bug": "webkit.org/b/180404"}}
-            },
-            "test_input[range-42-50]": {
-                "expected": {"all": {"status": ["FAIL"], "bug": "webkit.org/b/180404"}}
-            },
-            "test_input[email-...@example.com-]": {
-                "expected": {"all": {"status": ["FAIL"], "bug": "webkit.org/b/180404"}}
-            },
-            "test_input[password-password-]": {
-                "expected": {"all": {"status": ["FAIL"], "bug": "webkit.org/b/180404"}}
-            },
-            "test_input[search-search-]": {
-                "expected": {"all": {"status": ["FAIL"], "bug": "webkit.org/b/180404"}}
-            },
-            "test_input[tel-999-]": {
-                "expected": {"all": {"status": ["FAIL"], "bug": "webkit.org/b/180404"}}
-            },
-            "test_input[text-text-]": {
-                "expected": {"all": {"status": ["FAIL"], "bug": "webkit.org/b/180404"}}
-            },
-            "test_input[url-https://example.com/-]": {
-                "expected": {"all": {"status": ["FAIL"], "bug": "webkit.org/b/180404"}}
-            },
-            "test_input[color-#ff0000-#000000]": {
-                "expected": {"all": {"status": ["FAIL"], "bug": "webkit.org/b/180404"}}
-            },
-            "test_input[date-2017-12-26-]": {
-                "expected": {"all": {"status": ["FAIL"], "bug": "webkit.org/b/180404"}}
-            },
-            "test_input[datetime-2017-12-26T19:48-]": {
-                "expected": {"all": {"status": ["FAIL"], "bug": "webkit.org/b/180404"}}
-            },
-            "test_input[datetime-local-2017-12-26T19:48-]": {
-                "expected": {"all": {"status": ["FAIL"], "bug": "webkit.org/b/180404"}}
-            },
-            "test_input[time-19:48-]": {
-                "expected": {"all": {"status": ["FAIL"], "bug": "webkit.org/b/180404"}}
-            },
-            "test_input[month-2017-11-]": {
-                "expected": {"all": {"status": ["FAIL"], "bug": "webkit.org/b/180404"}}
-            },
-            "test_input[week-2017-W52-]": {
-                "expected": {"all": {"status": ["FAIL"], "bug": "webkit.org/b/180404"}}
-            },
-            "test_textarea": {
-                "expected": {"all": {"status": ["FAIL"], "bug": "webkit.org/b/180404"}}
-            },
-            "test_input_file": {
-                "expected": {"all": {"status": ["SKIP"], "bug": "webkit.org/b/180404"}}
-            },
-            "test_input_file_multiple": {
-                "expected": {"all": {"status": ["SKIP"], "bug": "webkit.org/b/180404"}}
-            },
-            "test_select": {
-                "expected": {"all": {"status": ["FAIL"], "bug": "webkit.org/b/180404"}}
-            },
-            "test_button": {
-                "expected": {"all": {"status": ["FAIL"], "bug": "webkit.org/b/180404"}}
-            },
-            "test_button_with_subtree": {
-                "expected": {"all": {"status": ["FAIL"], "bug": "webkit.org/b/180404"}}
-            },
-            "test_contenteditable": {
-                "expected": {"all": {"status": ["FAIL"], "bug": "webkit.org/b/180404"}}
-            },
-            "test_designmode": {
-                "expected": {"all": {"status": ["FAIL"], "bug": "webkit.org/b/180404"}}
-            },
-            "test_resettable_element_does_not_satisfy_validation_constraints[number-foo]": {
-                "expected": {"all": {"status": ["SKIP"], "bug": "webkit.org/b/180404"}}
-            },
-            "test_resettable_element_does_not_satisfy_validation_constraints[range-foo]": {
-                "expected": {"all": {"status": ["SKIP"], "bug": "webkit.org/b/180404"}}
-            },
-            "test_resettable_element_does_not_satisfy_validation_constraints[email-foo]": {
-                "expected": {"all": {"status": ["SKIP"], "bug": "webkit.org/b/180404"}}
-            },
-            "test_resettable_element_does_not_satisfy_validation_constraints[url-foo]": {
-                "expected": {"all": {"status": ["SKIP"], "bug": "webkit.org/b/180404"}}
-            },
-            "test_resettable_element_does_not_satisfy_validation_constraints[color-foo]": {
-                "expected": {"all": {"status": ["SKIP"], "bug": "webkit.org/b/180404"}}
-            },
-            "test_resettable_element_does_not_satisfy_validation_constraints[date-foo]": {
-                "expected": {"all": {"status": ["SKIP"], "bug": "webkit.org/b/180404"}}
-            },
-            "test_resettable_element_does_not_satisfy_validation_constraints[datetime-foo]": {
-                "expected": {"all": {"status": ["SKIP"], "bug": "webkit.org/b/180404"}}
-            },
-            "test_resettable_element_does_not_satisfy_validation_constraints[datetime-local-foo]": {
-                "expected": {"all": {"status": ["SKIP"], "bug": "webkit.org/b/180404"}}
-            },
-            "test_resettable_element_does_not_satisfy_validation_constraints[time-foo]": {
-                "expected": {"all": {"status": ["SKIP"], "bug": "webkit.org/b/180404"}}
-            },
-            "test_resettable_element_does_not_satisfy_validation_constraints[month-foo]": {
-                "expected": {"all": {"status": ["SKIP"], "bug": "webkit.org/b/180404"}}
-            },
-            "test_resettable_element_does_not_satisfy_validation_constraints[week-foo]": {
-                "expected": {"all": {"status": ["SKIP"], "bug": "webkit.org/b/180404"}}
-            },
-            "test_non_editable_inputs[checkbox]": {
-                "expected": {"all": {"status": ["FAIL"], "bug": "webkit.org/b/180404"}}
-            },
-            "test_non_editable_inputs[radio]": {
-                "expected": {"all": {"status": ["FAIL"], "bug": "webkit.org/b/180404"}}
-            },
-            "test_non_editable_inputs[hidden]": {
-                "expected": {"all": {"status": ["FAIL"], "bug": "webkit.org/b/180404"}}
-            },
-            "test_non_editable_inputs[submit]": {
-                "expected": {"all": {"status": ["FAIL"], "bug": "webkit.org/b/180404"}}
-            },
-            "test_non_editable_inputs[button]": {
-                "expected": {"all": {"status": ["FAIL"], "bug": "webkit.org/b/180404"}}
-            },
-            "test_non_editable_inputs[image]": {
-                "expected": {"all": {"status": ["FAIL"], "bug": "webkit.org/b/180404"}}
-            },
-            "test_scroll_into_view": {
-                "expected": {"all": {"status": ["FAIL"], "bug": "webkit.org/b/180404"}}
-            }
-        }
-    },
     "imported/w3c/webdriver/tests/get_current_url/get.py": {
         "subtests": {
             "test_set_malformed_url": {
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to