- Revision
- 200702
- Author
- bb...@apple.com
- Date
- 2016-05-11 13:57:08 -0700 (Wed, 11 May 2016)
Log Message
Web Automation: add command to asynchronously load the Web Inspector frontend in the background
https://bugs.webkit.org/show_bug.cgi?id=157509
Reviewed by Timothy Hatcher and Joseph Pecoraro.
In order to make it easier to debug code that executes as a result of an automation
command, this patch adds a new Automation command to asynchronously load the debugger
and Inspector frontend. It is designed for use by automation clients to implement an
auto-inspection feature to aid in debugging automation scripts.
* UIProcess/Automation/Automation.json: Add new command.
* UIProcess/Automation/WebAutomationSession.cpp:
(WebKit::WebAutomationSession::inspectBrowsingContext): Added.
(WebKit::WebAutomationSession::inspectorFrontendLoaded): Added.
This message is forwarded by WebInspectorProxy to the inspected page's session.
* UIProcess/Automation/WebAutomationSession.h:
* UIProcess/Cocoa/WebAutomationSessionCocoa.mm:
(WebKit::WebAutomationSession::sendSynthesizedEventsToPage):
Force the active automation window to become key and bring to front prior to
sending each NSEvent. This way, if the Inspector pauses while a command executes,
the automation window will get back focus when the Inspector unpauses just before
the next synthesized mouse or keyboard NSEvent is sent to its NSWindow.
* UIProcess/WebInspectorProxy.cpp:
(WebKit::WebInspectorProxy::frontendLoaded):
Forward to the inspected page's session.
* UIProcess/WebInspectorProxy.h:
* UIProcess/WebInspectorProxy.messages.in: Add notification of the frontend's load.
* WebProcess/WebPage/WebInspectorUI.cpp:
(WebKit::WebInspectorUI::frontendLoaded):
Kick off notifying the automation session in UIProcess that the inspector loaded.
(WebKit::WebInspectorUI::closeWindow):
In some circumstances, the Web Inspector can be loaded without showing
the window. If this hidden page closes, make sure the frontend host gets
a chance to disconnect its InspectorFrontendClient. Normally this happens
when the window closes, but unshown Inspectors do not get window instances.
Modified Paths
Diff
Modified: trunk/Source/WebKit2/ChangeLog (200701 => 200702)
--- trunk/Source/WebKit2/ChangeLog 2016-05-11 20:54:09 UTC (rev 200701)
+++ trunk/Source/WebKit2/ChangeLog 2016-05-11 20:57:08 UTC (rev 200702)
@@ -1,3 +1,46 @@
+2016-05-10 Brian Burg <bb...@apple.com>
+
+ Web Automation: add command to asynchronously load the Web Inspector frontend in the background
+ https://bugs.webkit.org/show_bug.cgi?id=157509
+
+ Reviewed by Timothy Hatcher and Joseph Pecoraro.
+
+ In order to make it easier to debug code that executes as a result of an automation
+ command, this patch adds a new Automation command to asynchronously load the debugger
+ and Inspector frontend. It is designed for use by automation clients to implement an
+ auto-inspection feature to aid in debugging automation scripts.
+
+ * UIProcess/Automation/Automation.json: Add new command.
+ * UIProcess/Automation/WebAutomationSession.cpp:
+ (WebKit::WebAutomationSession::inspectBrowsingContext): Added.
+ (WebKit::WebAutomationSession::inspectorFrontendLoaded): Added.
+ This message is forwarded by WebInspectorProxy to the inspected page's session.
+
+ * UIProcess/Automation/WebAutomationSession.h:
+ * UIProcess/Cocoa/WebAutomationSessionCocoa.mm:
+ (WebKit::WebAutomationSession::sendSynthesizedEventsToPage):
+ Force the active automation window to become key and bring to front prior to
+ sending each NSEvent. This way, if the Inspector pauses while a command executes,
+ the automation window will get back focus when the Inspector unpauses just before
+ the next synthesized mouse or keyboard NSEvent is sent to its NSWindow.
+
+ * UIProcess/WebInspectorProxy.cpp:
+ (WebKit::WebInspectorProxy::frontendLoaded):
+ Forward to the inspected page's session.
+
+ * UIProcess/WebInspectorProxy.h:
+ * UIProcess/WebInspectorProxy.messages.in: Add notification of the frontend's load.
+
+ * WebProcess/WebPage/WebInspectorUI.cpp:
+ (WebKit::WebInspectorUI::frontendLoaded):
+ Kick off notifying the automation session in UIProcess that the inspector loaded.
+
+ (WebKit::WebInspectorUI::closeWindow):
+ In some circumstances, the Web Inspector can be loaded without showing
+ the window. If this hidden page closes, make sure the frontend host gets
+ a chance to disconnect its InspectorFrontendClient. Normally this happens
+ when the window closes, but unshown Inspectors do not get window instances.
+
2016-05-11 Chris Dumez <cdu...@apple.com>
Update Node::appendChild() / replaceChild() / removeChild() / insertBefore() to take references instead of pointers
Modified: trunk/Source/WebKit2/UIProcess/Automation/Automation.json (200701 => 200702)
--- trunk/Source/WebKit2/UIProcess/Automation/Automation.json 2016-05-11 20:54:09 UTC (rev 200701)
+++ trunk/Source/WebKit2/UIProcess/Automation/Automation.json 2016-05-11 20:57:08 UTC (rev 200702)
@@ -294,6 +294,14 @@
"async": true
},
{
+ "name": "inspectBrowsingContext",
+ "description": "Inspect the specified browsing context using Web Inspector.",
+ "parameters": [
+ { "name": "handle", "$ref": "BrowsingContextHandle", "description": "The handle for the browsing context that should be inspected." }
+ ],
+ "async": true
+ },
+ {
"name": "evaluateJavaScriptFunction",
"description": "Evaluates a script function in a browsing context and calls it with the supplied arguments.",
"parameters": [
Modified: trunk/Source/WebKit2/UIProcess/Automation/WebAutomationSession.cpp (200701 => 200702)
--- trunk/Source/WebKit2/UIProcess/Automation/WebAutomationSession.cpp 2016-05-11 20:54:09 UTC (rev 200701)
+++ trunk/Source/WebKit2/UIProcess/Automation/WebAutomationSession.cpp 2016-05-11 20:57:08 UTC (rev 200702)
@@ -31,6 +31,7 @@
#include "WebAutomationSessionMessages.h"
#include "WebAutomationSessionProxyMessages.h"
#include "WebCookieManagerProxy.h"
+#include "WebInspectorProxy.h"
#include "WebProcessPool.h"
#include <_javascript_Core/InspectorBackendDispatcher.h>
#include <_javascript_Core/InspectorFrontendRouter.h>
@@ -432,12 +433,34 @@
page->reload(reloadFromOrigin, contentBlockersEnabled);
}
+void WebAutomationSession::inspectBrowsingContext(Inspector::ErrorString& errorString, const String& handle, Ref<InspectBrowsingContextCallback>&& callback)
+{
+ WebPageProxy* page = webPageProxyForHandle(handle);
+ if (!page)
+ FAIL_WITH_PREDEFINED_ERROR(WindowNotFound);
+
+ if (auto callback = m_pendingInspectorCallbacksPerPage.take(page->pageID()))
+ callback->sendFailure(STRING_FOR_PREDEFINED_ERROR_NAME(Timeout));
+ m_pendingInspectorCallbacksPerPage.set(page->pageID(), WTFMove(callback));
+
+ // Don't bring the inspector to front since this may be done automatically.
+ // We just want it loaded so it can pause if a breakpoint is hit during a command.
+ if (page->inspector())
+ page->inspector()->connect();
+}
+
void WebAutomationSession::navigationOccurredForPage(const WebPageProxy& page)
{
if (auto callback = m_pendingNavigationInBrowsingContextCallbacksPerPage.take(page.pageID()))
callback->sendSuccess(InspectorObject::create());
}
+void WebAutomationSession::inspectorFrontendLoaded(const WebPageProxy& page)
+{
+ if (auto callback = m_pendingInspectorCallbacksPerPage.take(page.pageID()))
+ callback->sendSuccess(InspectorObject::create());
+}
+
void WebAutomationSession::evaluateJavaScriptFunction(Inspector::ErrorString& errorString, const String& browsingContextHandle, const String* optionalFrameHandle, const String& function, const Inspector::InspectorArray& arguments, const bool* optionalExpectsImplicitCallbackArgument, const int* optionalCallbackTimeout, Ref<EvaluateJavaScriptFunctionCallback>&& callback)
{
WebPageProxy* page = webPageProxyForHandle(browsingContextHandle);
Modified: trunk/Source/WebKit2/UIProcess/Automation/WebAutomationSession.h (200701 => 200702)
--- trunk/Source/WebKit2/UIProcess/Automation/WebAutomationSession.h 2016-05-11 20:54:09 UTC (rev 200701)
+++ trunk/Source/WebKit2/UIProcess/Automation/WebAutomationSession.h 2016-05-11 20:57:08 UTC (rev 200702)
@@ -83,6 +83,7 @@
void setProcessPool(WebProcessPool*);
void navigationOccurredForPage(const WebPageProxy&);
+ void inspectorFrontendLoaded(const WebPageProxy&);
#if ENABLE(REMOTE_INSPECTOR)
// Inspector::RemoteAutomationTarget API
@@ -104,6 +105,7 @@
void goBackInBrowsingContext(Inspector::ErrorString&, const String&, Ref<GoBackInBrowsingContextCallback>&&) override;
void goForwardInBrowsingContext(Inspector::ErrorString&, const String&, Ref<GoForwardInBrowsingContextCallback>&&) override;
void reloadBrowsingContext(Inspector::ErrorString&, const String&, Ref<ReloadBrowsingContextCallback>&&) override;
+ void inspectBrowsingContext(Inspector::ErrorString&, const String&, Ref<InspectBrowsingContextCallback>&&) override;
void evaluateJavaScriptFunction(Inspector::ErrorString&, const String& browsingContextHandle, const String* optionalFrameHandle, const String& function, const Inspector::InspectorArray& arguments, const bool* optionalExpectsImplicitCallbackArgument, const int* optionalCallbackTimeout, 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;
@@ -176,6 +178,8 @@
HashMap<uint64_t, RefPtr<Inspector::BackendDispatcher::CallbackBase>> m_pendingNavigationInBrowsingContextCallbacksPerPage;
+ HashMap<uint64_t, RefPtr<Inspector::BackendDispatcher::CallbackBase>> m_pendingInspectorCallbacksPerPage;
+
uint64_t m_nextEvaluateJavaScriptCallbackID { 1 };
HashMap<uint64_t, RefPtr<Inspector::AutomationBackendDispatcherHandler::EvaluateJavaScriptFunctionCallback>> m_evaluateJavaScriptFunctionCallbacks;
Modified: trunk/Source/WebKit2/UIProcess/Cocoa/WebAutomationSessionCocoa.mm (200701 => 200702)
--- trunk/Source/WebKit2/UIProcess/Cocoa/WebAutomationSessionCocoa.mm 2016-05-11 20:54:09 UTC (rev 200701)
+++ trunk/Source/WebKit2/UIProcess/Cocoa/WebAutomationSessionCocoa.mm 2016-05-11 20:57:08 UTC (rev 200702)
@@ -51,6 +51,10 @@
NSWindow *window = page.platformWindow();
for (NSEvent *event in eventsToSend) {
+ // Take focus back in case the Inspector became focused while the prior command or
+ // NSEvent was delivered to the window.
+ [window makeKeyAndOrderFront:nil];
+
markEventAsSynthesizedForAutomation(event);
[window sendEvent:event];
}
Modified: trunk/Source/WebKit2/UIProcess/WebInspectorProxy.cpp (200701 => 200702)
--- trunk/Source/WebKit2/UIProcess/WebInspectorProxy.cpp 2016-05-11 20:54:09 UTC (rev 200701)
+++ trunk/Source/WebKit2/UIProcess/WebInspectorProxy.cpp 2016-05-11 20:57:08 UTC (rev 200702)
@@ -32,6 +32,7 @@
#include "WKArray.h"
#include "WKContextMenuItem.h"
#include "WKMutableArray.h"
+#include "WebAutomationSession.h"
#include "WebFramePolicyListenerProxy.h"
#include "WebFrameProxy.h"
#include "WebInspectorMessages.h"
@@ -601,6 +602,12 @@
platformDidClose();
}
+void WebInspectorProxy::frontendLoaded()
+{
+ if (auto* automationSession = m_inspectedPage->process().processPool().automationSession())
+ automationSession->inspectorFrontendLoaded(*m_inspectedPage);
+}
+
void WebInspectorProxy::bringToFront()
{
// WebCore::InspectorFrontendClientLocal tells us to do this on load. We want to
Modified: trunk/Source/WebKit2/UIProcess/WebInspectorProxy.h (200701 => 200702)
--- trunk/Source/WebKit2/UIProcess/WebInspectorProxy.h 2016-05-11 20:54:09 UTC (rev 200701)
+++ trunk/Source/WebKit2/UIProcess/WebInspectorProxy.h 2016-05-11 20:57:08 UTC (rev 200702)
@@ -190,6 +190,7 @@
// Called by WebInspectorProxy messages
void createInspectorPage(IPC::Attachment, bool canAttach, bool underTest);
+ void frontendLoaded();
void didClose();
void bringToFront();
void attachAvailabilityChanged(bool);
Modified: trunk/Source/WebKit2/UIProcess/WebInspectorProxy.messages.in (200701 => 200702)
--- trunk/Source/WebKit2/UIProcess/WebInspectorProxy.messages.in 2016-05-11 20:54:09 UTC (rev 200701)
+++ trunk/Source/WebKit2/UIProcess/WebInspectorProxy.messages.in 2016-05-11 20:57:08 UTC (rev 200702)
@@ -23,6 +23,7 @@
messages -> WebInspectorProxy {
CreateInspectorPage(IPC::Attachment connectionIdentifier, bool canAttach, bool underTest)
+ FrontendLoaded()
DidClose()
BringToFront()
Modified: trunk/Source/WebKit2/WebProcess/WebPage/WebInspectorUI.cpp (200701 => 200702)
--- trunk/Source/WebKit2/WebProcess/WebPage/WebInspectorUI.cpp 2016-05-11 20:54:09 UTC (rev 200701)
+++ trunk/Source/WebKit2/WebProcess/WebPage/WebInspectorUI.cpp 2016-05-11 20:57:08 UTC (rev 200702)
@@ -96,6 +96,8 @@
setDockingUnavailable(m_dockingUnavailable);
setDockSide(m_dockSide);
+ WebProcess::singleton().parentProcessConnection()->send(Messages::WebInspectorProxy::FrontendLoaded(), m_inspectedPageIdentifier);
+
bringToFront();
}
@@ -128,6 +130,9 @@
m_frontendController->setInspectorFrontendClient(nullptr);
m_frontendController = nullptr;
+ if (m_frontendHost)
+ m_frontendHost->disconnectClient();
+
m_inspectedPageIdentifier = 0;
m_underTest = false;
}