Web Automation: Add Automation.screenshot
https://bugs.webkit.org/show_bug.cgi?id=156073
<rdar://problem/25468646>

Reviewed by Timothy Hatcher and Brian Burg.

* UIProcess/Automation/Automation.json:
Add Automation.screenshot which returns base64 encoded PNG data.

* WebProcess/Automation/WebAutomationSessionProxy.h:
* WebProcess/Automation/WebAutomationSessionProxy.messages.in:
* UIProcess/Automation/WebAutomationSession.cpp:
(WebKit::WebAutomationSession::screenshot):
(WebKit::WebAutomationSession::didTakeScreenshot):
(WebKit::WebAutomationSession::platformGetBase64EncodedPNGData):
Send a message to the WebPage to get an Image of the page
and handle the response.

* UIProcess/Cocoa/WebAutomationSessionCocoa.mm:
(WebKit::WebAutomationSession::platformGetBase64EncodedPNGData):
Convert the bitmap data to a base64 encoded PNG.

* UIProcess/Automation/WebAutomationSession.h:
* UIProcess/Automation/WebAutomationSession.messages.in:
* WebProcess/Automation/WebAutomationSessionProxy.cpp:
(WebKit::evaluateJavaScriptCallback):
(WebKit::WebAutomationSessionProxy::didClearWindowObjectForFrame):
(WebKit::WebAutomationSessionProxy::resolveChildFrameWithOrdinal):
(WebKit::WebAutomationSessionProxy::resolveChildFrameWithNodeHandle):
(WebKit::WebAutomationSessionProxy::resolveChildFrameWithName):
(WebKit::WebAutomationSessionProxy::resolveParentFrame):
(WebKit::WebAutomationSessionProxy::computeElementLayout):
Use null string where possible for efficiency.

(WebKit::WebAutomationSessionProxy::takeScreenshot):
Take an image of the entire page and pass back to the UIProcess.

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@198907 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/WebKit2/UIProcess/Automation/WebAutomationSession.h b/Source/WebKit2/UIProcess/Automation/WebAutomationSession.h
index f937d7a..f0e5225 100644
--- a/Source/WebKit2/UIProcess/Automation/WebAutomationSession.h
+++ b/Source/WebKit2/UIProcess/Automation/WebAutomationSession.h
@@ -28,6 +28,7 @@
 #include "APIObject.h"
 #include "AutomationBackendDispatchers.h"
 #include "Connection.h"
+#include "ShareableBitmap.h"
 #include "WebEvent.h"
 #include <wtf/Forward.h>
 
@@ -105,6 +106,7 @@
     void evaluateJavaScriptFunction(Inspector::ErrorString&, const String& browsingContextHandle, const String* optionalFrameHandle, const String& function, const Inspector::InspectorArray& arguments, bool expectsImplicitCallbackArgument, Ref<Inspector::AutomationBackendDispatcherHandler::EvaluateJavaScriptFunctionCallback>&&) override;
     void performMouseInteraction(Inspector::ErrorString&, const String& handle, const Inspector::InspectorObject& requestedPosition, const String& mouseButton, const String& mouseInteraction, const Inspector::InspectorArray& keyModifiers, RefPtr<Inspector::Protocol::Automation::Point>& updatedPosition) override;
     void performKeyboardInteractions(Inspector::ErrorString&, const String& handle, const Inspector::InspectorArray& interactions) override;
+    void takeScreenshot(Inspector::ErrorString&, const String& handle, Ref<Inspector::AutomationBackendDispatcherHandler::TakeScreenshotCallback>&&) override;
     void resolveChildFrameHandle(Inspector::ErrorString&, const String& browsingContextHandle, const String* optionalFrameHandle, const int* optionalOrdinal, const String* optionalName, const String* optionalNodeHandle, Ref<ResolveChildFrameHandleCallback>&&) override;
     void resolveParentFrameHandle(Inspector::ErrorString&, const String& browsingContextHandle, const String& frameHandle, Ref<ResolveParentFrameHandleCallback>&&) override;
     void computeElementLayout(Inspector::ErrorString&, const String& browsingContextHandle, const String& frameHandle, const String& nodeHandle, const bool* optionalScrollIntoViewIfNeeded, const bool* useViewportCoordinates, Ref<Inspector::AutomationBackendDispatcherHandler::ComputeElementLayoutCallback>&&) override;
@@ -135,6 +137,7 @@
     void didResolveChildFrame(uint64_t callbackID, uint64_t frameID, const String& errorType);
     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);
 
     // Platform-specific helper methods.
     void platformSimulateMouseInteraction(WebPageProxy&, const WebCore::IntPoint& viewPosition, Inspector::Protocol::Automation::MouseInteraction, Inspector::Protocol::Automation::MouseButton, WebEvent::Modifiers);
@@ -142,6 +145,8 @@
     void platformSimulateKeyStroke(WebPageProxy&, Inspector::Protocol::Automation::KeyboardInteractionType, Inspector::Protocol::Automation::VirtualKey);
     // Simulates key presses to produce the codepoints in a string. One or more code points are delivered atomically at grapheme cluster boundaries.
     void platformSimulateKeySequence(WebPageProxy&, const String&);
+    // Get base64 encoded PNG data from a bitmap.
+    String platformGetBase64EncodedPNGData(const ShareableBitmap::Handle&);
 
 #if USE(APPKIT)
     void sendSynthesizedEventsToPage(WebPageProxy&, NSArray *eventsToSend);
@@ -174,6 +179,9 @@
     uint64_t m_nextComputeElementLayoutCallbackID { 1 };
     HashMap<uint64_t, RefPtr<Inspector::AutomationBackendDispatcherHandler::ComputeElementLayoutCallback>> m_computeElementLayoutCallbacks;
 
+    uint64_t m_nextScreenshotCallbackID { 1 };
+    HashMap<uint64_t, RefPtr<Inspector::AutomationBackendDispatcherHandler::TakeScreenshotCallback>> m_screenshotCallbacks;
+
 #if ENABLE(REMOTE_INSPECTOR)
     Inspector::FrontendChannel* m_remoteChannel { nullptr };
 #endif