blob: d6be6cbcc19abb9619c64c21dc6dd7f10d9b8756 [file] [log] [blame]
// Copyright 2019 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/ui/web_applications/web_app_browsertest_base.h"
#include <string>
#include <vector>
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/bind.h"
#include "base/test/test_future.h"
#include "base/time/time.h"
#include "chrome/browser/apps/app_service/app_launch_params.h"
#include "chrome/browser/banners/test_app_banner_manager_desktop.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/browser/ui/web_applications/test/web_app_browsertest_util.h"
#include "chrome/browser/web_applications/mojom/user_display_mode.mojom.h"
#include "chrome/browser/web_applications/os_integration/os_integration_manager.h"
#include "chrome/browser/web_applications/os_integration/os_integration_test_override.h"
#include "chrome/browser/web_applications/proto/web_app_install_state.pb.h"
#include "chrome/browser/web_applications/test/debug_info_printer.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_callback_app_identity.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_ui_manager.h"
#include "chrome/browser/web_applications/web_app_utils.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/test/base/ui_test_utils.h"
#include "components/keyed_service/content/browser_context_dependency_manager.h"
#include "components/services/app_service/public/cpp/app_launch_util.h"
#include "content/public/browser/navigation_controller.h"
#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/page_type.h"
#include "content/public/test/browser_test_utils.h"
#include "net/base/url_util.h"
#include "net/dns/mock_host_resolver.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace web_app {
WebAppBrowserTestBase::WebAppBrowserTestBase()
: WebAppBrowserTestBase({}, {}) {}
WebAppBrowserTestBase::WebAppBrowserTestBase(
const std::vector<base::test::FeatureRef>& enabled_features,
const std::vector<base::test::FeatureRef>& disabled_features)
// TODO(crbug.com/40874949): Fix the manifest update process by ensuring
// during test installs, an app is installed from the manifest so that the
// identity update dialog is not triggered after navigation. This will
// ensure removal of update_dialog_scope_.
: https_server_(net::EmbeddedTestServer::TYPE_HTTPS),
update_dialog_scope_(SetIdentityUpdateDialogActionForTesting(
AppIdentityUpdate::kSkipped)) {
scoped_feature_list_.InitWithFeatures(enabled_features, disabled_features);
}
WebAppBrowserTestBase::~WebAppBrowserTestBase() = default;
WebAppProvider& WebAppBrowserTestBase::provider() {
auto* provider = WebAppProvider::GetForTest(profile());
DCHECK(provider);
return *provider;
}
Profile* WebAppBrowserTestBase::profile() {
CHECK(browser_profile_);
return browser_profile_.get();
}
webapps::AppId WebAppBrowserTestBase::InstallPWA(const GURL& start_url) {
auto web_app_info =
WebAppInstallInfo::CreateWithStartUrlForTesting(start_url);
web_app_info->scope = start_url.GetWithoutFilename();
web_app_info->user_display_mode = mojom::UserDisplayMode::kStandalone;
web_app_info->title = u"A Web App";
return web_app::test::InstallWebApp(profile(), std::move(web_app_info));
}
webapps::AppId WebAppBrowserTestBase::InstallWebApp(
std::unique_ptr<WebAppInstallInfo> web_app_info) {
return web_app::test::InstallWebApp(profile(), std::move(web_app_info));
}
void WebAppBrowserTestBase::UninstallWebApp(const webapps::AppId& app_id) {
web_app::test::UninstallWebApp(profile(), app_id);
}
Browser* WebAppBrowserTestBase::LaunchWebAppBrowser(
const webapps::AppId& app_id) {
return web_app::LaunchWebAppBrowser(profile(), app_id);
}
Browser* WebAppBrowserTestBase::LaunchWebAppBrowserAndWait(
const webapps::AppId& app_id) {
return web_app::LaunchWebAppBrowserAndWait(profile(), app_id);
}
Browser* WebAppBrowserTestBase::LaunchWebAppBrowserAndAwaitInstallabilityCheck(
const webapps::AppId& app_id) {
Browser* browser = web_app::LaunchWebAppBrowserAndWait(profile(), app_id);
webapps::TestAppBannerManagerDesktop::FromWebContents(
browser->tab_strip_model()->GetActiveWebContents())
->WaitForInstallableCheck();
return browser;
}
Browser* WebAppBrowserTestBase::LaunchBrowserForWebAppInTab(
const webapps::AppId& app_id) {
return web_app::LaunchBrowserForWebAppInTab(profile(), app_id);
}
bool WebAppBrowserTestBase::NavigateInRenderer(content::WebContents* contents,
const GURL& url) {
EXPECT_TRUE(
content::ExecJs(contents, "window.location = '" + url.spec() + "';"));
bool success = content::WaitForLoadStop(contents);
EXPECT_EQ(url, contents->GetController().GetLastCommittedEntry()->GetURL());
return success;
}
// static
bool WebAppBrowserTestBase::NavigateAndAwaitInstallabilityCheck(
Browser* browser,
const GURL& url) {
auto* manager = webapps::TestAppBannerManagerDesktop::FromWebContents(
browser->tab_strip_model()->GetActiveWebContents());
EXPECT_TRUE(ui_test_utils::NavigateToURL(browser, url));
return manager->WaitForInstallableCheck();
}
Browser* WebAppBrowserTestBase::NavigateInNewWindowAndAwaitInstallabilityCheck(
const GURL& url) {
Browser* new_browser = Browser::Create(
Browser::CreateParams(Browser::TYPE_NORMAL, profile(), true));
AddBlankTabAndShow(new_browser);
NavigateAndAwaitInstallabilityCheck(new_browser, url);
return new_browser;
}
std::optional<webapps::AppId> WebAppBrowserTestBase::FindAppWithUrlInScope(
const GURL& url) {
return provider().registrar_unsafe().FindBestAppWithUrlInScope(
url, web_app::WebAppFilter::InstalledInChrome());
}
Browser* WebAppBrowserTestBase::OpenPopupAndWait(Browser* browser,
const GURL& url,
const gfx::Size& popup_size) {
content::WebContents* const web_contents =
browser->tab_strip_model()->GetActiveWebContents();
ui_test_utils::BrowserCreatedObserver browser_created_observer;
std::string open_window_script = base::StringPrintf(
"window.open('%s', '_blank', 'toolbar=none,width=%i,height=%i')",
url.spec().c_str(), popup_size.width(), popup_size.height());
EXPECT_TRUE(content::ExecJs(web_contents, open_window_script));
// The navigation should happen in a new window.
Browser* popup_browser = browser_created_observer.Wait();
EXPECT_NE(browser, popup_browser);
content::WebContents* popup_contents =
popup_browser->tab_strip_model()->GetActiveWebContents();
EXPECT_TRUE(content::WaitForLoadStop(popup_contents));
EXPECT_EQ(popup_contents->GetLastCommittedURL(), url);
return popup_browser;
}
OsIntegrationTestOverrideImpl&
WebAppBrowserTestBase::os_integration_override() {
return faked_os_integration_.test_override();
}
content::WebContents* WebAppBrowserTestBase::OpenApplication(
const webapps::AppId& app_id) {
ui_test_utils::UrlLoadObserver url_observer(
provider().registrar_unsafe().GetAppStartUrl(app_id));
web_app::WebAppProvider* provider =
web_app::WebAppProvider::GetForLocalAppsUnchecked(profile());
base::test::TestFuture<base::WeakPtr<Browser>,
base::WeakPtr<content::WebContents>,
apps::LaunchContainer>
future;
provider->scheduler().LaunchAppWithCustomParams(
apps::AppLaunchParams(
app_id, apps::LaunchContainer::kLaunchContainerWindow,
WindowOpenDisposition::NEW_WINDOW, apps::LaunchSource::kFromTest),
future.GetCallback());
url_observer.Wait();
return future.template Get<1>().get();
}
GURL WebAppBrowserTestBase::GetInstallableAppURL() {
return https_server()->GetURL("/banners/manifest_test_page.html");
}
GURL WebAppBrowserTestBase::GetAppURLWithManifest(
const std::string& manifest_url) {
GURL url = GetInstallableAppURL();
return net::AppendQueryParameter(url, "manifest",
https_server()->GetURL(manifest_url).spec());
}
// static
const char* WebAppBrowserTestBase::GetInstallableAppName() {
return "Manifest test app";
}
void WebAppBrowserTestBase::SetUp() {
https_server_.AddDefaultHandlers(GetChromeTestDataDir());
webapps::TestAppBannerManagerDesktop::SetUp();
WebAppBrowserTestBaseParent::SetUp();
}
void WebAppBrowserTestBase::TearDown() {
WebAppBrowserTestBaseParent::TearDown();
}
void WebAppBrowserTestBase::SetUpInProcessBrowserTestFixture() {
WebAppBrowserTestBaseParent::SetUpInProcessBrowserTestFixture();
cert_verifier_.SetUpInProcessBrowserTestFixture();
create_services_subscription_ =
BrowserContextDependencyManager::GetInstance()
->RegisterCreateServicesCallbackForTesting(base::BindRepeating(
&WebAppBrowserTestBase::OnWillCreateBrowserContextServices,
base::Unretained(this)));
}
void WebAppBrowserTestBase::TearDownInProcessBrowserTestFixture() {
WebAppBrowserTestBaseParent::TearDownInProcessBrowserTestFixture();
cert_verifier_.TearDownInProcessBrowserTestFixture();
}
void WebAppBrowserTestBase::TearDownOnMainThread() {
if (testing::Test::HasFailure()) {
ProfileManager* profile_manager = g_browser_process->profile_manager();
base::TimeDelta log_time = base::TimeTicks::Now() - start_time_;
test::LogDebugInfoToConsole(profile_manager->GetLoadedProfiles(), log_time);
}
WebAppBrowserTestBaseParent::TearDownOnMainThread();
}
void WebAppBrowserTestBase::SetUpCommandLine(base::CommandLine* command_line) {
WebAppBrowserTestBaseParent::SetUpCommandLine(command_line);
// Browser will both run and display insecure content.
command_line->AppendSwitch(switches::kAllowRunningInsecureContent);
cert_verifier_.SetUpCommandLine(command_line);
}
void WebAppBrowserTestBase::PreRunTestOnMainThread() {
WebAppBrowserTestBaseParent::PreRunTestOnMainThread();
browser_profile_ = browser()->profile()->GetWeakPtr();
}
void WebAppBrowserTestBase::SetUpOnMainThread() {
WebAppBrowserTestBaseParent::SetUpOnMainThread();
host_resolver()->AddRule("*", "127.0.0.1");
ASSERT_TRUE(https_server()->Start());
// By default, all SSL cert checks are valid. Can be overridden in tests.
cert_verifier_.mock_cert_verifier()->set_default_result(net::OK);
web_app::test::WaitUntilReady(
web_app::WebAppProvider::GetForTest(browser()->profile()));
}
} // namespace web_app