// Copyright 2024 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include <string> #include "base/json/json_writer.h" #include "base/strings/utf_string_conversions.h" #include "components/js_injection/browser/js_communication_host.h" #include "components/js_injection/browser/navigation_web_message_sender.h" #include "components/js_injection/browser/web_message.h" #include "components/js_injection/browser/web_message_host.h" #include "components/js_injection/browser/web_message_host_factory.h" #include "content/public/browser/back_forward_cache.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/web_contents.h" #include "content/public/common/content_features.h" #include "content/public/test/back_forward_cache_util.h" #include "content/public/test/browser_test.h" #include "content/public/test/browser_test_utils.h" #include "content/public/test/content_browser_test.h" #include "content/public/test/content_browser_test_utils.h" #include "content/public/test/test_utils.h" #include "content/shell/browser/shell.h" #include "net/test/embedded_test_server/controllable_http_response.h" #include "net/test/embedded_test_server/embedded_test_server.h" #include "testing/gtest/include/gtest/gtest.h" #include "url/gurl.h" namespace js_injection { HostToken; // Listens to navigation messages and queues them per-WebMessageHost. The queued // messages can be read in sequence for each host. It's useful to queue the // messages per-host, since some messages can arrive interleaved with messages // intended for other hosts, e.g. PAGE_DELETED messages can fire a bit later // than the next page's NAVIGATION_COMPLETED message, if the RenderFrameHost // changes and the deletion of the previous RenderFrameHost happens after // the new RenderFrameHost's navigation committed. However, it's guaranteed // that the order within the same host stays consistent (NAVIGATION_COMPLETED & // PAGE_LOAD_END won't fire after PAGE_DELETED) and only PAGE_DELETED can be // fired for the old page after the new page's NAVIGATION_COMPLETED. class NavigationMessageListener { … }; class FakeWebMessageHost : public WebMessageHost { … }; class FakeWebMessageHostFactory : public WebMessageHostFactory { … }; class NavigationListenerBrowserTest : public content::ContentBrowserTest, public testing::WithParamInterface<bool> { … }; // Test that adding the special navigationListener will result in receiving // navigation messages for a variety of navigation cases: // 1) Regular navigation // 2) Reload // 3) Same-document navigation // 4) Same-document history navigation // 5) Failed navigation resulting in an error page. IN_PROC_BROWSER_TEST_P(NavigationListenerBrowserTest, Basic) { … } // Test navigation messages when navigating away from a page that hasn't fired // the load event. IN_PROC_BROWSER_TEST_P(NavigationListenerBrowserTest, NoLoadEnd) { … } // Test navigation messages when a new renderer-initiated same-document // navigation happens while a cross-document navigation is ongoing and hasn't // received its network response. Both navigations should commit. IN_PROC_BROWSER_TEST_P(NavigationListenerBrowserTest, NewRendererInitiatedSameDocNavDuringCrossDocNav) { … } // Test navigation messages when a new browser-initiated same-document // navigation happens while a cross-document navigation is ongoing and hasn't // received its network response. Different than above, the newer same-document // navigation should cancel the first navigation here, since the newer // NavigationHandle will take the place of the first NavigationHandle. IN_PROC_BROWSER_TEST_P(NavigationListenerBrowserTest, NewBrowserInitiatedSameDocNavDuringCrossDocNav) { … } // Test navigation messages when a new cross-document navigation happens while // an earlier cross-document navigation is ongoing and hasn't received its // network response. The newer navigation should cancel the first navigation // here, since the newer NavigationHandle will take the place of the first // NavigationHandle. This behavior will be the same regardless of whether the // newer navigation is browser- or renderer-initiated. IN_PROC_BROWSER_TEST_P(NavigationListenerBrowserTest, NewCrossDocNavDuringCrossDocNav) { … } // Disabled due to flakiness. See https://crbug.com/357879183 INSTANTIATE_TEST_SUITE_P(DISABLED_All, NavigationListenerBrowserTest, testing::Bool(), [](const testing::TestParamInfo<bool>& info) { … }; } // namespace js_injection