[Cocoa] Web Automation: provide a way to ask clients the type of a JavaScript dialog
authorbburg@apple.com <bburg@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 1 Mar 2018 02:12:31 +0000 (02:12 +0000)
committerbburg@apple.com <bburg@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 1 Mar 2018 02:12:31 +0000 (02:12 +0000)
https://bugs.webkit.org/show_bug.cgi?id=182660
<rdar://problem/37408183>

Reviewed by Tim Horton and Carlos Garcia Campos.

Add another delegate method to ask what type of dialog is being shown.
This is used to implement §18.4 Step 5, where sending text to a dialog
without a prompt will return several different kinds of errors.

No new tests, covered by web platform tests once Safari side has landed.

* UIProcess/API/Cocoa/_WKAutomationSessionDelegate.h: Update FIXME radar numbers.
* UIProcess/Cocoa/AutomationSessionClient.h:
* UIProcess/Cocoa/AutomationSessionClient.mm:
(WebKit::AutomationSessionClient::AutomationSessionClient):
(WebKit::toImpl):
(WebKit::AutomationSessionClient::typeOfCurrentJavaScriptDialogOnPage):
If there is no current dialog to be checked, the client can return the 'None'
type. This gets converted into a std::nullopt and causes a command error later.

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

Source/WebKit/ChangeLog
Source/WebKit/UIProcess/API/Cocoa/_WKAutomationSessionDelegate.h
Source/WebKit/UIProcess/Cocoa/AutomationSessionClient.h
Source/WebKit/UIProcess/Cocoa/AutomationSessionClient.mm

index 61fc8b7..bbf7c9a 100644 (file)
@@ -1,3 +1,26 @@
+2018-02-28  Brian Burg  <bburg@apple.com>
+
+        [Cocoa] Web Automation: provide a way to ask clients the type of a JavaScript dialog
+        https://bugs.webkit.org/show_bug.cgi?id=182660
+        <rdar://problem/37408183>
+
+        Reviewed by Tim Horton and Carlos Garcia Campos.
+
+        Add another delegate method to ask what type of dialog is being shown.
+        This is used to implement §18.4 Step 5, where sending text to a dialog
+        without a prompt will return several different kinds of errors.
+
+        No new tests, covered by web platform tests once Safari side has landed.
+
+        * UIProcess/API/Cocoa/_WKAutomationSessionDelegate.h: Update FIXME radar numbers.
+        * UIProcess/Cocoa/AutomationSessionClient.h:
+        * UIProcess/Cocoa/AutomationSessionClient.mm:
+        (WebKit::AutomationSessionClient::AutomationSessionClient):
+        (WebKit::toImpl):
+        (WebKit::AutomationSessionClient::typeOfCurrentJavaScriptDialogOnPage):
+        If there is no current dialog to be checked, the client can return the 'None'
+        type. This gets converted into a std::nullopt and causes a command error later.
+
 2018-02-28  John Wilander  <wilander@apple.com>
 
         Remove assertion from ResourceLoadStatisticsClassifier::calculateResourcePrevalence() which causes crashes when domains are explicitly set as prevalent without the associated statistics
index 4bcf7de..a555cd6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2016, 2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 @class WKWebView;
 @class _WKAutomationSession;
 
+typedef NS_ENUM(NSInteger, _WKAutomationSessionJavaScriptDialogType) {
+    _WKAutomationSessionJavaScriptDialogTypeNone = 1,
+    _WKAutomationSessionJavaScriptDialogTypeAlert,
+    _WKAutomationSessionJavaScriptDialogTypeConfirm,
+    _WKAutomationSessionJavaScriptDialogTypePrompt,
+} WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_IOS_TBA));
+
 @protocol _WKAutomationSessionDelegate <NSObject>
 @optional
 
 - (void)_automationSession:(_WKAutomationSession *)automationSession acceptCurrentJavaScriptDialogForWebView:(WKWebView *)webView WK_API_AVAILABLE(macosx(10.13), ios(11.0));
 - (NSString *)_automationSession:(_WKAutomationSession *)automationSession messageOfCurrentJavaScriptDialogForWebView:(WKWebView *)webView WK_API_AVAILABLE(macosx(10.13), ios(11.0));
 - (void)_automationSession:(_WKAutomationSession *)automationSession setUserInput:(NSString *)value forCurrentJavaScriptDialogForWebView:(WKWebView *)webView WK_API_AVAILABLE(macosx(10.13), ios(11.0));
+- (_WKAutomationSessionJavaScriptDialogType)_automationSession:(_WKAutomationSession *)automationSession typeOfCurrentJavaScriptDialogForWebView:(WKWebView *)webView WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_IOS_TBA));
 
-// FIXME: Objective-C delegate methods shouldn't use C API types like WKPageRef. We need to
+// FIXME 37408718: Objective-C delegate methods shouldn't use C API types like WKPageRef. We need to
 // migrate clients to use WKWebView, or expose the same behavior via a C SPI for those clients.
-- (WKPageRef)_automationSessionDidRequestNewWindow:(_WKAutomationSession *)automationSession;
-- (BOOL)_automationSession:(_WKAutomationSession *)automationSession isShowingJavaScriptDialogOnPage:(WKPageRef)page;
-- (void)_automationSession:(_WKAutomationSession *)automationSession dismissCurrentJavaScriptDialogOnPage:(WKPageRef)page;
-- (void)_automationSession:(_WKAutomationSession *)automationSession acceptCurrentJavaScriptDialogOnPage:(WKPageRef)page;
-- (NSString *)_automationSession:(_WKAutomationSession *)automationSession messageOfCurrentJavaScriptDialogOnPage:(WKPageRef)page;
-- (void)_automationSession:(_WKAutomationSession *)automationSession setUserInput:(NSString *)value forCurrentJavaScriptDialogOnPage:(WKPageRef)page;
+- (WKPageRef)_automationSessionDidRequestNewWindow:(_WKAutomationSession *)automationSession WK_API_AVAILABLE(macosx(10.13), ios(11.0));
+- (BOOL)_automationSession:(_WKAutomationSession *)automationSession isShowingJavaScriptDialogOnPage:(WKPageRef)page WK_API_AVAILABLE(macosx(10.13), ios(11.0));
+- (void)_automationSession:(_WKAutomationSession *)automationSession dismissCurrentJavaScriptDialogOnPage:(WKPageRef)page WK_API_AVAILABLE(macosx(10.13), ios(11.0));
+- (void)_automationSession:(_WKAutomationSession *)automationSession acceptCurrentJavaScriptDialogOnPage:(WKPageRef)page WK_API_AVAILABLE(macosx(10.13), ios(11.0));
+- (NSString *)_automationSession:(_WKAutomationSession *)automationSession messageOfCurrentJavaScriptDialogOnPage:(WKPageRef)page WK_API_AVAILABLE(macosx(10.13), ios(11.0));
+- (void)_automationSession:(_WKAutomationSession *)automationSession setUserInput:(NSString *)value forCurrentJavaScriptDialogOnPage:(WKPageRef)page WK_API_AVAILABLE(macosx(10.13), ios(11.0));
+- (_WKAutomationSessionJavaScriptDialogType)_automationSession:(_WKAutomationSession *)automationSession typeOfCurrentJavaScriptDialogOnPage:(WKPageRef)page WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_IOS_TBA));
 @end
 
 #endif // WK_API_ENABLED
index 2d56f54..35e8ec2 100644 (file)
@@ -64,14 +64,16 @@ private:
         bool acceptCurrentJavaScriptDialogForWebView : 1;
         bool messageOfCurrentJavaScriptDialogForWebView : 1;
         bool setUserInputForCurrentJavaScriptPromptForWebView : 1;
+        bool typeOfCurrentJavaScriptDialogForWebView : 1;
 
-        // FIXME 28524687: these delegate methods should be removed.
+        // FIXME 37408718: these delegate methods should be removed.
         bool didRequestNewWindow : 1;
         bool isShowingJavaScriptDialogOnPage : 1;
         bool dismissCurrentJavaScriptDialogOnPage : 1;
         bool acceptCurrentJavaScriptDialogOnPage : 1;
         bool messageOfCurrentJavaScriptDialogOnPage : 1;
         bool setUserInputForCurrentJavaScriptPromptOnPage : 1;
+        bool typeOfCurrentJavaScriptDialogOnPage : 1;
     } m_delegateMethods;
 };
 
index 9bf2da0..a5cb09c 100644 (file)
@@ -48,14 +48,16 @@ AutomationSessionClient::AutomationSessionClient(id <_WKAutomationSessionDelegat
     m_delegateMethods.acceptCurrentJavaScriptDialogForWebView = [delegate respondsToSelector:@selector(_automationSession:acceptCurrentJavaScriptDialogForWebView:)];
     m_delegateMethods.messageOfCurrentJavaScriptDialogForWebView = [delegate respondsToSelector:@selector(_automationSession:messageOfCurrentJavaScriptDialogForWebView:)];
     m_delegateMethods.setUserInputForCurrentJavaScriptPromptForWebView = [delegate respondsToSelector:@selector(_automationSession:setUserInput:forCurrentJavaScriptDialogForWebView:)];
+    m_delegateMethods.typeOfCurrentJavaScriptDialogForWebView = [delegate respondsToSelector:@selector(_automationSession:typeOfCurrentJavaScriptDialogForWebView:)];
 
-    // FIXME 28524687: these delegate methods should be removed.
+    // FIXME 37408718: these delegate methods should be removed.
     m_delegateMethods.didRequestNewWindow = [delegate respondsToSelector:@selector(_automationSessionDidRequestNewWindow:)];
     m_delegateMethods.isShowingJavaScriptDialogOnPage = [delegate respondsToSelector:@selector(_automationSession:isShowingJavaScriptDialogOnPage:)];
     m_delegateMethods.dismissCurrentJavaScriptDialogOnPage = [delegate respondsToSelector:@selector(_automationSession:dismissCurrentJavaScriptDialogOnPage:)];
     m_delegateMethods.acceptCurrentJavaScriptDialogOnPage = [delegate respondsToSelector:@selector(_automationSession:acceptCurrentJavaScriptDialogOnPage:)];
     m_delegateMethods.messageOfCurrentJavaScriptDialogOnPage = [delegate respondsToSelector:@selector(_automationSession:messageOfCurrentJavaScriptDialogOnPage:)];
     m_delegateMethods.setUserInputForCurrentJavaScriptPromptOnPage = [delegate respondsToSelector:@selector(_automationSession:setUserInput:forCurrentJavaScriptDialogOnPage:)];
+    m_delegateMethods.typeOfCurrentJavaScriptDialogOnPage = [delegate respondsToSelector:@selector(_automationSession:typeOfCurrentJavaScriptDialogOnPage:)];
 }
 
 void AutomationSessionClient::didDisconnectFromRemote(WebAutomationSession& session)
@@ -64,7 +66,7 @@ void AutomationSessionClient::didDisconnectFromRemote(WebAutomationSession& sess
         [m_delegate.get() _automationSessionDidDisconnectFromRemote:wrapper(session)];
 }
 
-// FIXME 28524687: support for WKPageRef-based delegate methods should be removed.
+// FIXME 37408718: support for WKPageRef-based delegate methods should be removed.
 // Until these are removed, prefer to use the WKWebView delegate methods if implemented.
 WebPageProxy* AutomationSessionClient::didRequestNewWindow(WebAutomationSession& session)
 {
@@ -123,10 +125,27 @@ void AutomationSessionClient::setUserInputForCurrentJavaScriptPromptOnPage(WebAu
         [m_delegate.get() _automationSession:wrapper(session) setUserInput:value forCurrentJavaScriptDialogOnPage:toAPI(&page)];
 }
 
-std::optional<API::AutomationSessionClient::JavaScriptDialogType> AutomationSessionClient::typeOfCurrentJavaScriptDialogOnPage(WebAutomationSession&, WebPageProxy&)
+static std::optional<API::AutomationSessionClient::JavaScriptDialogType> toImpl(_WKAutomationSessionJavaScriptDialogType type)
 {
-    // FIXME: Implement it. This is only used in WebAutomationSession::setUserInputForCurrentJavaScriptPrompt() so for now we return
-    // always Prompt type for compatibility.
+    switch (type) {
+    case _WKAutomationSessionJavaScriptDialogTypeNone:
+        return std::nullopt;
+    case _WKAutomationSessionJavaScriptDialogTypePrompt:
+        return API::AutomationSessionClient::JavaScriptDialogType::Prompt;
+    case _WKAutomationSessionJavaScriptDialogTypeConfirm:
+        return API::AutomationSessionClient::JavaScriptDialogType::Confirm;
+    case _WKAutomationSessionJavaScriptDialogTypeAlert:
+        return API::AutomationSessionClient::JavaScriptDialogType::Alert;
+    }
+}
+
+std::optional<API::AutomationSessionClient::JavaScriptDialogType> AutomationSessionClient::typeOfCurrentJavaScriptDialogOnPage(WebAutomationSession& session, WebPageProxy& page)
+{
+    if (m_delegateMethods.typeOfCurrentJavaScriptDialogForWebView)
+        return toImpl([m_delegate.get() _automationSession:wrapper(session) typeOfCurrentJavaScriptDialogForWebView:fromWebPageProxy(page)]);
+    if (m_delegateMethods.typeOfCurrentJavaScriptDialogOnPage)
+        return toImpl([m_delegate.get() _automationSession:wrapper(session) typeOfCurrentJavaScriptDialogOnPage:toAPI(&page)]);
+
     return API::AutomationSessionClient::JavaScriptDialogType::Prompt;
 }