Diff
Modified: trunk/Source/WebKit2/ChangeLog (199090 => 199091)
--- trunk/Source/WebKit2/ChangeLog 2016-04-06 01:37:07 UTC (rev 199090)
+++ trunk/Source/WebKit2/ChangeLog 2016-04-06 03:23:18 UTC (rev 199091)
@@ -1,3 +1,38 @@
+2016-04-05 Brian Burg <[email protected]>
+
+ Web Automation: add support for getting, deleting, and adding cookies
+ https://bugs.webkit.org/show_bug.cgi?id=156090
+ <rdar://problem/25477678>
+
+ Reviewed by Timothy Hatcher.
+
+ Add protocol commands for manipulating cookies with respect to a given page.
+ Implement all but the addSingleCookie command, which needs a new WebCore API.
+
+ * UIProcess/Automation/Automation.json:
+ Copy the Page domain Cookie object. Add new commands.
+
+ * UIProcess/Automation/WebAutomationSession.cpp:
+ (WebKit::WebAutomationSession::getAllCookies):
+ (WebKit::buildObjectForCookie): Copied from InspectorPageAgent.
+ (WebKit::buildArrayForCookies): Copied from InspectorPageAgent.
+ (WebKit::WebAutomationSession::didGetCookiesForFrame):
+ (WebKit::WebAutomationSession::deleteSingleCookie):
+ (WebKit::WebAutomationSession::didDeleteCookie):
+ (WebKit::WebAutomationSession::addSingleCookie): Added a stub for now.
+ (WebKit::WebAutomationSession::deleteAllCookies):
+ This command can use the WebCookieManager supplement directly instead of
+ proxying through AutomationSession. It doesn't block until the delete is
+ performed like the other methods do, but this shouldn't be a problem.
+
+ * UIProcess/Automation/WebAutomationSession.h:
+ * UIProcess/Automation/WebAutomationSession.messages.in:
+ * WebProcess/Automation/WebAutomationSessionProxy.cpp:
+ (WebKit::WebAutomationSessionProxy::getCookiesForFrame):
+ (WebKit::WebAutomationSessionProxy::deleteCookie):
+ * WebProcess/Automation/WebAutomationSessionProxy.h:
+ * WebProcess/Automation/WebAutomationSessionProxy.messages.in:
+
2016-04-05 Alex Christensen <[email protected]>
Fix Range requests when not using the NetworkCache with NetworkSession
Modified: trunk/Source/WebKit2/UIProcess/Automation/Automation.json (199090 => 199091)
--- trunk/Source/WebKit2/UIProcess/Automation/Automation.json 2016-04-06 01:37:07 UTC (rev 199090)
+++ trunk/Source/WebKit2/UIProcess/Automation/Automation.json 2016-04-06 03:23:18 UTC (rev 199091)
@@ -187,6 +187,21 @@
{ "name": "key", "$ref": "VirtualKey", "optional": true, "description": "A virtual key to be used to perform the specified interaction." },
{ "name": "text", "type": "string", "optional": true, "description": "A unicode string to be delivered to the page. The sequence of key events is determined by splitting the string at grapheme cluster boundaries." }
]
+ },
+ {
+ "id": "Cookie",
+ "type": "object",
+ "properties": [
+ { "name": "name", "type": "string", "description": "Cookie name." },
+ { "name": "value", "type": "string", "description": "Cookie value." },
+ { "name": "domain", "type": "string", "description": "Cookie domain. If empty, the domain is inherited from the relevant browsing context." },
+ { "name": "path", "type": "string", "description": "Cookie path." },
+ { "name": "expires", "type": "number", "description": "Cookie expires." },
+ { "name": "size", "type": "integer", "description": "Cookie size." },
+ { "name": "httpOnly", "type": "boolean", "description": "True if cookie is http-only." },
+ { "name": "secure", "type": "boolean", "description": "True if cookie is secure." },
+ { "name": "session", "type": "boolean", "description": "True in case of session cookie." }
+ ]
}
],
"commands": [
@@ -410,6 +425,43 @@
{ "name": "browsingContextHandle", "$ref": "BrowsingContextHandle", "description": "The handle for the browsing context." },
{ "name": "userInput", "type": "string", "description": "The text to enter in the prompt." }
]
+ },
+ {
+ "name": "getAllCookies",
+ "description": "Returns all cookies visible to the specified browsing context.",
+ "parameters": [
+ { "name": "browsingContextHandle", "$ref": "BrowsingContextHandle", "description": "The handle for the browsing context." }
+ ],
+ "returns": [
+ { "name": "cookies", "type": "array", "items": { "$ref": "Cookie" }, "description": "Array of cookie objects." }
+ ],
+ "async": true
+ },
+ {
+ "name": "deleteSingleCookie",
+ "description": "Deletes a cookie with the given name if visible to the specified browsing context.",
+ "parameters": [
+ { "name": "browsingContextHandle", "$ref": "BrowsingContextHandle", "description": "The handle for the browsing context." },
+ { "name": "cookieName", "type": "string", "description": "Name of the cookie to remove." }
+ ],
+ "async": true
+ },
+ {
+ "name": "addSingleCookie",
+ "description": "Add a cookie to cookie storage for the specified browsing context.",
+ "parameters": [
+ { "name": "browsingContextHandle", "$ref": "BrowsingContextHandle", "description": "The handle for the browsing context." },
+ { "name": "cookie", "$ref": "Cookie", "description": "The cookie that should be added to storage." }
+ ],
+ "async": true
+ },
+ {
+ "name": "deleteAllCookies",
+ "description": "Delete all cookies that are visible to the specified browsing context.",
+ "parameters": [
+ { "name": "browsingContextHandle", "$ref": "BrowsingContextHandle", "description": "The handle for the browsing context." }
+ ],
+ "async": true
}
]
}
Modified: trunk/Source/WebKit2/UIProcess/Automation/WebAutomationSession.cpp (199090 => 199091)
--- trunk/Source/WebKit2/UIProcess/Automation/WebAutomationSession.cpp 2016-04-06 01:37:07 UTC (rev 199090)
+++ trunk/Source/WebKit2/UIProcess/Automation/WebAutomationSession.cpp 2016-04-06 03:23:18 UTC (rev 199091)
@@ -30,6 +30,7 @@
#include "AutomationProtocolObjects.h"
#include "WebAutomationSessionMessages.h"
#include "WebAutomationSessionProxyMessages.h"
+#include "WebCookieManagerProxy.h"
#include "WebProcessPool.h"
#include <_javascript_Core/InspectorBackendDispatcher.h>
#include <_javascript_Core/InspectorFrontendRouter.h>
@@ -657,6 +658,118 @@
m_client->setUserInputForCurrentJavaScriptPromptOnPage(this, page, promptValue);
}
+void WebAutomationSession::getAllCookies(ErrorString& errorString, const String& browsingContextHandle, Ref<GetAllCookiesCallback>&& callback)
+{
+ WebPageProxy* page = webPageProxyForHandle(browsingContextHandle);
+ if (!page)
+ FAIL_WITH_PREDEFINED_ERROR_MESSAGE(WindowNotFound);
+
+ WebFrameProxy* mainFrame = page->mainFrame();
+ ASSERT(mainFrame);
+ if (!mainFrame)
+ FAIL_WITH_PREDEFINED_ERROR_MESSAGE(WindowNotFound);
+
+ uint64_t callbackID = m_nextGetCookiesCallbackID++;
+ m_getCookieCallbacks.set(callbackID, WTFMove(callback));
+
+ page->process().send(Messages::WebAutomationSessionProxy::GetCookiesForFrame(mainFrame->frameID(), callbackID), 0);
+}
+
+static Ref<Inspector::Protocol::Automation::Cookie> buildObjectForCookie(const WebCore::Cookie& cookie)
+{
+ return Inspector::Protocol::Automation::Cookie::create()
+ .setName(cookie.name)
+ .setValue(cookie.value)
+ .setDomain(cookie.domain)
+ .setPath(cookie.path)
+ .setExpires(cookie.expires)
+ .setSize((cookie.name.length() + cookie.value.length()))
+ .setHttpOnly(cookie.httpOnly)
+ .setSecure(cookie.secure)
+ .setSession(cookie.session)
+ .release();
+}
+
+static Ref<Inspector::Protocol::Array<Inspector::Protocol::Automation::Cookie>> buildArrayForCookies(Vector<WebCore::Cookie>& cookiesList)
+{
+ auto cookies = Inspector::Protocol::Array<Inspector::Protocol::Automation::Cookie>::create();
+
+ for (const auto& cookie : cookiesList)
+ cookies->addItem(buildObjectForCookie(cookie));
+
+ return cookies;
+}
+
+void WebAutomationSession::didGetCookiesForFrame(uint64_t callbackID, Vector<WebCore::Cookie> cookies, const String& errorType)
+{
+ auto callback = m_getCookieCallbacks.take(callbackID);
+ if (!callback)
+ return;
+
+ if (!errorType.isEmpty()) {
+ callback->sendFailure(errorType);
+ return;
+ }
+
+ callback->sendSuccess(buildArrayForCookies(cookies));
+}
+
+void WebAutomationSession::deleteSingleCookie(ErrorString& errorString, const String& browsingContextHandle, const String& cookieName, Ref<DeleteSingleCookieCallback>&& callback)
+{
+ WebPageProxy* page = webPageProxyForHandle(browsingContextHandle);
+ if (!page)
+ FAIL_WITH_PREDEFINED_ERROR_MESSAGE(WindowNotFound);
+
+ WebFrameProxy* mainFrame = page->mainFrame();
+ ASSERT(mainFrame);
+ if (!mainFrame)
+ FAIL_WITH_PREDEFINED_ERROR_MESSAGE(WindowNotFound);
+
+ uint64_t callbackID = m_nextDeleteCookieCallbackID++;
+ m_deleteCookieCallbacks.set(callbackID, WTFMove(callback));
+
+ page->process().send(Messages::WebAutomationSessionProxy::DeleteCookie(mainFrame->frameID(), cookieName, callbackID), 0);
+}
+
+void WebAutomationSession::didDeleteCookie(uint64_t callbackID, const String& errorType)
+{
+ auto callback = m_deleteCookieCallbacks.take(callbackID);
+ if (!callback)
+ return;
+
+ if (!errorType.isEmpty()) {
+ callback->sendFailure(errorType);
+ return;
+ }
+
+ callback->sendSuccess();
+}
+
+void WebAutomationSession::addSingleCookie(ErrorString& errorString, const String& browsingContextHandle, const Inspector::InspectorObject& cookie, Ref<AddSingleCookieCallback>&& callback)
+{
+ // FIXME: Implementing this command requires a new CookieJar API <https://webkit.org/b/156091>
+ UNUSED_PARAM(browsingContextHandle);
+ // FIXME: if the incoming cookie's domain is the string '(inherit)',
+ // then it should be inherited from the main frame's domain.
+ UNUSED_PARAM(cookie);
+ UNUSED_PARAM(callback);
+
+ FAIL_WITH_PREDEFINED_ERROR_MESSAGE(NotImplemented);
+}
+
+void WebAutomationSession::deleteAllCookies(ErrorString& errorString, const String& browsingContextHandle, Ref<DeleteAllCookiesCallback>&& callback)
+{
+ WebPageProxy* page = webPageProxyForHandle(browsingContextHandle);
+ if (!page)
+ FAIL_WITH_PREDEFINED_ERROR_MESSAGE(WindowNotFound);
+
+ WebCore::URL activeURL = WebCore::URL(WebCore::URL(), page->pageLoadState().activeURL());
+ ASSERT(activeURL.isValid());
+
+ WebCookieManagerProxy* cookieManager = m_processPool->supplement<WebCookieManagerProxy>();
+ cookieManager->deleteCookiesForHostname(activeURL.host());
+}
+
#if USE(APPKIT)
static WebEvent::Modifiers protocolModifierToWebEventModifier(Inspector::Protocol::Automation::KeyModifier modifier)
{
Modified: trunk/Source/WebKit2/UIProcess/Automation/WebAutomationSession.h (199090 => 199091)
--- trunk/Source/WebKit2/UIProcess/Automation/WebAutomationSession.h 2016-04-06 01:37:07 UTC (rev 199090)
+++ trunk/Source/WebKit2/UIProcess/Automation/WebAutomationSession.h 2016-04-06 03:23:18 UTC (rev 199091)
@@ -46,11 +46,10 @@
}
namespace WebCore {
+class IntPoint;
class IntRect;
-}
-namespace WebCore {
-class IntPoint;
+struct Cookie;
}
#if USE(APPKIT)
@@ -117,7 +116,10 @@
void acceptCurrentJavaScriptDialog(Inspector::ErrorString&, const String& browsingContextHandle) override;
void messageOfCurrentJavaScriptDialog(Inspector::ErrorString&, const String& browsingContextHandle, String* text) override;
void setUserInputForCurrentJavaScriptPrompt(Inspector::ErrorString&, const String& browsingContextHandle, const String& text) override;
-
+ void getAllCookies(Inspector::ErrorString&, const String& browsingContextHandle, Ref<GetAllCookiesCallback>&&) override;
+ 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, Ref<DeleteAllCookiesCallback>&&) override;
#if USE(APPKIT)
bool wasEventSynthesizedForAutomation(NSEvent *);
#endif
@@ -140,6 +142,8 @@
void didResolveParentFrame(uint64_t callbackID, uint64_t frameID, const String& errorType);
void didComputeElementLayout(uint64_t callbackID, WebCore::IntRect, const String& errorType);
void didTakeScreenshot(uint64_t callbackID, const ShareableBitmap::Handle&, const String& errorType);
+ void didGetCookiesForFrame(uint64_t callbackID, Vector<WebCore::Cookie>, const String& errorType);
+ void didDeleteCookie(uint64_t callbackID, const String& errorType);
// Platform-specific helper methods.
void platformSimulateMouseInteraction(WebPageProxy&, const WebCore::IntPoint& viewPosition, Inspector::Protocol::Automation::MouseInteraction, Inspector::Protocol::Automation::MouseButton, WebEvent::Modifiers);
@@ -186,6 +190,12 @@
uint64_t m_nextScreenshotCallbackID { 1 };
HashMap<uint64_t, RefPtr<Inspector::AutomationBackendDispatcherHandler::TakeScreenshotCallback>> m_screenshotCallbacks;
+ uint64_t m_nextGetCookiesCallbackID { 1 };
+ HashMap<uint64_t, RefPtr<Inspector::AutomationBackendDispatcherHandler::GetAllCookiesCallback>> m_getCookieCallbacks;
+
+ uint64_t m_nextDeleteCookieCallbackID { 1 };
+ HashMap<uint64_t, RefPtr<Inspector::AutomationBackendDispatcherHandler::DeleteSingleCookieCallback>> m_deleteCookieCallbacks;
+
#if ENABLE(REMOTE_INSPECTOR)
Inspector::FrontendChannel* m_remoteChannel { nullptr };
#endif
Modified: trunk/Source/WebKit2/UIProcess/Automation/WebAutomationSession.messages.in (199090 => 199091)
--- trunk/Source/WebKit2/UIProcess/Automation/WebAutomationSession.messages.in 2016-04-06 01:37:07 UTC (rev 199090)
+++ trunk/Source/WebKit2/UIProcess/Automation/WebAutomationSession.messages.in 2016-04-06 03:23:18 UTC (rev 199091)
@@ -29,4 +29,7 @@
DidComputeElementLayout(uint64_t callbackID, WebCore::IntRect rect, String errorType)
DidTakeScreenshot(uint64_t callbackID, WebKit::ShareableBitmap::Handle imageDataHandle, String errorType)
+
+ DidGetCookiesForFrame(uint64_t callbackID, Vector<WebCore::Cookie> cookies, String errorType)
+ DidDeleteCookie(uint64_t callbackID, String errorType)
}
Modified: trunk/Source/WebKit2/WebProcess/Automation/WebAutomationSessionProxy.cpp (199090 => 199091)
--- trunk/Source/WebKit2/WebProcess/Automation/WebAutomationSessionProxy.cpp 2016-04-06 01:37:07 UTC (rev 199090)
+++ trunk/Source/WebKit2/WebProcess/Automation/WebAutomationSessionProxy.cpp 2016-04-06 03:23:18 UTC (rev 199091)
@@ -39,6 +39,7 @@
#include <_javascript_Core/JSRetainPtr.h>
#include <_javascript_Core/JSStringRefPrivate.h>
#include <_javascript_Core/OpaqueJSString.h>
+#include <WebCore/CookieJar.h>
#include <WebCore/DOMWindow.h>
#include <WebCore/Frame.h>
#include <WebCore/FrameTree.h>
@@ -492,4 +493,38 @@
WebProcess::singleton().parentProcessConnection()->send(Messages::WebAutomationSession::DidTakeScreenshot(callbackID, handle, String()), 0);
}
+void WebAutomationSessionProxy::getCookiesForFrame(uint64_t frameID, uint64_t callbackID)
+{
+ String frameNotFoundErrorType = Inspector::Protocol::AutomationHelpers::getEnumConstantValue(Inspector::Protocol::Automation::ErrorMessage::FrameNotFound);
+
+ WebFrame* frame = WebProcess::singleton().webFrame(frameID);
+ if (!frame || !frame->coreFrame() || !frame->coreFrame()->document()) {
+ WebProcess::singleton().parentProcessConnection()->send(Messages::WebAutomationSession::DidGetCookiesForFrame(callbackID, Vector<WebCore::Cookie>(), frameNotFoundErrorType), 0);
+ return;
+ }
+
+ // This returns the same list of cookies as when evaluating `document.cookies` in _javascript_.
+ WebCore::Document* document = frame->coreFrame()->document();
+ Vector<WebCore::Cookie> foundCookies;
+ WebCore::getRawCookies(document, document->cookieURL(), foundCookies);
+
+ WebProcess::singleton().parentProcessConnection()->send(Messages::WebAutomationSession::DidGetCookiesForFrame(callbackID, foundCookies, String()), 0);
+}
+
+void WebAutomationSessionProxy::deleteCookie(uint64_t frameID, String cookieName, uint64_t callbackID)
+{
+ String frameNotFoundErrorType = Inspector::Protocol::AutomationHelpers::getEnumConstantValue(Inspector::Protocol::Automation::ErrorMessage::FrameNotFound);
+
+ WebFrame* frame = WebProcess::singleton().webFrame(frameID);
+ if (!frame || !frame->coreFrame() || !frame->coreFrame()->document()) {
+ WebProcess::singleton().parentProcessConnection()->send(Messages::WebAutomationSession::DidDeleteCookie(callbackID, frameNotFoundErrorType), 0);
+ return;
+ }
+
+ WebCore::Document* document = frame->coreFrame()->document();
+ WebCore::deleteCookie(document, document->cookieURL(), cookieName);
+
+ WebProcess::singleton().parentProcessConnection()->send(Messages::WebAutomationSession::DidDeleteCookie(callbackID, String()), 0);
+}
+
} // namespace WebKit
Modified: trunk/Source/WebKit2/WebProcess/Automation/WebAutomationSessionProxy.h (199090 => 199091)
--- trunk/Source/WebKit2/WebProcess/Automation/WebAutomationSessionProxy.h 2016-04-06 01:37:07 UTC (rev 199090)
+++ trunk/Source/WebKit2/WebProcess/Automation/WebAutomationSessionProxy.h 2016-04-06 03:23:18 UTC (rev 199091)
@@ -66,6 +66,8 @@
void focusFrame(uint64_t frameID);
void computeElementLayout(uint64_t frameID, String nodeHandle, bool scrollIntoViewIfNeeded, bool useViewportCoordinates, uint64_t callbackID);
void takeScreenshot(uint64_t pageID, uint64_t callbackID);
+ void getCookiesForFrame(uint64_t frameID, uint64_t callbackID);
+ void deleteCookie(uint64_t frameID, String cookieName, uint64_t callbackID);
String m_sessionIdentifier;
Modified: trunk/Source/WebKit2/WebProcess/Automation/WebAutomationSessionProxy.messages.in (199090 => 199091)
--- trunk/Source/WebKit2/WebProcess/Automation/WebAutomationSessionProxy.messages.in 2016-04-06 01:37:07 UTC (rev 199090)
+++ trunk/Source/WebKit2/WebProcess/Automation/WebAutomationSessionProxy.messages.in 2016-04-06 03:23:18 UTC (rev 199091)
@@ -33,4 +33,7 @@
ComputeElementLayout(uint64_t frameID, String nodeHandle, bool scrollIntoViewIfNeeded, bool useViewportCoordinates, uint64_t callbackID)
TakeScreenshot(uint64_t pageID, uint64_t callbackID)
+
+ GetCookiesForFrame(uint64_t frameID, uint64_t callbackID)
+ DeleteCookie(uint64_t frameID, String cookieName, uint64_t callbackID)
}