Sfoglia il codice sorgente

WebContent+WebDriver: Move the Navigate To command to WebContent

Timothy Flynn 2 anni fa
parent
commit
31bb79295d

+ 3 - 0
Userland/Applications/Browser/WebDriverSessionClient.ipc

@@ -8,6 +8,9 @@
 #include <LibWeb/Cookie/ParsedCookie.h>
 #include <LibWeb/WebDriver/ExecuteScript.h>
 
+// FIXME: This isn't used here, but the generated IPC fails to compile without this include.
+#include <LibWeb/WebDriver/Response.h>
+
 endpoint WebDriverSessionClient {
     quit() =|
 

+ 3 - 0
Userland/Services/WebContent/WebContentClient.ipc

@@ -3,6 +3,9 @@
 #include <LibGfx/ShareableBitmap.h>
 #include <LibWeb/Cookie/ParsedCookie.h>
 
+// FIXME: This isn't used here, but the generated IPC fails to compile without this include.
+#include <LibWeb/WebDriver/Response.h>
+
 endpoint WebContentClient
 {
     did_start_loading(URL url) =|

+ 3 - 0
Userland/Services/WebContent/WebDriverClient.ipc

@@ -1,3 +1,6 @@
+#include <LibWeb/WebDriver/Response.h>
+
 endpoint WebDriverClient {
     set_is_webdriver_active(bool active) =|
+    navigate_to(JsonValue payload) => (Web::WebDriver::Response response)
 }

+ 56 - 0
Userland/Services/WebContent/WebDriverConnection.cpp

@@ -19,6 +19,21 @@
 
 namespace WebContent {
 
+#define DRIVER_TRY(expression)                            \
+    ({                                                    \
+        auto _temporary_result = (expression);            \
+        if (_temporary_result.is_error()) [[unlikely]]    \
+            return { _temporary_result.release_error() }; \
+        _temporary_result.release_value();                \
+    })
+
+static JsonValue make_success_response(JsonValue value)
+{
+    JsonObject result;
+    result.set("value", move(value));
+    return result;
+}
+
 ErrorOr<NonnullRefPtr<WebDriverConnection>> WebDriverConnection::connect(PageHost& page_host, String const& webdriver_ipc_path)
 {
     dbgln_if(WEBDRIVER_DEBUG, "Trying to connect to {}", webdriver_ipc_path);
@@ -39,4 +54,45 @@ void WebDriverConnection::set_is_webdriver_active(bool is_webdriver_active)
     m_page_host.set_is_webdriver_active(is_webdriver_active);
 }
 
+// 10.1 Navigate To, https://w3c.github.io/webdriver/#navigate-to
+Messages::WebDriverClient::NavigateToResponse WebDriverConnection::navigate_to(JsonValue const& payload)
+{
+    dbgln_if(WEBDRIVER_DEBUG, "WebDriverConnection::navigate_to {}", payload);
+
+    // 1. If the current top-level browsing context is no longer open, return error with error code no such window.
+    DRIVER_TRY(ensure_open_top_level_browsing_context());
+
+    // 2. Let url be the result of getting the property url from the parameters argument.
+    if (!payload.is_object() || !payload.as_object().has_string("url"sv))
+        return { Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::InvalidArgument, "Payload doesn't have a string `url`"sv) };
+    URL url(payload.as_object().get_ptr("url"sv)->as_string());
+
+    // FIXME: 3. If url is not an absolute URL or is not an absolute URL with fragment or not a local scheme, return error with error code invalid argument.
+    // FIXME: 4. Handle any user prompts and return its value if it is an error.
+    // FIXME: 5. Let current URL be the current top-level browsing context’s active document’s URL.
+    // FIXME: 6. If current URL and url do not have the same absolute URL:
+    // FIXME:     a. If timer has not been started, start a timer. If this algorithm has not completed before timer reaches the session’s session page load timeout in milliseconds, return an error with error code timeout.
+
+    // 7. Navigate the current top-level browsing context to url.
+    m_page_host.page().load(url);
+
+    // FIXME: 8. If url is special except for file and current URL and URL do not have the same absolute URL:
+    // FIXME:     a. Try to wait for navigation to complete.
+    // FIXME:     b. Try to run the post-navigation checks.
+    // FIXME: 9. Set the current browsing context with the current top-level browsing context.
+    // FIXME: 10. If the current top-level browsing context contains a refresh state pragma directive of time 1 second or less, wait until the refresh timeout has elapsed, a new navigate has begun, and return to the first step of this algorithm.
+
+    // 11. Return success with data null.
+    return { make_success_response({}) };
+}
+
+// https://w3c.github.io/webdriver/#dfn-no-longer-open
+ErrorOr<void, Web::WebDriver::Error> WebDriverConnection::ensure_open_top_level_browsing_context()
+{
+    // A browsing context is said to be no longer open if it has been discarded.
+    if (m_page_host.page().top_level_browsing_context().has_been_discarded())
+        return Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::NoSuchWindow, "Window not found"sv);
+    return {};
+}
+
 }

+ 3 - 0
Userland/Services/WebContent/WebDriverConnection.h

@@ -29,6 +29,9 @@ private:
 
     virtual void die() override { }
     virtual void set_is_webdriver_active(bool) override;
+    virtual Messages::WebDriverClient::NavigateToResponse navigate_to(JsonValue const& payload) override;
+
+    ErrorOr<void, Web::WebDriver::Error> ensure_open_top_level_browsing_context();
 
     PageHost& m_page_host;
 };

+ 1 - 2
Userland/Services/WebDriver/Client.cpp

@@ -482,8 +482,7 @@ Web::WebDriver::Response Client::handle_navigate_to(Vector<StringView> const& pa
 {
     dbgln_if(WEBDRIVER_DEBUG, "Handling POST /session/<session_id>/url");
     auto* session = TRY(find_session_with_id(parameters[0]));
-    auto result = TRY(session->navigate_to(payload));
-    return make_json_value(result);
+    return session->web_content_connection().navigate_to(payload);
 }
 
 // 10.2 Get Current URL, https://w3c.github.io/webdriver/#dfn-get-current-url

+ 0 - 34
Userland/Services/WebDriver/Session.cpp

@@ -165,40 +165,6 @@ Web::WebDriver::Response Session::set_timeouts(JsonValue const& payload)
     return JsonValue {};
 }
 
-// 10.1 Navigate To, https://w3c.github.io/webdriver/#dfn-navigate-to
-Web::WebDriver::Response Session::navigate_to(JsonValue const& payload)
-{
-    // 1. If the current top-level browsing context is no longer open, return error with error code no such window.
-    TRY(check_for_open_top_level_browsing_context_or_return_error());
-
-    // FIXME 2. Handle any user prompts and return its value if it is an error.
-
-    // 3. If the url property is missing from the parameters argument or it is not a string, return error with error code invalid argument.
-    if (!payload.is_object() || !payload.as_object().has_string("url"sv)) {
-        return Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::InvalidArgument, "Payload doesn't have a string url");
-    }
-
-    // 4. Let url be the result of getting a property named url from the parameters argument.
-    URL url(payload.as_object().get_ptr("url"sv)->as_string());
-
-    // FIXME: 5. If url is not an absolute URL or an absolute URL with fragment, return error with error code invalid argument. [URL]
-
-    // 6. Let url be the result of getting a property named url from the parameters argument.
-    // Duplicate step?
-
-    // 7. Navigate the current top-level browsing context to url.
-    m_browser_connection->async_set_url(url);
-
-    // FIXME: 8. Run the post-navigation checks and return its value if it is an error.
-
-    // FIXME: 9. Wait for navigation to complete and return its value if it is an error.
-
-    // FIXME: 10. Set the current browsing context to the current top-level browsing context.
-
-    // 11. Return success with data null.
-    return JsonValue();
-}
-
 // 10.2 Get Current URL, https://w3c.github.io/webdriver/#dfn-get-current-url
 Web::WebDriver::Response Session::get_current_url()
 {

+ 0 - 1
Userland/Services/WebDriver/Session.h

@@ -51,7 +51,6 @@ public:
     ErrorOr<void> stop();
     JsonObject get_timeouts();
     Web::WebDriver::Response set_timeouts(JsonValue const& payload);
-    Web::WebDriver::Response navigate_to(JsonValue const& url);
     Web::WebDriver::Response get_current_url();
     Web::WebDriver::Response back();
     Web::WebDriver::Response forward();