Title: [222503] trunk/Source/WebKit
Revision
222503
Author
[email protected]
Date
2017-09-26 10:12:21 -0700 (Tue, 26 Sep 2017)

Log Message

Web Automation: add commands to get and set user permissions for pages in an automation session
https://bugs.webkit.org/show_bug.cgi?id=177405
<rdar://problem/34493846>

Reviewed by Joseph Pecoraro.

To test some Web APIs via WebDriver, it needs to be possible to simulate a user accepting or
denying requests for elevated permissions, such as getUserMedia() or geolocation.

This patch adds a generic way for a test to configure the automation session's
simulated user action that will happen every time a specific permission is requested.
A test can set a "session permission", trigger the permission request via Web API,
and then verify that the page behaves correctly when the user accepted or denied the request.

A proposal will follow shortly to expose this functionality via a new REST API endpoint.

* UIProcess/Automation/Automation.json: Add get/set commands.

* UIProcess/Automation/WebAutomationSession.cpp:
(WebKit::WebAutomationSession::getSessionPermissions):
(WebKit::WebAutomationSession::setSessionPermissions):
For now, store the permission value in a member of the session. The getUserMedia
permission only needs a bool, but there is no reason we couldn't use more complicated
values for permissions (i.e., strings, numbers, arrays, objects) someday.

(WebKit::WebAutomationSession::shouldAllowGetUserMediaForPage const):
Expose the specific decision to be taken based on whether the request is allowed or denied.

* UIProcess/Automation/WebAutomationSession.h:
* UIProcess/UserMediaPermissionRequestManagerProxy.cpp:
(WebKit::UserMediaPermissionRequestManagerProxy::requestUserMediaPermissionForFrame):
If the page is under automation, then simulate the user action according to the
current values of permissions set for the session.

Modified Paths

Diff

Modified: trunk/Source/WebKit/ChangeLog (222502 => 222503)


--- trunk/Source/WebKit/ChangeLog	2017-09-26 16:29:08 UTC (rev 222502)
+++ trunk/Source/WebKit/ChangeLog	2017-09-26 17:12:21 UTC (rev 222503)
@@ -1,3 +1,39 @@
+2017-09-26  Brian Burg  <[email protected]>
+
+        Web Automation: add commands to get and set user permissions for pages in an automation session
+        https://bugs.webkit.org/show_bug.cgi?id=177405
+        <rdar://problem/34493846>
+
+        Reviewed by Joseph Pecoraro.
+
+        To test some Web APIs via WebDriver, it needs to be possible to simulate a user accepting or
+        denying requests for elevated permissions, such as getUserMedia() or geolocation.
+
+        This patch adds a generic way for a test to configure the automation session's
+        simulated user action that will happen every time a specific permission is requested.
+        A test can set a "session permission", trigger the permission request via Web API,
+        and then verify that the page behaves correctly when the user accepted or denied the request.
+
+        A proposal will follow shortly to expose this functionality via a new REST API endpoint.
+
+        * UIProcess/Automation/Automation.json: Add get/set commands.
+
+        * UIProcess/Automation/WebAutomationSession.cpp:
+        (WebKit::WebAutomationSession::getSessionPermissions):
+        (WebKit::WebAutomationSession::setSessionPermissions):
+        For now, store the permission value in a member of the session. The getUserMedia
+        permission only needs a bool, but there is no reason we couldn't use more complicated
+        values for permissions (i.e., strings, numbers, arrays, objects) someday.
+
+        (WebKit::WebAutomationSession::shouldAllowGetUserMediaForPage const):
+        Expose the specific decision to be taken based on whether the request is allowed or denied.
+
+        * UIProcess/Automation/WebAutomationSession.h:
+        * UIProcess/UserMediaPermissionRequestManagerProxy.cpp:
+        (WebKit::UserMediaPermissionRequestManagerProxy::requestUserMediaPermissionForFrame):
+        If the page is under automation, then simulate the user action according to the
+        current values of permissions set for the session.
+
 2017-09-25  Alex Christensen  <[email protected]>
 
         Make PolicyAction an encodable enum class

Modified: trunk/Source/WebKit/UIProcess/Automation/Automation.json (222502 => 222503)


--- trunk/Source/WebKit/UIProcess/Automation/Automation.json	2017-09-26 16:29:08 UTC (rev 222502)
+++ trunk/Source/WebKit/UIProcess/Automation/Automation.json	2017-09-26 17:12:21 UTC (rev 222503)
@@ -217,6 +217,22 @@
                 { "name": "secure", "type": "boolean", "description": "True if cookie is secure." },
                 { "name": "session", "type": "boolean", "description": "True in case of session cookie." }
             ]
+        },
+        {
+            "id": "SessionPermission",
+            "type": "string",
+            "description": "Enumerates different permissions that must be obtained in order to use privileged APIs.",
+            "enum": [
+                "GetUserMedia"
+            ]
+        },
+        {
+            "id": "SessionPermissionData",
+            "type": "object",
+            "properties": [
+                { "name": "permission", "$ref": "SessionPermission" },
+                { "name": "value", "type": "boolean" }
+            ]
         }
     ],
     "commands": [
@@ -534,6 +550,20 @@
             "parameters": [
                 { "name": "browsingContextHandle", "$ref": "BrowsingContextHandle", "description": "The handle for the browsing context." }
             ]
+        },
+        {
+            "name": "getSessionPermissions",
+            "description": "Returns the state of all session permissions, which control whether privileged Web APIs can be used. Permissions are applied to all browsing contexts associated with the automation session.",
+            "returns": [
+                { "name": "permissions", "type": "array", "items": { "$ref": "SessionPermissionData" }, "description": "Array of available session permissions and their values." }
+            ]
+        },
+        {
+            "name": "setSessionPermissions",
+            "description": "Attempts to set the state of session permissions, which control whether privileged Web APIs can be used. Permissions that are not understood are ignored. Permissions are applied to all browsing contexts associated with the automation session.",
+            "parameters": [
+                { "name": "permissions", "type": "array", "items": { "$ref": "SessionPermissionData" }, "description": "Array of session permissions to set, if they are available." }
+            ]
         }
     ],
     "events": [

Modified: trunk/Source/WebKit/UIProcess/Automation/WebAutomationSession.cpp (222502 => 222503)


--- trunk/Source/WebKit/UIProcess/Automation/WebAutomationSession.cpp	2017-09-26 16:29:08 UTC (rev 222502)
+++ trunk/Source/WebKit/UIProcess/Automation/WebAutomationSession.cpp	2017-09-26 17:12:21 UTC (rev 222503)
@@ -1222,6 +1222,50 @@
     cookieManager->deleteCookiesForHostname(page->websiteDataStore().sessionID(), activeURL.host());
 }
 
+void WebAutomationSession::getSessionPermissions(ErrorString&, RefPtr<Inspector::Protocol::Array<Inspector::Protocol::Automation::SessionPermissionData>>& out_permissions)
+{
+    auto permissionsObjectArray = Inspector::Protocol::Array<Inspector::Protocol::Automation::SessionPermissionData>::create();
+    auto getUserMediaPermissionObject = Inspector::Protocol::Automation::SessionPermissionData::create()
+        .setPermission(Inspector::Protocol::Automation::SessionPermission::GetUserMedia)
+        .setValue(m_permissionForGetUserMedia)
+        .release();
+
+    permissionsObjectArray->addItem(WTFMove(getUserMediaPermissionObject));
+    out_permissions = WTFMove(permissionsObjectArray);
+}
+
+void WebAutomationSession::setSessionPermissions(ErrorString& errorString, const Inspector::InspectorArray& permissions)
+{
+    for (auto it = permissions.begin(); it != permissions.end(); ++it) {
+        RefPtr<InspectorObject> permission;
+        if (!it->get()->asObject(permission))
+            FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(InvalidParameter, "The parameter 'permissions' is invalid.");
+
+        String permissionName;
+        if (!permission->getString(WTF::ASCIILiteral("permission"), permissionName))
+            FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(InvalidParameter, "The parameter 'permission' is missing or invalid.");
+
+        auto parsedPermissionName = Inspector::Protocol::AutomationHelpers::parseEnumValueFromString<Inspector::Protocol::Automation::SessionPermission>(permissionName);
+        if (!parsedPermissionName)
+            FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(InvalidParameter, "The parameter 'permission' has an unknown value.");
+
+        bool permissionValue;
+        if (!permission->getBoolean(WTF::ASCIILiteral("value"), permissionValue))
+            FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(InvalidParameter, "The parameter 'value' is missing or invalid.");
+
+        switch (parsedPermissionName.value()) {
+        case Inspector::Protocol::Automation::SessionPermission::GetUserMedia:
+            m_permissionForGetUserMedia = permissionValue;
+            break;
+        }
+    }
+}
+
+bool WebAutomationSession::shouldAllowGetUserMediaForPage(const WebPageProxy&) const
+{
+    return m_permissionForGetUserMedia;
+}
+
 #if USE(APPKIT) || PLATFORM(GTK)
 static WebEvent::Modifiers protocolModifierToWebEventModifier(Inspector::Protocol::Automation::KeyModifier modifier)
 {

Modified: trunk/Source/WebKit/UIProcess/Automation/WebAutomationSession.h (222502 => 222503)


--- trunk/Source/WebKit/UIProcess/Automation/WebAutomationSession.h	2017-09-26 16:29:08 UTC (rev 222502)
+++ trunk/Source/WebKit/UIProcess/Automation/WebAutomationSession.h	2017-09-26 17:12:21 UTC (rev 222503)
@@ -101,6 +101,8 @@
     void handleRunOpenPanel(const WebPageProxy&, const WebFrameProxy&, const API::OpenPanelParameters&, WebOpenPanelResultListenerProxy&);
     void willShowJavaScriptDialog(WebPageProxy&);
 
+    bool shouldAllowGetUserMediaForPage(const WebPageProxy&) const;
+
 #if ENABLE(REMOTE_INSPECTOR)
     // Inspector::RemoteAutomationTarget API
     String name() const override { return m_sessionIdentifier; }
@@ -145,6 +147,8 @@
     void deleteSingleCookie(Inspector::ErrorString&, const String& browsingContextHandle, const String& cookieName, Ref<DeleteSingleCookieCallback>&&) override;
     void addSingleCookie(Inspector::ErrorString&, const String& browsingContextHandle, const Inspector::InspectorObject& cookie, Ref<AddSingleCookieCallback>&&) override;
     void deleteAllCookies(Inspector::ErrorString&, const String& browsingContextHandle) override;
+    void getSessionPermissions(Inspector::ErrorString&, RefPtr<Inspector::Protocol::Array<Inspector::Protocol::Automation::SessionPermissionData>>& out_permissions) override;
+    void setSessionPermissions(Inspector::ErrorString&, const Inspector::InspectorArray& in_permissions) override;
 
     // Platform: macOS
 #if PLATFORM(MAC)
@@ -253,6 +257,8 @@
     RunLoop::Timer<WebAutomationSession> m_loadTimer;
     Vector<String> m_filesToSelectForFileUpload;
 
+    bool m_permissionForGetUserMedia { true };
+
 #if ENABLE(REMOTE_INSPECTOR)
     Inspector::FrontendChannel* m_remoteChannel { nullptr };
 #endif

Modified: trunk/Source/WebKit/UIProcess/UserMediaPermissionRequestManagerProxy.cpp (222502 => 222503)


--- trunk/Source/WebKit/UIProcess/UserMediaPermissionRequestManagerProxy.cpp	2017-09-26 16:29:08 UTC (rev 222502)
+++ trunk/Source/WebKit/UIProcess/UserMediaPermissionRequestManagerProxy.cpp	2017-09-26 17:12:21 UTC (rev 222503)
@@ -23,8 +23,10 @@
 #include "APISecurityOrigin.h"
 #include "APIUIClient.h"
 #include "UserMediaProcessManager.h"
+#include "WebAutomationSession.h"
 #include "WebPageMessages.h"
 #include "WebPageProxy.h"
+#include "WebProcessPool.h"
 #include "WebProcessProxy.h"
 #include <WebCore/MediaConstraints.h>
 #include <WebCore/MockRealtimeMediaSourceCenter.h>
@@ -300,7 +302,18 @@
             allowRequest(request);
             return;
         }
+        
+        if (m_page.isControlledByAutomation()) {
+            if (WebAutomationSession* automationSession = m_page.process().processPool().automationSession()) {
+                if (automationSession->shouldAllowGetUserMediaForPage(m_page))
+                    allowRequest(request);
+                else
+                    userMediaAccessWasDenied(userMediaID, UserMediaPermissionRequestProxy::UserMediaAccessDenialReason::UserMediaDisabled);
 
+                return;
+            }
+        }
+
         if (!m_page.uiClient().decidePolicyForUserMediaPermissionRequest(m_page, *m_page.process().webFrame(frameID), WTFMove(userMediaOrigin), WTFMove(topLevelOrigin), request.get()))
             userMediaAccessWasDenied(userMediaID, UserMediaPermissionRequestProxy::UserMediaAccessDenialReason::UserMediaDisabled);
     };
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to