WebDriver: deserializeTimeouts() shouldn't reject double timeout values
authorzandobersek@gmail.com <zandobersek@gmail.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 10 Jan 2018 16:16:22 +0000 (16:16 +0000)
committerzandobersek@gmail.com <zandobersek@gmail.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 10 Jan 2018 16:16:22 +0000 (16:16 +0000)
https://bugs.webkit.org/show_bug.cgi?id=181473

Reviewed by Carlos Garcia Campos.

With these changes, the following tests are fixed:
    imported/selenium/py/test/selenium/webdriver/common/executing_async_javascript_tests.py::testShouldTimeoutIfScriptDoesNotInvokeCallbackWithLongTimeout
    imported/selenium/py/test/selenium/webdriver/common/executing_async_javascript_tests.py::testShouldDetectPageLoadsWhileWaitingOnAnAsyncScriptAndReturnAnError
    imported/selenium/py/test/selenium/webdriver/common/executing_async_javascript_tests.py::testShouldBeAbleToExecuteAsynchronousScripts
    imported/selenium/py/test/selenium/webdriver/common/implicit_waits_tests.py::testShouldImplicitlyWaitForASingleElement
    imported/selenium/py/test/selenium/webdriver/common/implicit_waits_tests.py::testShouldStillFailToFindAnElementWhenImplicitWaitsAreEnabled
    imported/selenium/py/test/selenium/webdriver/common/implicit_waits_tests.py::testShouldReturnAfterFirstAttemptToFindOneAfterDisablingImplicitWaits
    imported/selenium/py/test/selenium/webdriver/common/implicit_waits_tests.py::testShouldImplicitlyWaitUntilAtLeastOneElementIsFoundWhenSearchingForMany
    imported/selenium/py/test/selenium/webdriver/common/implicit_waits_tests.py::testShouldStillFailToFindAnElemenstWhenImplicitWaitsAreEnabled
    imported/selenium/py/test/selenium/webdriver/common/implicit_waits_tests.py::testShouldReturnAfterFirstAttemptToFindManyAfterDisablingImplicitWaits
    imported/selenium/py/test/selenium/webdriver/common/page_load_timeout_tests.py::testShouldTimeoutOnPageLoadTakingTooLong
    imported/selenium/py/test/selenium/webdriver/common/page_load_timeout_tests.py::testShouldTimeoutOnPageLoadTakingTooLong
    imported/selenium/py/test/selenium/webdriver/common/webdriverwait_tests.py::testShouldWaitOnlyAsLongAsTimeoutSpecifiedWhenImplicitWaitsAreSet

The following two tests regress, and will be looked into separately:
    imported/w3c/webdriver/tests/sessions/new_session/merge.py::test_merge_invalid
    imported/w3c/webdriver/tests/sessions/new_session/merge.py::test_merge_invalid

* WebDriverService.cpp:
(WebDriver::integerValue): Helper function that retrieves an integer value
from a given JSON::Value object, if possible.
(WebDriver::deserializeTimeouts): Timeout JSON value has to be converted to
an integer, which is allowed if the value is of either Integer or Double type.
Helper integerValue() function retrieves the integer value, in addition to
ensuring that possible double value that we convert to an integer is already
in integer form to begin with.

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

Source/WebDriver/ChangeLog
Source/WebDriver/WebDriverService.cpp

index e814fad3f778756b54961642e78022507f1ebb19..5c459ffcfd392fd67ac193c23f8c48cdde6bb743 100644 (file)
@@ -1,3 +1,37 @@
+2018-01-10  Zan Dobersek  <zdobersek@igalia.com>
+
+        WebDriver: deserializeTimeouts() shouldn't reject double timeout values
+        https://bugs.webkit.org/show_bug.cgi?id=181473
+
+        Reviewed by Carlos Garcia Campos.
+
+        With these changes, the following tests are fixed:
+            imported/selenium/py/test/selenium/webdriver/common/executing_async_javascript_tests.py::testShouldTimeoutIfScriptDoesNotInvokeCallbackWithLongTimeout
+            imported/selenium/py/test/selenium/webdriver/common/executing_async_javascript_tests.py::testShouldDetectPageLoadsWhileWaitingOnAnAsyncScriptAndReturnAnError
+            imported/selenium/py/test/selenium/webdriver/common/executing_async_javascript_tests.py::testShouldBeAbleToExecuteAsynchronousScripts
+            imported/selenium/py/test/selenium/webdriver/common/implicit_waits_tests.py::testShouldImplicitlyWaitForASingleElement
+            imported/selenium/py/test/selenium/webdriver/common/implicit_waits_tests.py::testShouldStillFailToFindAnElementWhenImplicitWaitsAreEnabled
+            imported/selenium/py/test/selenium/webdriver/common/implicit_waits_tests.py::testShouldReturnAfterFirstAttemptToFindOneAfterDisablingImplicitWaits
+            imported/selenium/py/test/selenium/webdriver/common/implicit_waits_tests.py::testShouldImplicitlyWaitUntilAtLeastOneElementIsFoundWhenSearchingForMany
+            imported/selenium/py/test/selenium/webdriver/common/implicit_waits_tests.py::testShouldStillFailToFindAnElemenstWhenImplicitWaitsAreEnabled
+            imported/selenium/py/test/selenium/webdriver/common/implicit_waits_tests.py::testShouldReturnAfterFirstAttemptToFindManyAfterDisablingImplicitWaits
+            imported/selenium/py/test/selenium/webdriver/common/page_load_timeout_tests.py::testShouldTimeoutOnPageLoadTakingTooLong
+            imported/selenium/py/test/selenium/webdriver/common/page_load_timeout_tests.py::testShouldTimeoutOnPageLoadTakingTooLong
+            imported/selenium/py/test/selenium/webdriver/common/webdriverwait_tests.py::testShouldWaitOnlyAsLongAsTimeoutSpecifiedWhenImplicitWaitsAreSet
+
+        The following two tests regress, and will be looked into separately:
+            imported/w3c/webdriver/tests/sessions/new_session/merge.py::test_merge_invalid
+            imported/w3c/webdriver/tests/sessions/new_session/merge.py::test_merge_invalid
+
+        * WebDriverService.cpp:
+        (WebDriver::integerValue): Helper function that retrieves an integer value
+        from a given JSON::Value object, if possible.
+        (WebDriver::deserializeTimeouts): Timeout JSON value has to be converted to
+        an integer, which is allowed if the value is of either Integer or Double type.
+        Helper integerValue() function retrieves the integer value, in addition to
+        ensuring that possible double value that we convert to an integer is already
+        in integer form to begin with.
+
 2017-12-15  Carlos Garcia Campos  <cgarcia@igalia.com>
 
         WebDriver: add support for accept/dismiss and notify unhandled prompt behavior
index 63118cb12e7243ff27050ec925aacf24339d6ade..dc411bf42ad541ecaf425c0c341b2e23581568a6 100644 (file)
@@ -270,6 +270,22 @@ void WebDriverService::sendResponse(Function<void (HTTPRequestHandler::Response&
     replyHandler({ result.httpStatusCode(), responseObject->toJSONString().utf8(), ASCIILiteral("application/json; charset=utf-8") });
 }
 
+static bool integerValue(JSON::Value& value, int& output)
+{
+    // Bail if an integer value cannot be retrieved.
+    if (!value.asInteger(output))
+        return false;
+
+    // If the contained value is a double, bail in case it doesn't match the integer
+    // value, i.e. if the double value was not originally in integer form.
+    // https://w3c.github.io/webdriver/webdriver-spec.html#dfn-integer
+    double doubleValue;
+    if (value.asDouble(doubleValue) && doubleValue != output)
+        return false;
+
+    return true;
+}
+
 static std::optional<Timeouts> deserializeTimeouts(JSON::Object& timeoutsObject)
 {
     // ยง8.5 Set Timeouts.
@@ -281,7 +297,7 @@ static std::optional<Timeouts> deserializeTimeouts(JSON::Object& timeoutsObject)
             continue;
 
         int timeoutMS;
-        if (it->value->type() != JSON::Value::Type::Integer || !it->value->asInteger(timeoutMS) || timeoutMS < 0 || timeoutMS > INT_MAX)
+        if (!integerValue(*it->value, timeoutMS) || timeoutMS < 0 || timeoutMS > INT_MAX)
             return std::nullopt;
 
         if (it->key == "script")