chromium/components/js_injection/browser/navigation_listener_browsertest.cc

// 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