TimeoutsConfiguration.cpp 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. /*
  2. * Copyright (c) 2022, Linus Groh <linusg@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include <AK/JsonObject.h>
  7. #include <LibWeb/WebDriver/TimeoutsConfiguration.h>
  8. namespace Web::WebDriver {
  9. // https://w3c.github.io/webdriver/#dfn-timeouts-object
  10. JsonObject timeouts_object(TimeoutsConfiguration const& timeouts)
  11. {
  12. // The timeouts object for a timeouts configuration timeouts is an object initialized with the following properties:
  13. auto timeouts_object = JsonObject {};
  14. // "script"
  15. // timeouts' script timeout value, if set, or its default value.
  16. if (timeouts.script_timeout.has_value())
  17. timeouts_object.set("script", *timeouts.script_timeout);
  18. else
  19. timeouts_object.set("script", JsonValue {});
  20. // "pageLoad"
  21. // timeouts' page load timeout’s value, if set, or its default value.
  22. timeouts_object.set("pageLoad", timeouts.page_load_timeout);
  23. // "implicit"
  24. // timeouts' implicit wait timeout’s value, if set, or its default value.
  25. timeouts_object.set("implicit", timeouts.implicit_wait_timeout);
  26. return timeouts_object;
  27. }
  28. // FIXME: Update this to match the newest spec: https://www.w3.org/TR/webdriver2/#dfn-deserialize-as-timeouts-configuration
  29. // https://w3c.github.io/webdriver/#ref-for-dfn-json-deserialize-3
  30. ErrorOr<TimeoutsConfiguration, Error> json_deserialize_as_a_timeouts_configuration(JsonValue const& value)
  31. {
  32. constexpr i64 max_safe_integer = 9007199254740991;
  33. // 1. Let timeouts be a new timeouts configuration.
  34. auto timeouts = TimeoutsConfiguration {};
  35. // 2. If value is not a JSON Object, return error with error code invalid argument.
  36. if (!value.is_object())
  37. return Error::from_code(ErrorCode::InvalidArgument, "Payload is not a JSON object");
  38. // 3. If value has a property with the key "script":
  39. if (value.as_object().has("script"sv)) {
  40. // 1. Let script duration be the value of property "script".
  41. auto script_duration = value.as_object().get("script"sv);
  42. // 2. If script duration is a number and less than 0 or greater than maximum safe integer, or it is not null, return error with error code invalid argument.
  43. Optional<u64> script_timeout;
  44. if (script_duration.has_value()) {
  45. bool is_valid;
  46. if (auto duration = script_duration->get_double_with_precision_loss(); duration.has_value()) {
  47. is_valid = *duration >= 0 && *duration <= max_safe_integer;
  48. // FIXME: script_timeout should be double.
  49. script_timeout = static_cast<u64>(*duration);
  50. } else if (script_duration->is_null()) {
  51. is_valid = true;
  52. } else {
  53. is_valid = false;
  54. }
  55. if (!is_valid)
  56. return Error::from_code(ErrorCode::InvalidArgument, "Invalid script duration");
  57. }
  58. // 3. Set timeouts’s script timeout to script duration.
  59. timeouts.script_timeout = script_timeout;
  60. }
  61. // 4. If value has a property with the key "pageLoad":
  62. if (value.as_object().has("pageLoad"sv)) {
  63. // 1. Let page load duration be the value of property "pageLoad".
  64. // NOTE: We parse this as a double due to WPT sending values such as `{"pageLoad": 300.00000000000006}`
  65. auto page_load_duration = value.as_object().get_double_with_precision_loss("pageLoad"sv);
  66. // 2. If page load duration is less than 0 or greater than maximum safe integer, return error with error code invalid argument.
  67. if (!page_load_duration.has_value() || *page_load_duration < 0 || *page_load_duration > max_safe_integer)
  68. return Error::from_code(ErrorCode::InvalidArgument, "Invalid page load duration");
  69. // 3. Set timeouts’s page load timeout to page load duration.
  70. timeouts.page_load_timeout = static_cast<u64>(*page_load_duration);
  71. }
  72. // 5. If value has a property with the key "implicit":
  73. if (value.as_object().has("implicit"sv)) {
  74. // 1. Let implicit duration be the value of property "implicit".
  75. auto implicit_duration = value.as_object().get_i64("implicit"sv);
  76. // 2. If implicit duration is less than 0 or greater than maximum safe integer, return error with error code invalid argument.
  77. if (!implicit_duration.has_value() || *implicit_duration < 0 || *implicit_duration > max_safe_integer)
  78. return Error::from_code(ErrorCode::InvalidArgument, "Invalid implicit duration");
  79. // 3. Set timeouts’s implicit wait timeout to implicit duration.
  80. timeouts.implicit_wait_timeout = static_cast<u64>(*implicit_duration);
  81. }
  82. // 6. Return success with data timeouts.
  83. return timeouts;
  84. }
  85. }