Title: [220317] trunk/Source
Revision
220317
Author
carlo...@webkit.org
Date
2017-08-05 04:14:34 -0700 (Sat, 05 Aug 2017)

Log Message

WebDriver: Implement page load strategy
https://bugs.webkit.org/show_bug.cgi?id=175183

Reviewed by Brian Burg.

Source/WebDriver:

Validate and parse page load strategy when processing capabilities.

* Capabilities.h:
* Session.cpp:
(WebDriver::Session::pageLoadStrategyString const): Helper to get the page load strategy as a String to be
passed to Automation.
(WebDriver::Session::go): Pass page load strategy if present.
(WebDriver::Session::back): Ditto.
(WebDriver::Session::forward): Ditto.
(WebDriver::Session::refresh): Ditto.
(WebDriver::Session::waitForNavigationToComplete): Ditto.
* Session.h:
* WebDriverService.cpp:
(WebDriver::deserializePageLoadStrategy):
(WebDriver::WebDriverService::parseCapabilities const):
(WebDriver::WebDriverService::validatedCapabilities const):
(WebDriver::WebDriverService::newSession):

Source/WebKit:

Split pending navigation maps into normal and eager, and use one or the other depending on the received page
load strategy. We need to keep different maps for every page load strategy because every command could use a
different strategy.

* UIProcess/Automation/WebAutomationSession.cpp:
(WebKit::WebAutomationSession::waitForNavigationToComplete): Extract page load strategy from parameter and pass
it to waitForNavigationToCompleteOnPage() and waitForNavigationToCompleteOnFrame().
(WebKit::WebAutomationSession::waitForNavigationToCompleteOnPage): Return early if page load strategy is
none. Otherwise at the pening callback to the normal or eager map depeding on the page load straegy.
(WebKit::WebAutomationSession::waitForNavigationToCompleteOnFrame): Ditto.
(WebKit::respondToPendingNavigationCallbacksWithTimeout): Helper to send pening navigation callback in case of
timeout failure.
(WebKit::WebAutomationSession::loadTimerFired): Call finishPendingNavigationsWithTimeoutFailure() with all the maps.
(WebKit::WebAutomationSession::navigateBrowsingContext): Extract page load strategy from parameter and pass it
to waitForNavigationToCompleteOnPage().
(WebKit::WebAutomationSession::goBackInBrowsingContext): Ditto.
(WebKit::WebAutomationSession::goForwardInBrowsingContext): Ditto.
(WebKit::WebAutomationSession::reloadBrowsingContext): Ditto.
(WebKit::WebAutomationSession::navigationOccurredForFrame): Use the normal maps.
(WebKit::WebAutomationSession::documentLoadedForFrame): Stop timeout timer and dispatch eager pending navigations.
* UIProcess/Automation/WebAutomationSession.h:
* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::didFinishDocumentLoadForFrame): Notify the automation session.

Modified Paths

Diff

Modified: trunk/Source/WebDriver/Capabilities.h (220316 => 220317)


--- trunk/Source/WebDriver/Capabilities.h	2017-08-05 10:32:43 UTC (rev 220316)
+++ trunk/Source/WebDriver/Capabilities.h	2017-08-05 11:14:34 UTC (rev 220317)
@@ -38,6 +38,12 @@
     std::optional<Seconds> implicit;
 };
 
+enum class PageLoadStrategy {
+    None,
+    Normal,
+    Eager
+};
+
 struct Capabilities {
     std::optional<String> browserName;
     std::optional<String> browserVersion;
@@ -44,6 +50,7 @@
     std::optional<String> platformName;
     std::optional<bool> acceptInsecureCerts;
     std::optional<Timeouts> timeouts;
+    std::optional<PageLoadStrategy> pageLoadStrategy;
 #if PLATFORM(GTK)
     std::optional<String> browserBinary;
     std::optional<Vector<String>> browserArguments;

Modified: trunk/Source/WebDriver/ChangeLog (220316 => 220317)


--- trunk/Source/WebDriver/ChangeLog	2017-08-05 10:32:43 UTC (rev 220316)
+++ trunk/Source/WebDriver/ChangeLog	2017-08-05 11:14:34 UTC (rev 220317)
@@ -1,5 +1,30 @@
 2017-08-05  Carlos Garcia Campos  <cgar...@igalia.com>
 
+        WebDriver: Implement page load strategy
+        https://bugs.webkit.org/show_bug.cgi?id=175183
+
+        Reviewed by Brian Burg.
+
+        Validate and parse page load strategy when processing capabilities.
+
+        * Capabilities.h:
+        * Session.cpp:
+        (WebDriver::Session::pageLoadStrategyString const): Helper to get the page load strategy as a String to be
+        passed to Automation.
+        (WebDriver::Session::go): Pass page load strategy if present.
+        (WebDriver::Session::back): Ditto.
+        (WebDriver::Session::forward): Ditto.
+        (WebDriver::Session::refresh): Ditto.
+        (WebDriver::Session::waitForNavigationToComplete): Ditto.
+        * Session.h:
+        * WebDriverService.cpp:
+        (WebDriver::deserializePageLoadStrategy):
+        (WebDriver::WebDriverService::parseCapabilities const):
+        (WebDriver::WebDriverService::validatedCapabilities const):
+        (WebDriver::WebDriverService::newSession):
+
+2017-08-05  Carlos Garcia Campos  <cgar...@igalia.com>
+
         Unreviewed. Try to fix build with clang after r220315.
 
         * WebDriverService.cpp:

Modified: trunk/Source/WebDriver/Session.cpp (220316 => 220317)


--- trunk/Source/WebDriver/Session.cpp	2017-08-05 10:32:43 UTC (rev 220316)
+++ trunk/Source/WebDriver/Session.cpp	2017-08-05 11:14:34 UTC (rev 220317)
@@ -102,6 +102,23 @@
         m_currentBrowsingContext = browsingContext;
 }
 
+std::optional<String> Session::pageLoadStrategyString() const
+{
+    if (!capabilities().pageLoadStrategy)
+        return std::nullopt;
+
+    switch (capabilities().pageLoadStrategy.value()) {
+    case PageLoadStrategy::None:
+        return String("None");
+    case PageLoadStrategy::Normal:
+        return String("Normal");
+    case PageLoadStrategy::Eager:
+        return String("Eager");
+    }
+
+    return std::nullopt;
+}
+
 void Session::createTopLevelBrowsingContext(Function<void (CommandResult&&)>&& completionHandler)
 {
     ASSERT(!m_toplevelBrowsingContext.value());
@@ -134,6 +151,8 @@
     parameters->setString(ASCIILiteral("url"), url);
     if (m_timeouts.pageLoad)
         parameters->setInteger(ASCIILiteral("pageLoadTimeout"), m_timeouts.pageLoad.value().millisecondsAs<int>());
+    if (auto pageLoadStrategy = pageLoadStrategyString())
+        parameters->setString(ASCIILiteral("pageLoadStrategy"), pageLoadStrategy.value());
     m_host->sendCommandToBackend(ASCIILiteral("navigateBrowsingContext"), WTFMove(parameters), [this, protectedThis = makeRef(*this), completionHandler = WTFMove(completionHandler)](SessionHost::CommandResponse&& response) {
         if (response.isError) {
             completionHandler(CommandResult::fail(WTFMove(response.responseObject)));
@@ -183,6 +202,8 @@
     parameters->setString(ASCIILiteral("handle"), m_toplevelBrowsingContext.value());
     if (m_timeouts.pageLoad)
         parameters->setInteger(ASCIILiteral("pageLoadTimeout"), m_timeouts.pageLoad.value().millisecondsAs<int>());
+    if (auto pageLoadStrategy = pageLoadStrategyString())
+        parameters->setString(ASCIILiteral("pageLoadStrategy"), pageLoadStrategy.value());
     m_host->sendCommandToBackend(ASCIILiteral("goBackInBrowsingContext"), WTFMove(parameters), [this, protectedThis = makeRef(*this), completionHandler = WTFMove(completionHandler)](SessionHost::CommandResponse&& response) {
         if (response.isError) {
             completionHandler(CommandResult::fail(WTFMove(response.responseObject)));
@@ -204,6 +225,8 @@
     parameters->setString(ASCIILiteral("handle"), m_toplevelBrowsingContext.value());
     if (m_timeouts.pageLoad)
         parameters->setInteger(ASCIILiteral("pageLoadTimeout"), m_timeouts.pageLoad.value().millisecondsAs<int>());
+    if (auto pageLoadStrategy = pageLoadStrategyString())
+        parameters->setString(ASCIILiteral("pageLoadStrategy"), pageLoadStrategy.value());
     m_host->sendCommandToBackend(ASCIILiteral("goForwardInBrowsingContext"), WTFMove(parameters), [this, protectedThis = makeRef(*this), completionHandler = WTFMove(completionHandler)](SessionHost::CommandResponse&& response) {
         if (response.isError) {
             completionHandler(CommandResult::fail(WTFMove(response.responseObject)));
@@ -225,6 +248,8 @@
     parameters->setString(ASCIILiteral("handle"), m_toplevelBrowsingContext.value());
     if (m_timeouts.pageLoad)
         parameters->setInteger(ASCIILiteral("pageLoadTimeout"), m_timeouts.pageLoad.value().millisecondsAs<int>());
+    if (auto pageLoadStrategy = pageLoadStrategyString())
+        parameters->setString(ASCIILiteral("pageLoadStrategy"), pageLoadStrategy.value());
     m_host->sendCommandToBackend(ASCIILiteral("reloadBrowsingContext"), WTFMove(parameters), [this, protectedThis = makeRef(*this), completionHandler = WTFMove(completionHandler)](SessionHost::CommandResponse&& response) {
         if (response.isError) {
             completionHandler(CommandResult::fail(WTFMove(response.responseObject)));
@@ -981,6 +1006,8 @@
         parameters->setString(ASCIILiteral("frameHandle"), m_currentBrowsingContext.value());
     if (m_timeouts.pageLoad)
         parameters->setInteger(ASCIILiteral("pageLoadTimeout"), m_timeouts.pageLoad.value().millisecondsAs<int>());
+    if (auto pageLoadStrategy = pageLoadStrategyString())
+        parameters->setString(ASCIILiteral("pageLoadStrategy"), pageLoadStrategy.value());
     m_host->sendCommandToBackend(ASCIILiteral("waitForNavigationToComplete"), WTFMove(parameters), [this, protectedThis = makeRef(*this), completionHandler = WTFMove(completionHandler)](SessionHost::CommandResponse&& response) {
         if (response.isError) {
             auto result = CommandResult::fail(WTFMove(response.responseObject));

Modified: trunk/Source/WebDriver/Session.h (220316 => 220317)


--- trunk/Source/WebDriver/Session.h	2017-08-05 10:32:43 UTC (rev 220316)
+++ trunk/Source/WebDriver/Session.h	2017-08-05 11:14:34 UTC (rev 220317)
@@ -101,6 +101,8 @@
     void switchToTopLevelBrowsingContext(std::optional<String>);
     void switchToBrowsingContext(std::optional<String>);
 
+    std::optional<String> pageLoadStrategyString() const;
+
     RefPtr<Inspector::InspectorObject> createElement(RefPtr<Inspector::InspectorValue>&&);
     RefPtr<Inspector::InspectorObject> createElement(const String& elementID);
     RefPtr<Inspector::InspectorObject> extractElement(Inspector::InspectorValue&);

Modified: trunk/Source/WebDriver/WebDriverService.cpp (220316 => 220317)


--- trunk/Source/WebDriver/WebDriverService.cpp	2017-08-05 10:32:43 UTC (rev 220316)
+++ trunk/Source/WebDriver/WebDriverService.cpp	2017-08-05 11:14:34 UTC (rev 220317)
@@ -277,6 +277,17 @@
     return timeouts;
 }
 
+static std::optional<PageLoadStrategy> deserializePageLoadStrategy(const String& pageLoadStrategy)
+{
+    if (pageLoadStrategy == "none")
+        return PageLoadStrategy::None;
+    if (pageLoadStrategy == "normal")
+        return PageLoadStrategy::Normal;
+    if (pageLoadStrategy == "eager")
+        return PageLoadStrategy::Eager;
+    return std::nullopt;
+}
+
 void WebDriverService::parseCapabilities(const InspectorObject& matchedCapabilities, Capabilities& capabilities) const
 {
     // Matched capabilities have already been validated.
@@ -295,6 +306,9 @@
     RefPtr<InspectorObject> timeouts;
     if (matchedCapabilities.getObject(ASCIILiteral("timeouts"), timeouts))
         capabilities.timeouts = deserializeTimeouts(*timeouts);
+    String pageLoadStrategy;
+    if (matchedCapabilities.getString(ASCIILiteral("pageLoadStrategy"), pageLoadStrategy))
+        capabilities.pageLoadStrategy = deserializePageLoadStrategy(pageLoadStrategy);
     platformParseCapabilities(matchedCapabilities, capabilities);
 }
 
@@ -336,9 +350,8 @@
             result->setString(it->key, stringValue);
         } else if (it->key == "pageLoadStrategy") {
             String pageLoadStrategy;
-            if (!it->value->asString(pageLoadStrategy))
+            if (!it->value->asString(pageLoadStrategy) || !deserializePageLoadStrategy(pageLoadStrategy))
                 return nullptr;
-            // FIXME: implement pageLoadStrategy.
             result->setString(it->key, pageLoadStrategy);
         } else if (it->key == "proxy") {
             // FIXME: implement proxy support.
@@ -560,6 +573,19 @@
                     timeoutsObject->setInteger(ASCIILiteral("implicit"), capabilities.timeouts.value().implicit.value().millisecondsAs<int>());
                 capabilitiesObject->setObject(ASCIILiteral("timeouts"), WTFMove(timeoutsObject));
             }
+            if (capabilities.pageLoadStrategy) {
+                switch (capabilities.pageLoadStrategy.value()) {
+                case PageLoadStrategy::None:
+                    capabilitiesObject->setString(ASCIILiteral("pageLoadStrategy"), "none");
+                    break;
+                case PageLoadStrategy::Normal:
+                    capabilitiesObject->setString(ASCIILiteral("pageLoadStrategy"), "normal");
+                    break;
+                case PageLoadStrategy::Eager:
+                    capabilitiesObject->setString(ASCIILiteral("pageLoadStrategy"), "eager");
+                    break;
+                }
+            }
             resultObject->setObject(ASCIILiteral("value"), WTFMove(capabilitiesObject));
             completionHandler(CommandResult::success(WTFMove(resultObject)));
         });

Modified: trunk/Source/WebKit/ChangeLog (220316 => 220317)


--- trunk/Source/WebKit/ChangeLog	2017-08-05 10:32:43 UTC (rev 220316)
+++ trunk/Source/WebKit/ChangeLog	2017-08-05 11:14:34 UTC (rev 220317)
@@ -1,5 +1,36 @@
 2017-08-05  Carlos Garcia Campos  <cgar...@igalia.com>
 
+        WebDriver: Implement page load strategy
+        https://bugs.webkit.org/show_bug.cgi?id=175183
+
+        Reviewed by Brian Burg.
+
+        Split pending navigation maps into normal and eager, and use one or the other depending on the received page
+        load strategy. We need to keep different maps for every page load strategy because every command could use a
+        different strategy.
+
+        * UIProcess/Automation/WebAutomationSession.cpp:
+        (WebKit::WebAutomationSession::waitForNavigationToComplete): Extract page load strategy from parameter and pass
+        it to waitForNavigationToCompleteOnPage() and waitForNavigationToCompleteOnFrame().
+        (WebKit::WebAutomationSession::waitForNavigationToCompleteOnPage): Return early if page load strategy is
+        none. Otherwise at the pening callback to the normal or eager map depeding on the page load straegy.
+        (WebKit::WebAutomationSession::waitForNavigationToCompleteOnFrame): Ditto.
+        (WebKit::respondToPendingNavigationCallbacksWithTimeout): Helper to send pening navigation callback in case of
+        timeout failure.
+        (WebKit::WebAutomationSession::loadTimerFired): Call finishPendingNavigationsWithTimeoutFailure() with all the maps.
+        (WebKit::WebAutomationSession::navigateBrowsingContext): Extract page load strategy from parameter and pass it
+        to waitForNavigationToCompleteOnPage().
+        (WebKit::WebAutomationSession::goBackInBrowsingContext): Ditto.
+        (WebKit::WebAutomationSession::goForwardInBrowsingContext): Ditto.
+        (WebKit::WebAutomationSession::reloadBrowsingContext): Ditto.
+        (WebKit::WebAutomationSession::navigationOccurredForFrame): Use the normal maps.
+        (WebKit::WebAutomationSession::documentLoadedForFrame): Stop timeout timer and dispatch eager pending navigations.
+        * UIProcess/Automation/WebAutomationSession.h:
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::didFinishDocumentLoadForFrame): Notify the automation session.
+
+2017-08-05  Carlos Garcia Campos  <cgar...@igalia.com>
+
         WebDriver: use in-view center point for clicks instead of bounding box center point
         https://bugs.webkit.org/show_bug.cgi?id=174863
 

Modified: trunk/Source/WebKit/UIProcess/Automation/WebAutomationSession.cpp (220316 => 220317)


--- trunk/Source/WebKit/UIProcess/Automation/WebAutomationSession.cpp	2017-08-05 10:32:43 UTC (rev 220316)
+++ trunk/Source/WebKit/UIProcess/Automation/WebAutomationSession.cpp	2017-08-05 11:14:34 UTC (rev 220317)
@@ -54,6 +54,8 @@
 // ยง8. Sessions
 // https://www.w3.org/TR/webdriver/#dfn-session-page-load-timeout
 static const Seconds defaultPageLoadTimeout = 300_s;
+// https://www.w3.org/TR/webdriver/#dfn-page-loading-strategy
+static const Inspector::Protocol::Automation::PageLoadStrategy defaultPageLoadStrategy = Inspector::Protocol::Automation::PageLoadStrategy::Normal;
 
 WebAutomationSession::WebAutomationSession()
     : m_client(std::make_unique<API::AutomationSessionClient>())
@@ -385,6 +387,17 @@
 #endif
 }
 
+static std::optional<Inspector::Protocol::Automation::PageLoadStrategy> pageLoadStrategyFromStringParameter(const String* optionalPageLoadStrategyString)
+{
+    if (!optionalPageLoadStrategyString)
+        return defaultPageLoadStrategy;
+
+    auto parsedPageLoadStrategy = Inspector::Protocol::AutomationHelpers::parseEnumValueFromString<Inspector::Protocol::Automation::PageLoadStrategy>(*optionalPageLoadStrategyString);
+    if (!parsedPageLoadStrategy)
+        return std::nullopt;
+    return parsedPageLoadStrategy;
+}
+
 void WebAutomationSession::waitForNavigationToComplete(Inspector::ErrorString& errorString, const String& browsingContextHandle, const String* optionalFrameHandle, const String* optionalPageLoadStrategyString, const int* optionalPageLoadTimeout, Ref<WaitForNavigationToCompleteCallback>&& callback)
 {
     WebPageProxy* page = webPageProxyForHandle(browsingContextHandle);
@@ -391,10 +404,11 @@
     if (!page)
         FAIL_WITH_PREDEFINED_ERROR(WindowNotFound);
 
-    // FIXME: Implement page load strategy.
+    auto pageLoadStrategy = pageLoadStrategyFromStringParameter(optionalPageLoadStrategyString);
+    if (!pageLoadStrategy)
+        FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(InvalidParameter, "The parameter 'pageLoadStrategy' is invalid.");
+    auto pageLoadTimeout = optionalPageLoadTimeout ? Seconds::fromMilliseconds(*optionalPageLoadTimeout) : defaultPageLoadTimeout;
 
-    Seconds pageLoadTimeout = optionalPageLoadTimeout ? Seconds::fromMilliseconds(*optionalPageLoadTimeout) : defaultPageLoadTimeout;
-
     if (optionalFrameHandle && !optionalFrameHandle->isEmpty()) {
         std::optional<uint64_t> frameID = webFrameIDForHandle(*optionalFrameHandle);
         if (!frameID)
@@ -402,47 +416,69 @@
         WebFrameProxy* frame = page->process().webFrame(frameID.value());
         if (!frame)
             FAIL_WITH_PREDEFINED_ERROR(FrameNotFound);
-        waitForNavigationToCompleteOnFrame(*frame, pageLoadTimeout, WTFMove(callback));
+        waitForNavigationToCompleteOnFrame(*frame, pageLoadStrategy.value(), pageLoadTimeout, WTFMove(callback));
     } else
-        waitForNavigationToCompleteOnPage(*page, pageLoadTimeout, WTFMove(callback));
+        waitForNavigationToCompleteOnPage(*page, pageLoadStrategy.value(), pageLoadTimeout, WTFMove(callback));
 }
 
-void WebAutomationSession::waitForNavigationToCompleteOnPage(WebPageProxy& page, Seconds timeout, Ref<Inspector::BackendDispatcher::CallbackBase>&& callback)
+void WebAutomationSession::waitForNavigationToCompleteOnPage(WebPageProxy& page, Inspector::Protocol::Automation::PageLoadStrategy loadStrategy, Seconds timeout, Ref<Inspector::BackendDispatcher::CallbackBase>&& callback)
 {
     ASSERT(!m_loadTimer.isActive());
-    if (!page.pageLoadState().isLoading()) {
+    if (loadStrategy == Inspector::Protocol::Automation::PageLoadStrategy::None || !page.pageLoadState().isLoading()) {
         callback->sendSuccess(InspectorObject::create());
         return;
     }
 
     m_loadTimer.startOneShot(timeout);
-    m_pendingNavigationInBrowsingContextCallbacksPerPage.set(page.pageID(), WTFMove(callback));
+    switch (loadStrategy) {
+    case Inspector::Protocol::Automation::PageLoadStrategy::Normal:
+        m_pendingNormalNavigationInBrowsingContextCallbacksPerPage.set(page.pageID(), WTFMove(callback));
+        break;
+    case Inspector::Protocol::Automation::PageLoadStrategy::Eager:
+        m_pendingEagerNavigationInBrowsingContextCallbacksPerPage.set(page.pageID(), WTFMove(callback));
+        break;
+    case Inspector::Protocol::Automation::PageLoadStrategy::None:
+        ASSERT_NOT_REACHED();
+    }
 }
 
-void WebAutomationSession::waitForNavigationToCompleteOnFrame(WebFrameProxy& frame, Seconds timeout, Ref<Inspector::BackendDispatcher::CallbackBase>&& callback)
+void WebAutomationSession::waitForNavigationToCompleteOnFrame(WebFrameProxy& frame, Inspector::Protocol::Automation::PageLoadStrategy loadStrategy, Seconds timeout, Ref<Inspector::BackendDispatcher::CallbackBase>&& callback)
 {
     ASSERT(!m_loadTimer.isActive());
-    if (frame.frameLoadState().state() == FrameLoadState::State::Finished) {
+    if (loadStrategy == Inspector::Protocol::Automation::PageLoadStrategy::None || frame.frameLoadState().state() == FrameLoadState::State::Finished) {
         callback->sendSuccess(InspectorObject::create());
         return;
     }
 
     m_loadTimer.startOneShot(timeout);
-    m_pendingNavigationInBrowsingContextCallbacksPerFrame.set(frame.frameID(), WTFMove(callback));
+    switch (loadStrategy) {
+    case Inspector::Protocol::Automation::PageLoadStrategy::Normal:
+        m_pendingNormalNavigationInBrowsingContextCallbacksPerFrame.set(frame.frameID(), WTFMove(callback));
+        break;
+    case Inspector::Protocol::Automation::PageLoadStrategy::Eager:
+        m_pendingEagerNavigationInBrowsingContextCallbacksPerFrame.set(frame.frameID(), WTFMove(callback));
+        break;
+    case Inspector::Protocol::Automation::PageLoadStrategy::None:
+        ASSERT_NOT_REACHED();
+    }
 }
 
-void WebAutomationSession::loadTimerFired()
+static void respondToPendingNavigationCallbacksWithTimeout(HashMap<uint64_t, RefPtr<Inspector::BackendDispatcher::CallbackBase>>& map)
 {
-    for (auto frameID : m_pendingNavigationInBrowsingContextCallbacksPerFrame.keys()) {
-        auto callback = m_pendingNavigationInBrowsingContextCallbacksPerFrame.take(frameID);
+    for (auto id : map.keys()) {
+        auto callback = map.take(id);
         callback->sendFailure(STRING_FOR_PREDEFINED_ERROR_NAME(Timeout));
     }
-    for (auto pageID : m_pendingNavigationInBrowsingContextCallbacksPerPage.keys()) {
-        auto callback = m_pendingNavigationInBrowsingContextCallbacksPerPage.take(pageID);
-        callback->sendFailure(STRING_FOR_PREDEFINED_ERROR_NAME(Timeout));
-    }
 }
 
+void WebAutomationSession::loadTimerFired()
+{
+    respondToPendingNavigationCallbacksWithTimeout(m_pendingNormalNavigationInBrowsingContextCallbacksPerFrame);
+    respondToPendingNavigationCallbacksWithTimeout(m_pendingEagerNavigationInBrowsingContextCallbacksPerFrame);
+    respondToPendingNavigationCallbacksWithTimeout(m_pendingNormalNavigationInBrowsingContextCallbacksPerPage);
+    respondToPendingNavigationCallbacksWithTimeout(m_pendingEagerNavigationInBrowsingContextCallbacksPerPage);
+}
+
 void WebAutomationSession::navigateBrowsingContext(Inspector::ErrorString& errorString, const String& handle, const String& url, const String* optionalPageLoadStrategyString, const int* optionalPageLoadTimeout, Ref<NavigateBrowsingContextCallback>&& callback)
 {
     WebPageProxy* page = webPageProxyForHandle(handle);
@@ -449,10 +485,13 @@
     if (!page)
         FAIL_WITH_PREDEFINED_ERROR(WindowNotFound);
 
-    // FIXME: Implement page load strategy.
+    auto pageLoadStrategy = pageLoadStrategyFromStringParameter(optionalPageLoadStrategyString);
+    if (!pageLoadStrategy)
+        FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(InvalidParameter, "The parameter 'pageLoadStrategy' is invalid.");
+    auto pageLoadTimeout = optionalPageLoadTimeout ? Seconds::fromMilliseconds(*optionalPageLoadTimeout) : defaultPageLoadTimeout;
 
     page->loadRequest(WebCore::URL(WebCore::URL(), url));
-    waitForNavigationToCompleteOnPage(*page, optionalPageLoadTimeout ? Seconds::fromMilliseconds(*optionalPageLoadTimeout) : defaultPageLoadTimeout, WTFMove(callback));
+    waitForNavigationToCompleteOnPage(*page, pageLoadStrategy.value(), pageLoadTimeout, WTFMove(callback));
 }
 
 void WebAutomationSession::goBackInBrowsingContext(Inspector::ErrorString& errorString, const String& handle, const String* optionalPageLoadStrategyString, const int* optionalPageLoadTimeout, Ref<GoBackInBrowsingContextCallback>&& callback)
@@ -461,10 +500,13 @@
     if (!page)
         FAIL_WITH_PREDEFINED_ERROR(WindowNotFound);
 
-    // FIXME: Implement page load strategy.
+    auto pageLoadStrategy = pageLoadStrategyFromStringParameter(optionalPageLoadStrategyString);
+    if (!pageLoadStrategy)
+        FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(InvalidParameter, "The parameter 'pageLoadStrategy' is invalid.");
+    auto pageLoadTimeout = optionalPageLoadTimeout ? Seconds::fromMilliseconds(*optionalPageLoadTimeout) : defaultPageLoadTimeout;
 
     page->goBack();
-    waitForNavigationToCompleteOnPage(*page, optionalPageLoadTimeout ? Seconds::fromMilliseconds(*optionalPageLoadTimeout) : defaultPageLoadTimeout, WTFMove(callback));
+    waitForNavigationToCompleteOnPage(*page, pageLoadStrategy.value(), pageLoadTimeout, WTFMove(callback));
 }
 
 void WebAutomationSession::goForwardInBrowsingContext(Inspector::ErrorString& errorString, const String& handle, const String* optionalPageLoadStrategyString, const int* optionalPageLoadTimeout, Ref<GoForwardInBrowsingContextCallback>&& callback)
@@ -473,10 +515,13 @@
     if (!page)
         FAIL_WITH_PREDEFINED_ERROR(WindowNotFound);
 
-    // FIXME: Implement page load strategy.
+    auto pageLoadStrategy = pageLoadStrategyFromStringParameter(optionalPageLoadStrategyString);
+    if (!pageLoadStrategy)
+        FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(InvalidParameter, "The parameter 'pageLoadStrategy' is invalid.");
+    auto pageLoadTimeout = optionalPageLoadTimeout ? Seconds::fromMilliseconds(*optionalPageLoadTimeout) : defaultPageLoadTimeout;
 
     page->goForward();
-    waitForNavigationToCompleteOnPage(*page, optionalPageLoadTimeout ? Seconds::fromMilliseconds(*optionalPageLoadTimeout) : defaultPageLoadTimeout, WTFMove(callback));
+    waitForNavigationToCompleteOnPage(*page, pageLoadStrategy.value(), pageLoadTimeout, WTFMove(callback));
 }
 
 void WebAutomationSession::reloadBrowsingContext(Inspector::ErrorString& errorString, const String& handle, const String* optionalPageLoadStrategyString, const int* optionalPageLoadTimeout, Ref<ReloadBrowsingContextCallback>&& callback)
@@ -485,10 +530,13 @@
     if (!page)
         FAIL_WITH_PREDEFINED_ERROR(WindowNotFound);
 
-    // FIXME: Implement page load strategy.
+    auto pageLoadStrategy = pageLoadStrategyFromStringParameter(optionalPageLoadStrategyString);
+    if (!pageLoadStrategy)
+        FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(InvalidParameter, "The parameter 'pageLoadStrategy' is invalid.");
+    auto pageLoadTimeout = optionalPageLoadTimeout ? Seconds::fromMilliseconds(*optionalPageLoadTimeout) : defaultPageLoadTimeout;
 
     page->reload({ });
-    waitForNavigationToCompleteOnPage(*page, optionalPageLoadTimeout ? Seconds::fromMilliseconds(*optionalPageLoadTimeout) : defaultPageLoadTimeout, WTFMove(callback));
+    waitForNavigationToCompleteOnPage(*page, pageLoadStrategy.value(), pageLoadTimeout, WTFMove(callback));
 }
 
 void WebAutomationSession::navigationOccurredForFrame(const WebFrameProxy& frame)
@@ -497,13 +545,13 @@
         // New page loaded, clear frame handles previously cached.
         m_handleWebFrameMap.clear();
         m_webFrameHandleMap.clear();
-        if (auto callback = m_pendingNavigationInBrowsingContextCallbacksPerPage.take(frame.page()->pageID())) {
+        if (auto callback = m_pendingNormalNavigationInBrowsingContextCallbacksPerPage.take(frame.page()->pageID())) {
             m_loadTimer.stop();
             callback->sendSuccess(InspectorObject::create());
         }
         m_domainNotifier->browsingContextCleared(handleForWebPageProxy(*frame.page()));
     } else {
-        if (auto callback = m_pendingNavigationInBrowsingContextCallbacksPerFrame.take(frame.frameID())) {
+        if (auto callback = m_pendingNormalNavigationInBrowsingContextCallbacksPerFrame.take(frame.frameID())) {
             m_loadTimer.stop();
             callback->sendSuccess(InspectorObject::create());
         }
@@ -510,6 +558,21 @@
     }
 }
 
+void WebAutomationSession::documentLoadedForFrame(const WebFrameProxy& frame)
+{
+    if (frame.isMainFrame()) {
+        if (auto callback = m_pendingEagerNavigationInBrowsingContextCallbacksPerPage.take(frame.page()->pageID())) {
+            m_loadTimer.stop();
+            callback->sendSuccess(InspectorObject::create());
+        }
+    } else {
+        if (auto callback = m_pendingEagerNavigationInBrowsingContextCallbacksPerFrame.take(frame.frameID())) {
+            m_loadTimer.stop();
+            callback->sendSuccess(InspectorObject::create());
+        }
+    }
+}
+
 void WebAutomationSession::inspectorFrontendLoaded(const WebPageProxy& page)
 {
     if (auto callback = m_pendingInspectorCallbacksPerPage.take(page.pageID()))

Modified: trunk/Source/WebKit/UIProcess/Automation/WebAutomationSession.h (220316 => 220317)


--- trunk/Source/WebKit/UIProcess/Automation/WebAutomationSession.h	2017-08-05 10:32:43 UTC (rev 220316)
+++ trunk/Source/WebKit/UIProcess/Automation/WebAutomationSession.h	2017-08-05 11:14:34 UTC (rev 220317)
@@ -94,6 +94,7 @@
     void setProcessPool(WebProcessPool*);
 
     void navigationOccurredForFrame(const WebFrameProxy&);
+    void documentLoadedForFrame(const WebFrameProxy&);
     void inspectorFrontendLoaded(const WebPageProxy&);
     void keyboardEventsFlushedForPage(const WebPageProxy&);
     void willClosePage(const WebPageProxy&);
@@ -163,8 +164,8 @@
     String handleForWebFrameID(uint64_t frameID);
     String handleForWebFrameProxy(const WebFrameProxy&);
 
-    void waitForNavigationToCompleteOnPage(WebPageProxy&, Seconds, Ref<Inspector::BackendDispatcher::CallbackBase>&&);
-    void waitForNavigationToCompleteOnFrame(WebFrameProxy&, Seconds, Ref<Inspector::BackendDispatcher::CallbackBase>&&);
+    void waitForNavigationToCompleteOnPage(WebPageProxy&, Inspector::Protocol::Automation::PageLoadStrategy, Seconds, Ref<Inspector::BackendDispatcher::CallbackBase>&&);
+    void waitForNavigationToCompleteOnFrame(WebFrameProxy&, Inspector::Protocol::Automation::PageLoadStrategy, Seconds, Ref<Inspector::BackendDispatcher::CallbackBase>&&);
     void loadTimerFired();
 
     // Implemented in generated WebAutomationSessionMessageReceiver.cpp.
@@ -212,8 +213,10 @@
     HashMap<uint64_t, String> m_webFrameHandleMap;
     HashMap<String, uint64_t> m_handleWebFrameMap;
 
-    HashMap<uint64_t, RefPtr<Inspector::BackendDispatcher::CallbackBase>> m_pendingNavigationInBrowsingContextCallbacksPerPage;
-    HashMap<uint64_t, RefPtr<Inspector::BackendDispatcher::CallbackBase>> m_pendingNavigationInBrowsingContextCallbacksPerFrame;
+    HashMap<uint64_t, RefPtr<Inspector::BackendDispatcher::CallbackBase>> m_pendingNormalNavigationInBrowsingContextCallbacksPerPage;
+    HashMap<uint64_t, RefPtr<Inspector::BackendDispatcher::CallbackBase>> m_pendingEagerNavigationInBrowsingContextCallbacksPerPage;
+    HashMap<uint64_t, RefPtr<Inspector::BackendDispatcher::CallbackBase>> m_pendingNormalNavigationInBrowsingContextCallbacksPerFrame;
+    HashMap<uint64_t, RefPtr<Inspector::BackendDispatcher::CallbackBase>> m_pendingEagerNavigationInBrowsingContextCallbacksPerFrame;
     HashMap<uint64_t, RefPtr<Inspector::BackendDispatcher::CallbackBase>> m_pendingInspectorCallbacksPerPage;
     HashMap<uint64_t, RefPtr<Inspector::BackendDispatcher::CallbackBase>> m_pendingKeyboardEventsFlushedCallbacksPerPage;
 

Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.cpp (220316 => 220317)


--- trunk/Source/WebKit/UIProcess/WebPageProxy.cpp	2017-08-05 10:32:43 UTC (rev 220316)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.cpp	2017-08-05 11:14:34 UTC (rev 220317)
@@ -3369,6 +3369,11 @@
     WebFrameProxy* frame = m_process->webFrame(frameID);
     MESSAGE_CHECK(frame);
 
+    if (m_controlledByAutomation) {
+        if (auto* automationSession = process().processPool().automationSession())
+            automationSession->documentLoadedForFrame(*frame);
+    }
+
     // FIXME: We should message check that navigationID is not zero here, but it's currently zero for some navigations through the page cache.
     RefPtr<API::Navigation> navigation;
     if (frame->isMainFrame() && navigationID)
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to