Web Automation: setUserInputForCurrentJavaScriptPrompt should fail if current dialog...
authorcarlosgc@webkit.org <carlosgc@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 8 Aug 2017 08:29:19 +0000 (08:29 +0000)
committercarlosgc@webkit.org <carlosgc@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 8 Aug 2017 08:29:19 +0000 (08:29 +0000)
https://bugs.webkit.org/show_bug.cgi?id=175261

Reviewed by Brian Burg.

Source/WebDriver:

* CommandResult.cpp:
(WebDriver::CommandResult::CommandResult): Handle ElementNotInteractable protocol error.

Source/WebKit:

According to the spec, send alert text command should fail if the current dialog is not a prompt. This patch
adds JavaScriptDialogType enum to API::AutomationSessionClient and a new virtual method to ask the client about
the type of the current dialog. WebAutomationSession::setUserInputForCurrentJavaScriptPrompt() uses the new
client method to check the type of the current dialog and fail in case it's not a prompt. Cocoa needs an
implementation, for now it always returns Prompt as the type to keep compatibility.

18.4 Send Alert Text.
https://w3c.github.io/webdriver/webdriver-spec.html#send-alert-text

This fixes selenium test testSettingTheValueOfAnAlertThrows.

* UIProcess/API/APIAutomationSessionClient.h:
(API::AutomationSessionClient::typeOfCurrentJavaScriptDialogOnPage):
* UIProcess/API/glib/WebKitAutomationSession.cpp:
* UIProcess/API/glib/WebKitWebView.cpp:
(webkitWebViewGetCurrentScriptDialogType):
* UIProcess/API/glib/WebKitWebViewPrivate.h:
* UIProcess/Automation/Automation.json:
* UIProcess/Automation/WebAutomationSession.cpp:
(WebKit::WebAutomationSession::setUserInputForCurrentJavaScriptPrompt):
* UIProcess/Cocoa/AutomationSessionClient.h:
* UIProcess/Cocoa/AutomationSessionClient.mm:
(WebKit::AutomationSessionClient::typeOfCurrentJavaScriptDialogOnPage):

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

Source/WebDriver/ChangeLog
Source/WebDriver/CommandResult.cpp
Source/WebKit/ChangeLog
Source/WebKit/UIProcess/API/APIAutomationSessionClient.h
Source/WebKit/UIProcess/API/glib/WebKitAutomationSession.cpp
Source/WebKit/UIProcess/API/glib/WebKitWebView.cpp
Source/WebKit/UIProcess/API/glib/WebKitWebViewPrivate.h
Source/WebKit/UIProcess/Automation/Automation.json
Source/WebKit/UIProcess/Automation/WebAutomationSession.cpp
Source/WebKit/UIProcess/Cocoa/AutomationSessionClient.h
Source/WebKit/UIProcess/Cocoa/AutomationSessionClient.mm

index a97fb66..e8fc347 100644 (file)
@@ -1,5 +1,15 @@
 2017-08-07  Carlos Garcia Campos  <cgarcia@igalia.com>
 
+        Web Automation: setUserInputForCurrentJavaScriptPrompt should fail if current dialog is not a prompt
+        https://bugs.webkit.org/show_bug.cgi?id=175261
+
+        Reviewed by Brian Burg.
+
+        * CommandResult.cpp:
+        (WebDriver::CommandResult::CommandResult): Handle ElementNotInteractable protocol error.
+
+2017-08-07  Carlos Garcia Campos  <cgarcia@igalia.com>
+
         WebDriver: implement unhandled prompt behavior
         https://bugs.webkit.org/show_bug.cgi?id=175184
 
index a1e7e9b..be8c817 100644 (file)
@@ -88,6 +88,8 @@ CommandResult::CommandResult(RefPtr<InspectorValue>&& result, std::optional<Erro
             m_errorCode = ErrorCode::NoSuchFrame;
         else if (errorName == "NotImplemented")
             m_errorCode = ErrorCode::UnsupportedOperation;
+        else if (errorName == "ElementNotInteractable")
+            m_errorCode = ErrorCode::ElementNotInteractable;
         else if (errorName == "JavaScriptError")
             m_errorCode = ErrorCode::JavascriptError;
         else if (errorName == "JavaScriptTimeout")
index e5feada..fa6cc89 100644 (file)
@@ -1,3 +1,34 @@
+2017-08-07  Carlos Garcia Campos  <cgarcia@igalia.com>
+
+        Web Automation: setUserInputForCurrentJavaScriptPrompt should fail if current dialog is not a prompt
+        https://bugs.webkit.org/show_bug.cgi?id=175261
+
+        Reviewed by Brian Burg.
+
+        According to the spec, send alert text command should fail if the current dialog is not a prompt. This patch
+        adds JavaScriptDialogType enum to API::AutomationSessionClient and a new virtual method to ask the client about
+        the type of the current dialog. WebAutomationSession::setUserInputForCurrentJavaScriptPrompt() uses the new
+        client method to check the type of the current dialog and fail in case it's not a prompt. Cocoa needs an
+        implementation, for now it always returns Prompt as the type to keep compatibility.
+
+        18.4 Send Alert Text.
+        https://w3c.github.io/webdriver/webdriver-spec.html#send-alert-text
+
+        This fixes selenium test testSettingTheValueOfAnAlertThrows.
+
+        * UIProcess/API/APIAutomationSessionClient.h:
+        (API::AutomationSessionClient::typeOfCurrentJavaScriptDialogOnPage):
+        * UIProcess/API/glib/WebKitAutomationSession.cpp:
+        * UIProcess/API/glib/WebKitWebView.cpp:
+        (webkitWebViewGetCurrentScriptDialogType):
+        * UIProcess/API/glib/WebKitWebViewPrivate.h:
+        * UIProcess/Automation/Automation.json:
+        * UIProcess/Automation/WebAutomationSession.cpp:
+        (WebKit::WebAutomationSession::setUserInputForCurrentJavaScriptPrompt):
+        * UIProcess/Cocoa/AutomationSessionClient.h:
+        * UIProcess/Cocoa/AutomationSessionClient.mm:
+        (WebKit::AutomationSessionClient::typeOfCurrentJavaScriptDialogOnPage):
+
 2017-08-08  Wenson Hsieh  <wenson_hsieh@apple.com>
 
         [iOS WK2] WKWebView schedules nonstop layout after pressing cmb+b,i,u inside a contenteditable div
index 2dc5542..0fc854a 100644 (file)
@@ -37,6 +37,13 @@ namespace API {
 
 class AutomationSessionClient {
 public:
+    enum class JavaScriptDialogType {
+        Alert,
+        Confirm,
+        Prompt,
+        BeforeUnloadConfirm
+    };
+
     virtual ~AutomationSessionClient() { }
 
     virtual String sessionIdentifier() const { return String(); }
@@ -47,6 +54,7 @@ public:
     virtual void acceptCurrentJavaScriptDialogOnPage(WebKit::WebAutomationSession&, WebKit::WebPageProxy&) { }
     virtual String messageOfCurrentJavaScriptDialogOnPage(WebKit::WebAutomationSession&, WebKit::WebPageProxy&) { return String(); }
     virtual void setUserInputForCurrentJavaScriptPromptOnPage(WebKit::WebAutomationSession&, WebKit::WebPageProxy&, const String&) { }
+    virtual std::optional<JavaScriptDialogType> typeOfCurrentJavaScriptDialogOnPage(WebKit::WebAutomationSession&, WebKit::WebPageProxy&) { return std::nullopt; }
 };
 
 } // namespace API
index ed50baf..87033bf 100644 (file)
@@ -132,6 +132,29 @@ private:
         webkitWebViewSetCurrentScriptDialogUserInput(webView, userInput);
     }
 
+    std::optional<API::AutomationSessionClient::JavaScriptDialogType> typeOfCurrentJavaScriptDialogOnPage(WebAutomationSession&, WebPageProxy& page) override
+    {
+        auto* webView = webkitWebContextGetWebViewForPage(m_session->priv->webContext, &page);
+        if (!webView)
+            return std::nullopt;
+        auto dialogType = webkitWebViewGetCurrentScriptDialogType(webView);
+        if (!dialogType)
+            return std::nullopt;
+        switch (dialogType.value()) {
+        case WEBKIT_SCRIPT_DIALOG_ALERT:
+            return API::AutomationSessionClient::JavaScriptDialogType::Alert;
+        case WEBKIT_SCRIPT_DIALOG_CONFIRM:
+            return API::AutomationSessionClient::JavaScriptDialogType::Confirm;
+        case WEBKIT_SCRIPT_DIALOG_PROMPT:
+            return API::AutomationSessionClient::JavaScriptDialogType::Prompt;
+        case WEBKIT_SCRIPT_DIALOG_BEFORE_UNLOAD_CONFIRM:
+            return API::AutomationSessionClient::JavaScriptDialogType::BeforeUnloadConfirm;
+        }
+
+        ASSERT_NOT_REACHED();
+        return std::nullopt;
+    }
+
     WebKitAutomationSession* m_session;
 };
 
index 0bf7b94..a773d3f 100644 (file)
@@ -2090,6 +2090,14 @@ void webkitWebViewDismissCurrentScriptDialog(WebKitWebView* webView)
         webkitScriptDialogDismiss(webView->priv->currentScriptDialog);
 }
 
+std::optional<WebKitScriptDialogType> webkitWebViewGetCurrentScriptDialogType(WebKitWebView* webView)
+{
+    if (!webView->priv->currentScriptDialog)
+        return std::nullopt;
+
+    return static_cast<WebKitScriptDialogType>(webView->priv->currentScriptDialog->type);
+}
+
 void webkitWebViewMakePolicyDecision(WebKitWebView* webView, WebKitPolicyDecisionType type, WebKitPolicyDecision* decision)
 {
     gboolean returnValue;
index f3c296f..8913966 100644 (file)
@@ -59,6 +59,7 @@ String webkitWebViewGetCurrentScriptDialogMessage(WebKitWebView*);
 void webkitWebViewSetCurrentScriptDialogUserInput(WebKitWebView*, const String&);
 void webkitWebViewAcceptCurrentScriptDialog(WebKitWebView*);
 void webkitWebViewDismissCurrentScriptDialog(WebKitWebView*);
+std::optional<WebKitScriptDialogType> webkitWebViewGetCurrentScriptDialogType(WebKitWebView*);
 void webkitWebViewMakePermissionRequest(WebKitWebView*, WebKitPermissionRequest*);
 void webkitWebViewMakePolicyDecision(WebKitWebView*, WebKitPolicyDecisionType, WebKitPolicyDecision*);
 void webkitWebViewMouseTargetChanged(WebKitWebView*, const WebKit::WebHitTestResultData&, WebKit::WebEvent::Modifiers);
index 2e026ec..21366c2 100644 (file)
@@ -58,7 +58,8 @@
                 "NotImplemented",
                 "MissingParameter",
                 "InvalidParameter",
-                "InvalidSelector"
+                "InvalidSelector",
+                "ElementNotInteractable"
             ]
         },
         {
index 41a50f7..c8ad5a1 100644 (file)
@@ -919,6 +919,24 @@ void WebAutomationSession::setUserInputForCurrentJavaScriptPrompt(Inspector::Err
     if (!m_client->isShowingJavaScriptDialogOnPage(*this, *page))
         FAIL_WITH_PREDEFINED_ERROR(NoJavaScriptDialog);
 
+    // ยง18.4 Send Alert Text.
+    // https://w3c.github.io/webdriver/webdriver-spec.html#send-alert-text
+    // 3. Run the substeps of the first matching current user prompt:
+    auto scriptDialogType = m_client->typeOfCurrentJavaScriptDialogOnPage(*this, *page);
+    ASSERT(scriptDialogType);
+    switch (scriptDialogType.value()) {
+    case API::AutomationSessionClient::JavaScriptDialogType::Alert:
+    case API::AutomationSessionClient::JavaScriptDialogType::Confirm:
+        // Return error with error code element not interactable.
+        FAIL_WITH_PREDEFINED_ERROR(ElementNotInteractable);
+    case API::AutomationSessionClient::JavaScriptDialogType::Prompt:
+        // Do nothing.
+        break;
+    case API::AutomationSessionClient::JavaScriptDialogType::BeforeUnloadConfirm:
+        // Return error with error code unsupported operation.
+        FAIL_WITH_PREDEFINED_ERROR(NotImplemented);
+    }
+
     m_client->setUserInputForCurrentJavaScriptPromptOnPage(*this, *page, promptValue);
 }
 
index 9cdb761..2d56f54 100644 (file)
@@ -51,6 +51,7 @@ private:
     void acceptCurrentJavaScriptDialogOnPage(WebAutomationSession&, WebPageProxy&) override;
     String messageOfCurrentJavaScriptDialogOnPage(WebAutomationSession&, WebPageProxy&) override;
     void setUserInputForCurrentJavaScriptPromptOnPage(WebAutomationSession&, WebPageProxy&, const String&) override;
+    std::optional<API::AutomationSessionClient::JavaScriptDialogType> typeOfCurrentJavaScriptDialogOnPage(WebAutomationSession&, WebPageProxy&) override;
 
     WeakObjCPtr<id <_WKAutomationSessionDelegate>> m_delegate;
 
index 0eadd25..9bf2da0 100644 (file)
@@ -123,6 +123,13 @@ void AutomationSessionClient::setUserInputForCurrentJavaScriptPromptOnPage(WebAu
         [m_delegate.get() _automationSession:wrapper(session) setUserInput:value forCurrentJavaScriptDialogOnPage:toAPI(&page)];
 }
 
+std::optional<API::AutomationSessionClient::JavaScriptDialogType> AutomationSessionClient::typeOfCurrentJavaScriptDialogOnPage(WebAutomationSession&, WebPageProxy&)
+{
+    // FIXME: Implement it. This is only used in WebAutomationSession::setUserInputForCurrentJavaScriptPrompt() so for now we return
+    // always Prompt type for compatibility.
+    return API::AutomationSessionClient::JavaScriptDialogType::Prompt;
+}
+
 } // namespace WebKit
 
 #endif // WK_API_ENABLED