chromium/chrome/browser/web_applications/web_app_link_capturing_parameterized_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 <ostream>

#include "base/base_paths.h"
#include "base/command_line.h"
#include "base/files/file_util.h"
#include "base/json/json_file_value_serializer.h"
#include "base/json/json_reader.h"
#include "base/memory/weak_ptr.h"
#include "base/path_service.h"
#include "base/ranges/algorithm.h"
#include "base/strings/string_number_conversions.h"
#include "base/task/current_thread.h"
#include "base/test/bind.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/test_future.h"
#include "base/threading/scoped_blocking_call.h"
#include "base/threading/thread_restrictions.h"
#include "base/types/expected.h"
#include "chrome/browser/apps/app_service/app_registry_cache_waiter.h"
#include "chrome/browser/apps/app_service/app_service_proxy.h"
#include "chrome/browser/apps/app_service/app_service_proxy_factory.h"
#include "chrome/browser/apps/link_capturing/link_capturing_feature_test_support.h"
#include "chrome/browser/notifications/notification_display_service_tester.h"
#include "chrome/browser/notifications/notification_permission_context.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_finder.h"
#include "chrome/browser/ui/browser_list.h"
#include "chrome/browser/ui/web_applications/app_browser_controller.h"
#include "chrome/browser/ui/web_applications/web_app_browsertest_base.h"
#include "chrome/browser/web_applications/mojom/user_display_mode.mojom.h"
#include "chrome/browser/web_applications/test/os_integration_test_override_impl.h"
#include "chrome/browser/web_applications/test/web_app_install_test_utils.h"
#include "chrome/browser/web_applications/web_app_command_scheduler.h"
#include "chrome/browser/web_applications/web_app_install_info.h"
#include "chrome/browser/web_applications/web_app_provider.h"
#include "chrome/browser/web_applications/web_app_registrar.h"
#include "chrome/browser/web_applications/web_app_registry_update.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h"
#include "components/services/app_service/public/cpp/app_launch_util.h"
#include "components/webapps/common/web_app_id.h"
#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/navigation_handle.h"
#include "content/public/common/content_features.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/test_navigation_observer.h"
#include "content/public/test/test_utils.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "third_party/blink/public/common/manifest/manifest.h"
#include "third_party/blink/public/mojom/manifest/manifest_launch_handler.mojom-shared.h"
#include "ui/base/window_open_disposition.h"
#include "ui/gfx/geometry/point.h"
#include "ui/gfx/geometry/point_conversions.h"
#include "url/gurl.h"

namespace {

constexpr char kStartPageScopeA[] =;
constexpr char kDestinationPageScopeA[] =;
constexpr char kDestinationPageScopeB[] =;
constexpr char kDestinationPageScopeX[] =;
constexpr char kLinkCaptureTestInputPath[] =;

constexpr char kValueScopeA2A[] =;
constexpr char kValueScopeA2B[] =;
constexpr char kValueScopeA2X[] =;
constexpr char kValueLink[] =;
constexpr char kValueButton[] =;
constexpr char kValueServiceWorkerButton[] =;
constexpr char kValueOpener[] =;
constexpr char kValueNoOpener[] =;
constexpr char kValueTargetSelf[] =;
constexpr char kValueTargetFrame[] =;
constexpr char kValueTargetBlank[] =;
constexpr char kValueTargetNoFrame[] =;

// Whether Link capturing is turned on:
enum class LinkCapturing {};

std::string_view ToParamString(LinkCapturing capturing) {}

// The starting point for the test:
enum class StartingPoint {};

std::string_view ToParamString(StartingPoint start) {}

// Destinations:
// ScopeA2A: Navigation to an installed app, within same scope.
// ScopeA2B: Navigation to an installed app, but different scope.
// ScopeA2X: Navigation to non-installed app (different scope).
enum class Destination {};

std::string ToIdString(Destination scope) {}

std::string_view ToParamString(Destination scope) {}

enum class RedirectType {};

std::string ToIdString(RedirectType redirect, Destination final_destination) {}

std::string_view ToParamString(RedirectType redirect) {}

// The element to use for navigation:
enum class NavigationElement {};

std::string ToIdString(NavigationElement element) {}

std::string_view ToParamString(NavigationElement element) {}

// The method of interacting with the element:
enum class ClickMethod {};

std::string_view ToParamString(ClickMethod click) {}

// Whether to supply an Opener/NoOpener:
enum class OpenerMode {};

std::string ToIdString(OpenerMode opener) {}

std::string ToParamString(
    blink::mojom::ManifestLaunchHandler_ClientMode client_mode) {}

std::string_view ToParamString(OpenerMode opener) {}

template <typename ParamType, class Char, class Traits>
std::basic_ostream<Char, Traits>& operator<<(
    std::basic_ostream<Char, Traits>& os,
    ParamType param) {}

// The target to supply for the navigation:
enum class NavigationTarget {};

std::string ToIdString(NavigationTarget target) {}

std::string_view ToParamString(NavigationTarget target) {}

// Use a std::tuple for the overall test configuration so testing::Combine can
// be used to construct the values.
LinkCaptureTestParam;

std::string LinkCaptureTestParamToString(
    testing::TestParamInfo<LinkCaptureTestParam> param_info) {}

std::string BrowserTypeToString(Browser::Type type) {}

// Serializes the state of a RenderFrameHost relevant for this test into a
// dictionary that can be stored as JSON. This includes the frame name and
// current URL.
// TODO(crbug.com/359418631): Add opener information to frames if possible.
base::Value::Dict RenderFrameHostToJson(content::RenderFrameHost& rfh) {}

// Serializes the state of a WebContents, including the state of all its iframes
// as well as navigation history for the tab.
base::Value::Dict WebContentsToJson(content::WebContents& web_contents) {}

// Serializes the state of all tabs in a particular Browser to a json
// dictionary, including which tab is the currently active tab.
//
// For app browsers, the scope path is added to simplify manual debugging to
// identify cases where a source app window can have an out of scope destination
// url loaded in it.
base::Value::Dict BrowserToJson(const Browser& browser) {}

// Serializes the entire state of chrome that we're interested in in this test
// to a dictionary. This state consists of the state of all Browser windows, in
// creation order of the Browser.
base::Value::Dict CaptureCurrentState() {}

// This helper class monitors WebContents creation in all tabs (of all browsers)
// and can be queried for the last one seen.
class WebContentsCreationMonitor : public ui_test_utils::AllTabsObserver {};

}  // namespace

// This test verifies the navigation capture logic by testing by launching sites
// inside app containers and tabs and test what happens when links are
// left/middle clicked and window.open is used (whether browser objects are
// reused and what type gets launched).
//
// The test expectations are read from a json file that is stored here:
// chrome/test/data/web_apps/link_capture_test_input.json
//
// The expectations file maps test names (as serialized from the test
// parameters) to a json object containing a `disabled` flag as well as
// `expected_state`, the expected state of all Browser objects and their
// WebContents at the end of a test.
//
// If link capturing behavior changes, the test expectations would need to be
// updated. This can be done manually (by editing the json file directly), or it
// can be done automatically by using the flag --rebaseline-link-capturing-test.
//
// By default only tests that aren't listed as disabled in the json file are
// executed. To also run tests marked as disabled, include the --run-all-tests
// flag. This is also needed if you want to rebaseline tests that are still
// disabled.
//
// Example usage:
// out/Default/browser_tests \
// --gtest_filter=*WebAppLinkCapturingParameterizedBrowserTest.* \
// --rebaseline-link-capturing-test --run-all-tests --test-launcher-jobs=40
class WebAppLinkCapturingParameterizedBrowserTest
    : public web_app::WebAppBrowserTestBase,
      public testing::WithParamInterface<LinkCaptureTestParam> {};

// TODO(crbug.com/359600606): Enable on CrOS if needed.
#if BUILDFLAG(IS_CHROMEOS)
#define MAYBE_CheckLinkCaptureCombinations
#else
#define MAYBE_CheckLinkCaptureCombinations
#endif  // BUILDFLAG(IS_CHROMEOS)
IN_PROC_BROWSER_TEST_P(WebAppLinkCapturingParameterizedBrowserTest,
                       MAYBE_CheckLinkCaptureCombinations) {}

// Pro-tip: To run only one combination from the below list, supply this...
// WebAppLinkCapturingParameterizedBrowserTest.CheckLinkCaptureCombinations/foo
// Where foo can be:
// CaptureOn_AppWnd_ScopeA2A_Direct_ViaLink_LeftClick_WithOpener_TargetSelf
// See ParamToString above for possible values.
INSTANTIATE_TEST_SUITE_P();

INSTANTIATE_TEST_SUITE_P();

INSTANTIATE_TEST_SUITE_P();

// This test verifies that there are no left-over expectations for tests that
// no longer exist in code but still exist in the expectations json file.
// Additionally if this test is run with the --rebaseline-link-capturing-test
// flag any left-over expectations will be cleaned up.
// TODO(crbug.com/359600606): Enable on CrOS if needed.
#if BUILDFLAG(IS_CHROMEOS)
#define MAYBE_CleanupExpectations
#else
#define MAYBE_CleanupExpectations
#endif  // BUILDFLAG(IS_CHROMEOS)
WebAppLinkCapturingParameterizedExpectationTest;
IN_PROC_BROWSER_TEST_F(WebAppLinkCapturingParameterizedExpectationTest,
                       MAYBE_CleanupExpectations) {}