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/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": {