Diff
Modified: trunk/Source/WebKit2/ChangeLog (198913 => 198914)
--- trunk/Source/WebKit2/ChangeLog 2016-03-31 20:52:38 UTC (rev 198913)
+++ trunk/Source/WebKit2/ChangeLog 2016-03-31 20:52:44 UTC (rev 198914)
@@ -1,3 +1,28 @@
+2016-03-31 Timothy Hatcher <[email protected]>
+
+ Web Automation: Navigation commands should not return until page loads or fails
+
+ https://bugs.webkit.org/show_bug.cgi?id=156063
+ rdar://problem/25464373
+
+ Reviewed by Brian Burg.
+
+ * UIProcess/Automation/Automation.json: Make navigation commands async.
+ * UIProcess/Automation/WebAutomationSession.cpp:
+ (WebKit::WebAutomationSession::navigateBrowsingContext): Save callback and timeout previous.
+ (WebKit::WebAutomationSession::goBackInBrowsingContext): Ditto.
+ (WebKit::WebAutomationSession::goForwardInBrowsingContext): Ditto.
+ (WebKit::WebAutomationSession::reloadBrowsingContext): Ditto.
+ (WebKit::WebAutomationSession::navigationOccuredForPage): Added. Fire callback for page.
+ * UIProcess/Automation/WebAutomationSession.h:
+
+ * UIProcess/WebPageProxy.cpp:
+ (WebKit::WebPageProxy::didFinishLoadForFrame): Call WebAutomationSession::navigationOccuredForPage.
+ (WebKit::WebPageProxy::didFailLoadForFrame): Ditto.
+ (WebKit::WebPageProxy::didSameDocumentNavigationForFrame): Ditto.
+
+ * UIProcess/WebProcessPool.h: Added automationSession() getter.
+
2016-03-30 Timothy Hatcher <[email protected]>
Web Automation: Add support for script timeouts to the evaluateJavaScriptFunction command
Modified: trunk/Source/WebKit2/UIProcess/Automation/Automation.json (198913 => 198914)
--- trunk/Source/WebKit2/UIProcess/Automation/Automation.json 2016-03-31 20:52:38 UTC (rev 198913)
+++ trunk/Source/WebKit2/UIProcess/Automation/Automation.json 2016-03-31 20:52:44 UTC (rev 198914)
@@ -47,6 +47,7 @@
"description": "This enum contains predefined error messages that can be used to signal a well-defined error condition, such as a missing implementation, unknown window handle, and so forth. The backend signals one of these errors by using it as a prefix of the commands's error message (the errorString argument in generated C++ backend dispatchers). This will be reported to the frontend as a protocol error with a JSON-RPC error code of 'ServerError'. It is up to the frontend whether and how to deal with errors.",
"enum": [
"InternalError",
+ "Timeout",
"_javascript_Error",
"_javascript_Timeout",
"WindowNotFound",
@@ -250,28 +251,32 @@
"parameters": [
{ "name": "handle", "$ref": "BrowsingContextHandle", "description": "The handle for the browsing context that should be navigated." },
{ "name": "url", "type": "string", "description": "The URL to load in the browsing context." }
- ]
+ ],
+ "async": true
},
{
"name": "goBackInBrowsingContext",
"description": "Navigates a browsing context to go back one page in history.",
"parameters": [
{ "name": "handle", "$ref": "BrowsingContextHandle", "description": "The handle for the browsing context that should be navigated." }
- ]
+ ],
+ "async": true
},
{
"name": "goForwardInBrowsingContext",
"description": "Navigates a browsing context to got forward one page in history.",
"parameters": [
{ "name": "handle", "$ref": "BrowsingContextHandle", "description": "The handle for the browsing context that should be navigated." }
- ]
+ ],
+ "async": true
},
{
"name": "reloadBrowsingContext",
"description": "Reloads the current page in a browsing context.",
"parameters": [
{ "name": "handle", "$ref": "BrowsingContextHandle", "description": "The handle for the browsing context that should be reloaded." }
- ]
+ ],
+ "async": true
},
{
"name": "evaluateJavaScriptFunction",
Modified: trunk/Source/WebKit2/UIProcess/Automation/WebAutomationSession.cpp (198913 => 198914)
--- trunk/Source/WebKit2/UIProcess/Automation/WebAutomationSession.cpp 2016-03-31 20:52:38 UTC (rev 198913)
+++ trunk/Source/WebKit2/UIProcess/Automation/WebAutomationSession.cpp 2016-03-31 20:52:44 UTC (rev 198914)
@@ -357,44 +357,66 @@
FAIL_WITH_PREDEFINED_ERROR_MESSAGE(InternalError);
}
-void WebAutomationSession::navigateBrowsingContext(Inspector::ErrorString& errorString, const String& handle, const String& url)
+void WebAutomationSession::navigateBrowsingContext(Inspector::ErrorString& errorString, const String& handle, const String& url, Ref<NavigateBrowsingContextCallback>&& callback)
{
WebPageProxy* page = webPageProxyForHandle(handle);
if (!page)
FAIL_WITH_PREDEFINED_ERROR_MESSAGE(WindowNotFound);
+ if (auto callback = m_pendingNavigationInBrowsingContextCallbacksPerPage.take(page->pageID()))
+ callback->sendFailure(Inspector::Protocol::getEnumConstantValue(Inspector::Protocol::Automation::ErrorMessage::Timeout));
+ m_pendingNavigationInBrowsingContextCallbacksPerPage.set(page->pageID(), WTFMove(callback));
+
page->loadRequest(WebCore::URL(WebCore::URL(), url));
}
-void WebAutomationSession::goBackInBrowsingContext(Inspector::ErrorString& errorString, const String& handle)
+void WebAutomationSession::goBackInBrowsingContext(Inspector::ErrorString& errorString, const String& handle, Ref<GoBackInBrowsingContextCallback>&& callback)
{
WebPageProxy* page = webPageProxyForHandle(handle);
if (!page)
FAIL_WITH_PREDEFINED_ERROR_MESSAGE(WindowNotFound);
+ if (auto callback = m_pendingNavigationInBrowsingContextCallbacksPerPage.take(page->pageID()))
+ callback->sendFailure(Inspector::Protocol::getEnumConstantValue(Inspector::Protocol::Automation::ErrorMessage::Timeout));
+ m_pendingNavigationInBrowsingContextCallbacksPerPage.set(page->pageID(), WTFMove(callback));
+
page->goBack();
}
-void WebAutomationSession::goForwardInBrowsingContext(Inspector::ErrorString& errorString, const String& handle)
+void WebAutomationSession::goForwardInBrowsingContext(Inspector::ErrorString& errorString, const String& handle, Ref<GoForwardInBrowsingContextCallback>&& callback)
{
WebPageProxy* page = webPageProxyForHandle(handle);
if (!page)
FAIL_WITH_PREDEFINED_ERROR_MESSAGE(WindowNotFound);
+ if (auto callback = m_pendingNavigationInBrowsingContextCallbacksPerPage.take(page->pageID()))
+ callback->sendFailure(Inspector::Protocol::getEnumConstantValue(Inspector::Protocol::Automation::ErrorMessage::Timeout));
+ m_pendingNavigationInBrowsingContextCallbacksPerPage.set(page->pageID(), WTFMove(callback));
+
page->goForward();
}
-void WebAutomationSession::reloadBrowsingContext(Inspector::ErrorString& errorString, const String& handle)
+void WebAutomationSession::reloadBrowsingContext(Inspector::ErrorString& errorString, const String& handle, Ref<ReloadBrowsingContextCallback>&& callback)
{
WebPageProxy* page = webPageProxyForHandle(handle);
if (!page)
FAIL_WITH_PREDEFINED_ERROR_MESSAGE(WindowNotFound);
+ if (auto callback = m_pendingNavigationInBrowsingContextCallbacksPerPage.take(page->pageID()))
+ callback->sendFailure(Inspector::Protocol::getEnumConstantValue(Inspector::Protocol::Automation::ErrorMessage::Timeout));
+ m_pendingNavigationInBrowsingContextCallbacksPerPage.set(page->pageID(), WTFMove(callback));
+
const bool reloadFromOrigin = false;
const bool contentBlockersEnabled = true;
page->reload(reloadFromOrigin, contentBlockersEnabled);
}
+void WebAutomationSession::navigationOccurredForPage(const WebPageProxy& page)
+{
+ if (auto callback = m_pendingNavigationInBrowsingContextCallbacksPerPage.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 (198913 => 198914)
--- trunk/Source/WebKit2/UIProcess/Automation/WebAutomationSession.h 2016-03-31 20:52:38 UTC (rev 198913)
+++ trunk/Source/WebKit2/UIProcess/Automation/WebAutomationSession.h 2016-03-31 20:52:44 UTC (rev 198914)
@@ -83,6 +83,8 @@
WebProcessPool* processPool() const { return m_processPool; }
void setProcessPool(WebProcessPool*);
+ void navigationOccurredForPage(const WebPageProxy&);
+
#if ENABLE(REMOTE_INSPECTOR)
// Inspector::RemoteAutomationTarget API
String name() const override { return m_sessionIdentifier; }
@@ -99,10 +101,10 @@
void switchToBrowsingContext(Inspector::ErrorString&, const String& browsingContextHandle, const String* optionalFrameHandle) override;
void resizeWindowOfBrowsingContext(Inspector::ErrorString&, const String& handle, const Inspector::InspectorObject& size) override;
void moveWindowOfBrowsingContext(Inspector::ErrorString&, const String& handle, const Inspector::InspectorObject& position) override;
- void navigateBrowsingContext(Inspector::ErrorString&, const String& handle, const String& url) override;
- void goBackInBrowsingContext(Inspector::ErrorString&, const String&) override;
- void goForwardInBrowsingContext(Inspector::ErrorString&, const String&) override;
- void reloadBrowsingContext(Inspector::ErrorString&, const String&) override;
+ void navigateBrowsingContext(Inspector::ErrorString&, const String& handle, const String& url, Ref<NavigateBrowsingContextCallback>&&) override;
+ 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 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;
@@ -167,6 +169,8 @@
HashMap<uint64_t, String> m_webFrameHandleMap;
HashMap<String, uint64_t> m_handleWebFrameMap;
+ HashMap<uint64_t, RefPtr<Inspector::BackendDispatcher::CallbackBase>> m_pendingNavigationInBrowsingContextCallbacksPerPage;
+
uint64_t m_nextEvaluateJavaScriptCallbackID { 1 };
HashMap<uint64_t, RefPtr<Inspector::AutomationBackendDispatcherHandler::EvaluateJavaScriptFunctionCallback>> m_evaluateJavaScriptFunctionCallbacks;
Modified: trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp (198913 => 198914)
--- trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp 2016-03-31 20:52:38 UTC (rev 198913)
+++ trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp 2016-03-31 20:52:44 UTC (rev 198914)
@@ -71,6 +71,7 @@
#include "TextCheckerState.h"
#include "UserMediaPermissionRequestProxy.h"
#include "WKContextPrivate.h"
+#include "WebAutomationSession.h"
#include "WebBackForwardList.h"
#include "WebBackForwardListItem.h"
#include "WebCertificateInfo.h"
@@ -3126,6 +3127,11 @@
if (isMainFrame)
m_pageLoadState.didFinishLoad(transaction);
+ if (isMainFrame && m_controlledByAutomation) {
+ if (auto* automationSession = process().processPool().automationSession())
+ automationSession->navigationOccurredForPage(*this);
+ }
+
frame->didFinishLoad();
m_pageLoadState.commitChanges();
@@ -3160,6 +3166,11 @@
if (isMainFrame)
m_pageLoadState.didFailLoad(transaction);
+ if (isMainFrame && m_controlledByAutomation) {
+ if (auto* automationSession = process().processPool().automationSession())
+ automationSession->navigationOccurredForPage(*this);
+ }
+
frame->didFailLoad();
m_pageLoadState.commitChanges();
@@ -3192,6 +3203,11 @@
if (isMainFrame)
m_pageLoadState.didSameDocumentNavigation(transaction, url);
+ if (isMainFrame && m_controlledByAutomation) {
+ if (auto* automationSession = process().processPool().automationSession())
+ automationSession->navigationOccurredForPage(*this);
+ }
+
m_pageLoadState.clearPendingAPIRequestURL(transaction);
frame->didSameDocumentNavigation(url);
Modified: trunk/Source/WebKit2/UIProcess/WebProcessPool.h (198913 => 198914)
--- trunk/Source/WebKit2/UIProcess/WebProcessPool.h 2016-03-31 20:52:38 UTC (rev 198913)
+++ trunk/Source/WebKit2/UIProcess/WebProcessPool.h 2016-03-31 20:52:44 UTC (rev 198914)
@@ -259,6 +259,7 @@
void updateAutomationCapabilities() const;
void setAutomationSession(RefPtr<WebAutomationSession>&&);
+ WebAutomationSession* automationSession() const { return m_automationSession.get(); }
// Defaults to false.
void setHTTPPipeliningEnabled(bool);