WebDriver: implement get timeouts command
authorcarlosgc@webkit.org <carlosgc@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 11 Jan 2018 10:00:31 +0000 (10:00 +0000)
committercarlosgc@webkit.org <carlosgc@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 11 Jan 2018 10:00:31 +0000 (10:00 +0000)
https://bugs.webkit.org/show_bug.cgi?id=181524

Reviewed by Žan Doberšek.

8.4 Get Timeouts
https://w3c.github.io/webdriver/webdriver-spec.html#get-timeouts

Also simplify the way timeouts are handled in Session. Stop using Timeouts struct, because once the session is
created the timeouts are no longer optional, they have a default value. Use individual members instead that are
initialized to their default values on construction and only overriden by capabilities or set timeouts command.

Fixes: imported/w3c/webdriver/tests/sessions/get_timeouts.py::test_get_timeouts
       imported/w3c/webdriver/tests/sessions/get_timeouts.py::test_get_default_timeouts
       imported/w3c/webdriver/tests/sessions/get_timeouts.py::test_get_new_timeouts

* Session.cpp:
(WebDriver::Session::Session):
(WebDriver::Session::getTimeouts):
(WebDriver::Session::setTimeouts):
(WebDriver::Session::go):
(WebDriver::Session::back):
(WebDriver::Session::forward):
(WebDriver::Session::refresh):
(WebDriver::Session::findElements):
(WebDriver::Session::waitForNavigationToComplete):
(WebDriver::Session::executeScript):
* Session.h:
* WebDriverService.cpp:
(WebDriver::WebDriverService::getTimeouts):
* WebDriverService.h:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@226770 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebDriver/ChangeLog
Source/WebDriver/Session.cpp
Source/WebDriver/Session.h
Source/WebDriver/WebDriverService.cpp
Source/WebDriver/WebDriverService.h

index 5c459ff..a31da53 100644 (file)
@@ -1,3 +1,37 @@
+2018-01-11  Carlos Garcia Campos  <cgarcia@igalia.com>
+
+        WebDriver: implement get timeouts command
+        https://bugs.webkit.org/show_bug.cgi?id=181524
+
+        Reviewed by Žan Doberšek.
+
+        8.4 Get Timeouts
+        https://w3c.github.io/webdriver/webdriver-spec.html#get-timeouts
+
+        Also simplify the way timeouts are handled in Session. Stop using Timeouts struct, because once the session is
+        created the timeouts are no longer optional, they have a default value. Use individual members instead that are
+        initialized to their default values on construction and only overriden by capabilities or set timeouts command.
+
+        Fixes: imported/w3c/webdriver/tests/sessions/get_timeouts.py::test_get_timeouts
+               imported/w3c/webdriver/tests/sessions/get_timeouts.py::test_get_default_timeouts
+               imported/w3c/webdriver/tests/sessions/get_timeouts.py::test_get_new_timeouts
+
+        * Session.cpp:
+        (WebDriver::Session::Session):
+        (WebDriver::Session::getTimeouts):
+        (WebDriver::Session::setTimeouts):
+        (WebDriver::Session::go):
+        (WebDriver::Session::back):
+        (WebDriver::Session::forward):
+        (WebDriver::Session::refresh):
+        (WebDriver::Session::findElements):
+        (WebDriver::Session::waitForNavigationToComplete):
+        (WebDriver::Session::executeScript):
+        * Session.h:
+        * WebDriverService.cpp:
+        (WebDriver::WebDriverService::getTimeouts):
+        * WebDriverService.h:
+
 2018-01-10  Zan Dobersek  <zdobersek@igalia.com>
 
         WebDriver: deserializeTimeouts() shouldn't reject double timeout values
index bb69e96..3f331cb 100644 (file)
@@ -39,9 +39,19 @@ namespace WebDriver {
 // https://www.w3.org/TR/webdriver/#elements
 static const String webElementIdentifier = ASCIILiteral("element-6066-11e4-a52e-4f735466cecf");
 
+// https://w3c.github.io/webdriver/webdriver-spec.html#dfn-session-script-timeout
+static const Seconds defaultScriptTimeout = 30_s;
+// https://w3c.github.io/webdriver/webdriver-spec.html#dfn-session-page-load-timeout
+static const Seconds defaultPageLoadTimeout = 300_s;
+// https://w3c.github.io/webdriver/webdriver-spec.html#dfn-session-implicit-wait-timeout
+static const Seconds defaultImplicitWaitTimeout = 0_s;
+
 Session::Session(std::unique_ptr<SessionHost>&& host)
     : m_host(WTFMove(host))
     , m_id(createCanonicalUUIDString())
+    , m_scriptTimeout(defaultScriptTimeout)
+    , m_pageLoadTimeout(defaultPageLoadTimeout)
+    , m_implicitWaitTimeout(defaultImplicitWaitTimeout)
 {
 }
 
@@ -97,14 +107,23 @@ void Session::close(Function<void (CommandResult&&)>&& completionHandler)
     });
 }
 
+void Session::getTimeouts(Function<void (CommandResult&&)>&& completionHandler)
+{
+    RefPtr<JSON::Object> parameters = JSON::Object::create();
+    parameters->setInteger(ASCIILiteral("script"), m_scriptTimeout.millisecondsAs<int>());
+    parameters->setInteger(ASCIILiteral("pageLoad"), m_pageLoadTimeout.millisecondsAs<int>());
+    parameters->setInteger(ASCIILiteral("implicit"), m_implicitWaitTimeout.millisecondsAs<int>());
+    completionHandler(CommandResult::success(WTFMove(parameters)));
+}
+
 void Session::setTimeouts(const Timeouts& timeouts, Function<void (CommandResult&&)>&& completionHandler)
 {
     if (timeouts.script)
-        m_timeouts.script = timeouts.script;
+        m_scriptTimeout = timeouts.script.value();
     if (timeouts.pageLoad)
-        m_timeouts.pageLoad = timeouts.pageLoad;
+        m_pageLoadTimeout = timeouts.pageLoad.value();
     if (timeouts.implicit)
-        m_timeouts.implicit = timeouts.implicit;
+        m_implicitWaitTimeout = timeouts.implicit.value();
     completionHandler(CommandResult::success());
 }
 
@@ -270,8 +289,7 @@ void Session::go(const String& url, Function<void (CommandResult&&)>&& completio
         RefPtr<JSON::Object> parameters = JSON::Object::create();
         parameters->setString(ASCIILiteral("handle"), m_toplevelBrowsingContext.value());
         parameters->setString(ASCIILiteral("url"), url);
-        if (m_timeouts.pageLoad)
-            parameters->setInteger(ASCIILiteral("pageLoadTimeout"), m_timeouts.pageLoad.value().millisecondsAs<int>());
+        parameters->setInteger(ASCIILiteral("pageLoadTimeout"), m_pageLoadTimeout.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) {
@@ -334,8 +352,7 @@ void Session::back(Function<void (CommandResult&&)>&& completionHandler)
         }
         RefPtr<JSON::Object> parameters = JSON::Object::create();
         parameters->setString(ASCIILiteral("handle"), m_toplevelBrowsingContext.value());
-        if (m_timeouts.pageLoad)
-            parameters->setInteger(ASCIILiteral("pageLoadTimeout"), m_timeouts.pageLoad.value().millisecondsAs<int>());
+        parameters->setInteger(ASCIILiteral("pageLoadTimeout"), m_pageLoadTimeout.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) {
@@ -363,8 +380,7 @@ void Session::forward(Function<void (CommandResult&&)>&& completionHandler)
         }
         RefPtr<JSON::Object> parameters = JSON::Object::create();
         parameters->setString(ASCIILiteral("handle"), m_toplevelBrowsingContext.value());
-        if (m_timeouts.pageLoad)
-            parameters->setInteger(ASCIILiteral("pageLoadTimeout"), m_timeouts.pageLoad.value().millisecondsAs<int>());
+        parameters->setInteger(ASCIILiteral("pageLoadTimeout"), m_pageLoadTimeout.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) {
@@ -392,8 +408,7 @@ void Session::refresh(Function<void (CommandResult&&)>&& completionHandler)
         }
         RefPtr<JSON::Object> parameters = JSON::Object::create();
         parameters->setString(ASCIILiteral("handle"), m_toplevelBrowsingContext.value());
-        if (m_timeouts.pageLoad)
-            parameters->setInteger(ASCIILiteral("pageLoadTimeout"), m_timeouts.pageLoad.value().millisecondsAs<int>());
+        parameters->setInteger(ASCIILiteral("pageLoadTimeout"), m_pageLoadTimeout.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) {
@@ -915,7 +930,6 @@ void Session::findElements(const String& strategy, const String& selector, FindE
         return;
     }
 
-    auto implicitWait = m_timeouts.implicit.value_or(0_s);
     RefPtr<JSON::Array> arguments = JSON::Array::create();
     arguments->pushString(JSON::Value::create(strategy)->toJSONString());
     if (rootElementID.isEmpty())
@@ -924,7 +938,7 @@ void Session::findElements(const String& strategy, const String& selector, FindE
         arguments->pushString(createElement(rootElementID)->toJSONString());
     arguments->pushString(JSON::Value::create(selector)->toJSONString());
     arguments->pushString(JSON::Value::create(mode == FindElementsMode::Single)->toJSONString());
-    arguments->pushString(JSON::Value::create(implicitWait.milliseconds())->toJSONString());
+    arguments->pushString(JSON::Value::create(m_implicitWaitTimeout.milliseconds())->toJSONString());
 
     RefPtr<JSON::Object> parameters = JSON::Object::create();
     parameters->setString(ASCIILiteral("browsingContextHandle"), m_toplevelBrowsingContext.value());
@@ -934,8 +948,8 @@ void Session::findElements(const String& strategy, const String& selector, FindE
     parameters->setArray(ASCIILiteral("arguments"), WTFMove(arguments));
     parameters->setBoolean(ASCIILiteral("expectsImplicitCallbackArgument"), true);
     // If there's an implicit wait, use one second more as callback timeout.
-    if (implicitWait)
-        parameters->setInteger(ASCIILiteral("callbackTimeout"), Seconds(implicitWait + 1_s).millisecondsAs<int>());
+    if (m_implicitWaitTimeout)
+        parameters->setInteger(ASCIILiteral("callbackTimeout"), Seconds(m_implicitWaitTimeout + 1_s).millisecondsAs<int>());
 
     m_host->sendCommandToBackend(ASCIILiteral("evaluateJavaScriptFunction"), WTFMove(parameters), [this, protectedThis = makeRef(*this), mode, completionHandler = WTFMove(completionHandler)](SessionHost::CommandResponse&& response) {
         if (response.isError || !response.responseObject) {
@@ -1360,8 +1374,7 @@ void Session::waitForNavigationToComplete(Function<void (CommandResult&&)>&& com
     parameters->setString(ASCIILiteral("browsingContextHandle"), m_toplevelBrowsingContext.value());
     if (m_currentBrowsingContext)
         parameters->setString(ASCIILiteral("frameHandle"), m_currentBrowsingContext.value());
-    if (m_timeouts.pageLoad)
-        parameters->setInteger(ASCIILiteral("pageLoadTimeout"), m_timeouts.pageLoad.value().millisecondsAs<int>());
+    parameters->setInteger(ASCIILiteral("pageLoadTimeout"), m_pageLoadTimeout.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) {
@@ -1725,8 +1738,8 @@ void Session::executeScript(const String& script, RefPtr<JSON::Array>&& argument
         parameters->setArray(ASCIILiteral("arguments"), WTFMove(arguments));
         if (mode == ExecuteScriptMode::Async) {
             parameters->setBoolean(ASCIILiteral("expectsImplicitCallbackArgument"), true);
-            if (m_timeouts.script)
-                parameters->setInteger(ASCIILiteral("callbackTimeout"), m_timeouts.script.value().millisecondsAs<int>());
+            if (m_scriptTimeout)
+                parameters->setInteger(ASCIILiteral("callbackTimeout"), m_scriptTimeout.millisecondsAs<int>());
         }
         m_host->sendCommandToBackend(ASCIILiteral("evaluateJavaScriptFunction"), WTFMove(parameters), [this, protectedThis = makeRef(*this), completionHandler = WTFMove(completionHandler)](SessionHost::CommandResponse&& response) mutable {
             if (response.isError || !response.responseObject) {
index 9ebdaf2..5a8a84e 100644 (file)
@@ -178,8 +178,10 @@ private:
     void performKeyboardInteractions(Vector<KeyboardInteraction>&&, Function<void (CommandResult&&)>&&);
 
     std::unique_ptr<SessionHost> m_host;
-    Timeouts m_timeouts;
     String m_id;
+    Seconds m_scriptTimeout;
+    Seconds m_pageLoadTimeout;
+    Seconds m_implicitWaitTimeout;
     std::optional<String> m_toplevelBrowsingContext;
     std::optional<String> m_currentBrowsingContext;
 };
index dc411bf..6553c70 100644 (file)
@@ -101,6 +101,7 @@ const WebDriverService::Command WebDriverService::s_commands[] = {
     { HTTPMethod::Post, "/session", &WebDriverService::newSession },
     { HTTPMethod::Delete, "/session/$sessionId", &WebDriverService::deleteSession },
     { HTTPMethod::Get, "/status", &WebDriverService::status },
+    { HTTPMethod::Get, "/session/$sessionId/timeouts", &WebDriverService::getTimeouts },
     { HTTPMethod::Post, "/session/$sessionId/timeouts", &WebDriverService::setTimeouts },
 
     { HTTPMethod::Post, "/session/$sessionId/url", &WebDriverService::go },
@@ -719,6 +720,16 @@ void WebDriverService::status(RefPtr<JSON::Object>&&, Function<void (CommandResu
     completionHandler(CommandResult::success(WTFMove(body)));
 }
 
+void WebDriverService::getTimeouts(RefPtr<JSON::Object>&& parameters, Function<void (CommandResult&&)>&& completionHandler)
+{
+    // §8.4 Get Timeouts.
+    // https://w3c.github.io/webdriver/webdriver-spec.html#get-timeouts
+    if (!findSessionOrCompleteWithError(*parameters, completionHandler))
+        return;
+
+    m_session->getTimeouts(WTFMove(completionHandler));
+}
+
 void WebDriverService::setTimeouts(RefPtr<JSON::Object>&& parameters, Function<void (CommandResult&&)>&& completionHandler)
 {
     // §8.5 Set Timeouts.
index e842172..d7c6a91 100644 (file)
@@ -63,6 +63,7 @@ private:
     void newSession(RefPtr<JSON::Object>&&, Function<void (CommandResult&&)>&&);
     void deleteSession(RefPtr<JSON::Object>&&, Function<void (CommandResult&&)>&&);
     void status(RefPtr<JSON::Object>&&, Function<void (CommandResult&&)>&&);
+    void getTimeouts(RefPtr<JSON::Object>&&, Function<void (CommandResult&&)>&&);
     void setTimeouts(RefPtr<JSON::Object>&&, Function<void (CommandResult&&)>&&);
     void go(RefPtr<JSON::Object>&&, Function<void (CommandResult&&)>&&);
     void getCurrentURL(RefPtr<JSON::Object>&&, Function<void (CommandResult&&)>&&);