blob: 7499275be5004d3ed7823c2453491417de4499e2 [file] [log] [blame]
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <string>
#include <tuple>
#include <utility>
#include <vector>
#include "base/strings/utf_string_conversions.h"
#include "chrome/app/chrome_command_ids.h"
#include "chrome/browser/renderer_context_menu/render_view_context_menu_test_util.h"
#include "chrome/browser/ui/browser_finder.h"
#include "chrome/browser/ui/browser_tabstrip.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/location_bar/location_bar.h"
#include "chrome/browser/ui/web_applications/system_web_app_ui_utils.h"
#include "chrome/browser/ui/web_applications/test/web_app_browsertest_util.h"
#include "chrome/browser/web_applications/system_web_app_manager_browsertest.h"
#include "chrome/browser/web_applications/test/test_system_web_app_installation.h"
#include "chrome/common/webui_url_constants.h"
#include "chrome/test/base/ui_test_utils.h"
#include "components/omnibox/browser/omnibox_edit_model.h"
#include "components/omnibox/browser/omnibox_view.h"
#include "content/public/browser/notification_types.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/test_navigation_observer.h"
namespace web_app {
class SystemWebAppLinkCaptureBrowserTest
: public SystemWebAppManagerBrowserTest {
public:
SystemWebAppLinkCaptureBrowserTest()
: SystemWebAppManagerBrowserTest(/*install_mock*/ false) {
maybe_installation_ =
TestSystemWebAppInstallation::SetUpAppThatCapturesNavigation(
install_from_web_app_info());
}
~SystemWebAppLinkCaptureBrowserTest() override = default;
protected:
Browser* CreateIncognitoBrowser() {
Browser* incognito = new Browser(Browser::CreateParams(
browser()->profile()->GetPrimaryOTRProfile(), true));
content::WindowedNotificationObserver observer(
content::NOTIFICATION_LOAD_STOP,
content::NotificationService::AllSources());
chrome::AddSelectedTabWithURL(incognito, GURL(url::kAboutBlankURL),
ui::PAGE_TRANSITION_AUTO_TOPLEVEL);
observer.Wait();
incognito->window()->Show();
return incognito;
}
const GURL kInitiatingAppUrl = GURL("chrome://initiating-app/pwa.html");
const SystemAppType kInitiatingAppType = SystemAppType::SETTINGS;
};
IN_PROC_BROWSER_TEST_P(SystemWebAppLinkCaptureBrowserTest,
OmniboxTypeURLAndNavigate) {
WaitForTestSystemAppInstall();
content::TestNavigationObserver observer(maybe_installation_->GetAppUrl());
observer.StartWatchingNewWebContents();
ui_test_utils::SendToOmniboxAndSubmit(
browser(), maybe_installation_->GetAppUrl().spec());
observer.Wait();
Browser* app_browser = FindSystemWebAppBrowser(
browser()->profile(), maybe_installation_->GetType());
EXPECT_TRUE(app_browser);
EXPECT_EQ(app_browser, chrome::FindLastActive());
EXPECT_EQ(2U, chrome::GetTotalBrowserCount());
EXPECT_EQ(Browser::TYPE_APP, app_browser->type());
EXPECT_FALSE(app_browser->app_controller()->ShouldShowCustomTabBar());
}
IN_PROC_BROWSER_TEST_P(SystemWebAppLinkCaptureBrowserTest, OmniboxPasteAndGo) {
WaitForTestSystemAppInstall();
OmniboxEditModel* model =
browser()->window()->GetLocationBar()->GetOmniboxView()->model();
content::TestNavigationObserver observer(maybe_installation_->GetAppUrl());
observer.StartWatchingNewWebContents();
model->PasteAndGo(base::UTF8ToUTF16(maybe_installation_->GetAppUrl().spec()));
observer.Wait();
Browser* app_browser = FindSystemWebAppBrowser(
browser()->profile(), maybe_installation_->GetType());
EXPECT_TRUE(app_browser);
EXPECT_EQ(app_browser, chrome::FindLastActive());
EXPECT_EQ(2U, chrome::GetTotalBrowserCount());
EXPECT_EQ(Browser::TYPE_APP, app_browser->type());
EXPECT_FALSE(app_browser->app_controller()->ShouldShowCustomTabBar());
}
IN_PROC_BROWSER_TEST_P(SystemWebAppLinkCaptureBrowserTest, AnchorLinkClick) {
WaitForTestSystemAppInstall();
GURL kInitiatingChromeUrl = GURL(chrome::kChromeUIAboutURL);
NavigateToURLAndWait(browser(), kInitiatingChromeUrl);
EXPECT_EQ(kInitiatingChromeUrl, browser()
->tab_strip_model()
->GetActiveWebContents()
->GetLastCommittedURL());
const std::string kAnchorTargets[] = {"", "_blank", "_self"};
const std::string kAnchorRelValues[] = {"", "noreferrer", "noopener",
"noreferrer noopener"};
for (const auto& target : kAnchorTargets) {
for (const auto& rel : kAnchorRelValues) {
SCOPED_TRACE(testing::Message() << "anchor link: target='" << target
<< "', rel='" << rel << "'");
content::TestNavigationObserver observer(
maybe_installation_->GetAppUrl());
observer.StartWatchingNewWebContents();
EXPECT_TRUE(content::ExecuteScript(
browser()->tab_strip_model()->GetActiveWebContents(),
content::JsReplace("{"
" let el = document.createElement('a');"
" el.href = $1;"
" el.target = $2;"
" el.rel = $3;"
" el.textContent = 'target = ' + $2;"
" document.body.appendChild(el);"
" el.click();"
"}",
maybe_installation_->GetAppUrl(), target, rel)));
observer.Wait();
Browser* app_browser = FindSystemWebAppBrowser(
browser()->profile(), maybe_installation_->GetType());
EXPECT_TRUE(app_browser);
EXPECT_EQ(app_browser, chrome::FindLastActive());
EXPECT_EQ(2U, chrome::GetTotalBrowserCount());
EXPECT_EQ(Browser::TYPE_APP, app_browser->type());
EXPECT_FALSE(app_browser->app_controller()->ShouldShowCustomTabBar());
app_browser->window()->Close();
base::RunLoop().RunUntilIdle();
// Check the initiating browser window is intact.
EXPECT_EQ(kInitiatingChromeUrl, browser()
->tab_strip_model()
->GetActiveWebContents()
->GetLastCommittedURL());
}
}
}
IN_PROC_BROWSER_TEST_P(SystemWebAppLinkCaptureBrowserTest,
AnchorLinkContextMenuNewTab) {
WaitForTestSystemAppInstall();
GURL kInitiatingChromeUrl = GURL(chrome::kChromeUIAboutURL);
NavigateToURLAndWait(browser(), kInitiatingChromeUrl);
EXPECT_EQ(kInitiatingChromeUrl, browser()
->tab_strip_model()
->GetActiveWebContents()
->GetLastCommittedURL());
content::ContextMenuParams context_menu_params;
context_menu_params.page_url = kInitiatingChromeUrl;
context_menu_params.link_url = maybe_installation_->GetAppUrl();
content::TestNavigationObserver observer(maybe_installation_->GetAppUrl());
observer.StartWatchingNewWebContents();
TestRenderViewContextMenu menu(
browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame(),
context_menu_params);
menu.Init();
menu.ExecuteCommand(IDC_CONTENT_CONTEXT_OPENLINKNEWTAB, 0);
observer.Wait();
Browser* app_browser = FindSystemWebAppBrowser(
browser()->profile(), maybe_installation_->GetType());
EXPECT_TRUE(app_browser);
EXPECT_EQ(app_browser, chrome::FindLastActive());
EXPECT_EQ(2U, chrome::GetTotalBrowserCount());
EXPECT_EQ(Browser::TYPE_APP, app_browser->type());
EXPECT_FALSE(app_browser->app_controller()->ShouldShowCustomTabBar());
app_browser->window()->Close();
base::RunLoop().RunUntilIdle();
// Check the initiating browser window is intact.
EXPECT_EQ(kInitiatingChromeUrl, browser()
->tab_strip_model()
->GetActiveWebContents()
->GetLastCommittedURL());
}
IN_PROC_BROWSER_TEST_P(SystemWebAppLinkCaptureBrowserTest,
AnchorLinkContextMenuNewWindow) {
WaitForTestSystemAppInstall();
GURL kInitiatingChromeUrl = GURL(chrome::kChromeUIAboutURL);
NavigateToURLAndWait(browser(), kInitiatingChromeUrl);
EXPECT_EQ(kInitiatingChromeUrl, browser()
->tab_strip_model()
->GetActiveWebContents()
->GetLastCommittedURL());
content::ContextMenuParams context_menu_params;
context_menu_params.page_url = kInitiatingChromeUrl;
context_menu_params.link_url = maybe_installation_->GetAppUrl();
content::TestNavigationObserver observer(maybe_installation_->GetAppUrl());
observer.StartWatchingNewWebContents();
TestRenderViewContextMenu menu(
browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame(),
context_menu_params);
menu.Init();
menu.ExecuteCommand(IDC_CONTENT_CONTEXT_OPENLINKNEWWINDOW, 0);
observer.Wait();
Browser* app_browser = FindSystemWebAppBrowser(
browser()->profile(), maybe_installation_->GetType());
EXPECT_TRUE(app_browser);
EXPECT_EQ(app_browser, chrome::FindLastActive());
EXPECT_EQ(2U, chrome::GetTotalBrowserCount());
EXPECT_EQ(Browser::TYPE_APP, app_browser->type());
EXPECT_FALSE(app_browser->app_controller()->ShouldShowCustomTabBar());
app_browser->window()->Close();
base::RunLoop().RunUntilIdle();
// Check the initiating browser window is intact.
EXPECT_EQ(kInitiatingChromeUrl, browser()
->tab_strip_model()
->GetActiveWebContents()
->GetLastCommittedURL());
}
IN_PROC_BROWSER_TEST_P(SystemWebAppLinkCaptureBrowserTest, ChangeLocationHref) {
WaitForTestSystemAppInstall();
GURL kInitiatingChromeUrl = GURL(chrome::kChromeUIAboutURL);
NavigateToURLAndWait(browser(), kInitiatingChromeUrl);
EXPECT_EQ(kInitiatingChromeUrl, browser()
->tab_strip_model()
->GetActiveWebContents()
->GetLastCommittedURL());
content::TestNavigationObserver observer(maybe_installation_->GetAppUrl());
observer.StartWatchingNewWebContents();
EXPECT_TRUE(content::ExecuteScript(
browser()->tab_strip_model()->GetActiveWebContents(),
content::JsReplace("location.href=$1;",
maybe_installation_->GetAppUrl())));
observer.Wait();
Browser* app_browser = FindSystemWebAppBrowser(
browser()->profile(), maybe_installation_->GetType());
EXPECT_TRUE(app_browser);
EXPECT_EQ(app_browser, chrome::FindLastActive());
EXPECT_EQ(2U, chrome::GetTotalBrowserCount());
EXPECT_EQ(Browser::TYPE_APP, app_browser->type());
EXPECT_FALSE(app_browser->app_controller()->ShouldShowCustomTabBar());
// Check the initiating browser window is intact.
EXPECT_EQ(kInitiatingChromeUrl, browser()
->tab_strip_model()
->GetActiveWebContents()
->GetLastCommittedURL());
}
IN_PROC_BROWSER_TEST_P(SystemWebAppLinkCaptureBrowserTest, WindowOpen) {
WaitForTestSystemAppInstall();
GURL kInitiatingChromeUrl = GURL(chrome::kChromeUIAboutURL);
NavigateToURLAndWait(browser(), kInitiatingChromeUrl);
EXPECT_EQ(kInitiatingChromeUrl, browser()
->tab_strip_model()
->GetActiveWebContents()
->GetLastCommittedURL());
const std::string kWindowOpenTargets[] = {"", "_blank"};
const std::string kWindowOpenFeatures[] = {"", "noreferrer", "noopener",
"noreferrer noopener"};
for (const auto& target : kWindowOpenTargets) {
for (const auto& features : kWindowOpenFeatures) {
SCOPED_TRACE(testing::Message() << "window.open: target='" << target
<< "', features='" << features << "'");
content::TestNavigationObserver observer(
maybe_installation_->GetAppUrl());
observer.StartWatchingNewWebContents();
EXPECT_TRUE(content::ExecuteScript(
browser()->tab_strip_model()->GetActiveWebContents(),
content::JsReplace("window.open($1, $2, $3);",
maybe_installation_->GetAppUrl(), target,
features)));
observer.Wait();
Browser* app_browser = FindSystemWebAppBrowser(
browser()->profile(), maybe_installation_->GetType());
EXPECT_TRUE(app_browser);
EXPECT_EQ(app_browser, chrome::FindLastActive());
EXPECT_EQ(2U, chrome::GetTotalBrowserCount());
EXPECT_EQ(Browser::TYPE_APP, app_browser->type());
EXPECT_FALSE(app_browser->app_controller()->ShouldShowCustomTabBar());
app_browser->window()->Close();
base::RunLoop().RunUntilIdle();
// Check the initiating browser window is intact.
EXPECT_EQ(kInitiatingChromeUrl, browser()
->tab_strip_model()
->GetActiveWebContents()
->GetLastCommittedURL());
}
}
}
IN_PROC_BROWSER_TEST_P(SystemWebAppLinkCaptureBrowserTest,
WindowOpenFromOtherSWA) {
WaitForTestSystemAppInstall();
content::WebContents* initiating_web_contents = LaunchApp(kInitiatingAppType);
const std::string kWindowOpenTargets[] = {"", "_blank"};
const std::string kWindowOpenFeatures[] = {"", "noreferrer", "noopener",
"noreferrer noopener"};
for (const auto& target : kWindowOpenTargets) {
for (const auto& features : kWindowOpenFeatures) {
SCOPED_TRACE(testing::Message() << "window.open: target='" << target
<< "', features='" << features << "'");
content::TestNavigationObserver observer(
maybe_installation_->GetAppUrl());
observer.StartWatchingNewWebContents();
EXPECT_TRUE(content::ExecuteScript(
initiating_web_contents,
content::JsReplace("window.open($1, $2, $3);",
maybe_installation_->GetAppUrl(), target,
features)));
observer.Wait();
Browser* app_browser = FindSystemWebAppBrowser(
browser()->profile(), maybe_installation_->GetType());
EXPECT_TRUE(app_browser);
EXPECT_EQ(app_browser, chrome::FindLastActive());
// There should be three browsers: the default one (new tab page), the
// initiating system app, the link capturing system app.
EXPECT_EQ(3U, chrome::GetTotalBrowserCount());
EXPECT_EQ(Browser::TYPE_APP, app_browser->type());
EXPECT_FALSE(app_browser->app_controller()->ShouldShowCustomTabBar());
app_browser->window()->Close();
base::RunLoop().RunUntilIdle();
// Check the initiating browser window is intact.
EXPECT_EQ(kInitiatingAppUrl,
initiating_web_contents->GetLastCommittedURL());
}
}
}
IN_PROC_BROWSER_TEST_P(SystemWebAppLinkCaptureBrowserTest,
CaptureToOpenedWindowAndNavigateURL) {
WaitForTestSystemAppInstall();
Browser* app_browser;
content::WebContents* web_contents =
LaunchApp(maybe_installation_->GetType(), &app_browser);
GURL kInitiatingChromeUrl = GURL(chrome::kChromeUIAboutURL);
NavigateToURLAndWait(browser(), kInitiatingChromeUrl);
EXPECT_EQ(kInitiatingChromeUrl, browser()
->tab_strip_model()
->GetActiveWebContents()
->GetLastCommittedURL());
const GURL kPageURL = maybe_installation_->GetAppUrl().Resolve("/page2.html");
content::TestNavigationObserver observer(web_contents);
EXPECT_TRUE(content::ExecuteScript(
browser()->tab_strip_model()->GetActiveWebContents(),
content::JsReplace("let el = document.createElement('a');"
"el.href = $1;"
"el.textContent = 'Link to SWA Page 2';"
"document.body.appendChild(el);"
"el.click();",
kPageURL)));
observer.Wait();
EXPECT_EQ(kPageURL, app_browser->tab_strip_model()
->GetActiveWebContents()
->GetLastCommittedURL());
}
// TODO(crbug.com/1109594): Update this when we decide if SWAs can be
// link-captured to standalone incognito windows. Currently, the SWA gets
// launched into a standalone browser window in incognito profile.
IN_PROC_BROWSER_TEST_P(SystemWebAppLinkCaptureBrowserTest,
IncognitoBrowserOmniboxLinkCapture) {
WaitForTestSystemAppInstall();
Browser* incognito_browser = CreateIncognitoBrowser();
browser()->window()->Close();
base::RunLoop().RunUntilIdle();
content::TestNavigationObserver observer(maybe_installation_->GetAppUrl());
observer.StartWatchingNewWebContents();
incognito_browser->window()->GetLocationBar()->FocusLocation(true);
ui_test_utils::SendToOmniboxAndSubmit(
incognito_browser, maybe_installation_->GetAppUrl().spec());
observer.Wait();
Browser* app_browser = FindSystemWebAppBrowser(
incognito_browser->profile(), maybe_installation_->GetType());
EXPECT_TRUE(app_browser);
EXPECT_EQ(app_browser, chrome::FindLastActive());
EXPECT_EQ(2U, chrome::GetTotalBrowserCount());
EXPECT_EQ(Browser::TYPE_APP, app_browser->type());
EXPECT_FALSE(app_browser->app_controller()->ShouldShowCustomTabBar());
}
INSTANTIATE_SYSTEM_WEB_APP_MANAGER_TEST_SUITE_ALL_INSTALL_TYPES_P(
SystemWebAppLinkCaptureBrowserTest);
} // namespace web_app