blob: 9a98e916dee7e95e8914312c61f8638002ceb818 [file] [log] [blame]
// Copyright 2020 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/views/extensions/extensions_toolbar_interactive_uitest.h"
#include <vector>
#include "base/path_service.h"
#include "base/strings/stringprintf.h"
#include "chrome/browser/extensions/chrome_test_extension_loader.h"
#include "chrome/browser/extensions/extension_tab_util.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/views/extensions/extensions_toolbar_container.h"
#include "chrome/browser/ui/views/frame/browser_view.h"
#include "chrome/browser/ui/views/toolbar/toolbar_view.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/test/base/ui_test_utils.h"
#include "components/crx_file/id_util.h"
#include "content/public/browser/web_contents.h"
#include "content/public/test/test_navigation_observer.h"
#include "extensions/browser/browsertest_util.h"
#include "extensions/browser/extension_registrar.h"
#include "extensions/browser/extension_system.h"
#include "extensions/common/extension_builder.h"
#include "extensions/test/test_extension_dir.h"
#include "net/dns/mock_host_resolver.h"
#include "ui/views/layout/animating_layout_manager_test_util.h"
#include "ui/views/view_utils.h"
ExtensionsToolbarUITest::ExtensionsToolbarUITest() = default;
ExtensionsToolbarUITest::~ExtensionsToolbarUITest() = default;
Profile* ExtensionsToolbarUITest::profile() {
return browser()->profile();
}
scoped_refptr<const extensions::Extension>
ExtensionsToolbarUITest::LoadTestExtension(const std::string& path,
bool allow_incognito) {
extensions::ChromeTestExtensionLoader loader(profile());
loader.set_allow_incognito_access(allow_incognito);
base::FilePath test_data_dir;
base::PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir);
scoped_refptr<const extensions::Extension> extension =
loader.LoadExtension(test_data_dir.AppendASCII(path));
AppendExtension(extension);
// Loading an extension can result in the container changing visibility.
// Allow it to finish laying out appropriately.
auto* container = GetExtensionsToolbarContainer();
container->GetWidget()->LayoutRootViewIfNecessary();
return extension;
}
scoped_refptr<const extensions::Extension>
ExtensionsToolbarUITest::ForceInstallExtension(const std::string& name) {
scoped_refptr<const extensions::Extension> extension =
extensions::ExtensionBuilder(name)
.SetLocation(extensions::mojom::ManifestLocation::kExternalPolicy)
.SetID(crx_file::id_util::GenerateId(name))
.Build();
extensions::ExtensionRegistrar::Get(browser()->profile())
->AddExtension(extension);
return extension;
}
scoped_refptr<const extensions::Extension>
ExtensionsToolbarUITest::InstallExtension(const std::string& name) {
return InstallExtensionWithHostPermissions(name, std::string());
}
scoped_refptr<const extensions::Extension>
ExtensionsToolbarUITest::InstallExtensionWithHostPermissions(
const std::string& name,
const std::string& host_permission,
const std::string& content_script_run_location) {
std::string host_permissions_entry;
if (!host_permission.empty()) {
host_permissions_entry = base::StringPrintf(
R"(
"host_permissions": ["%s"],
)",
host_permission.c_str());
}
extensions::TestExtensionDir extension_dir;
std::string content_script_entry;
if (!content_script_run_location.empty()) {
content_script_entry = base::StringPrintf(
R"(
"content_scripts": [{
"matches": ["%s"],
"js": ["script.js"],
"run_at": "%s"
}], )",
host_permission.c_str(), content_script_run_location.c_str());
extension_dir.WriteFile(FILE_PATH_LITERAL("script.js"),
base::StringPrintf("chrome.test.sendMessage('%s');",
"injection succeeded"));
}
extension_dir.WriteManifest(base::StringPrintf(
R"({
"name": "%s",
"manifest_version": 3,
%s
%s
"version": "0.1"
})",
name.c_str(), content_script_entry.c_str(),
host_permissions_entry.c_str()));
scoped_refptr<const extensions::Extension> extension =
extensions::ChromeTestExtensionLoader(profile()).LoadExtension(
extension_dir.UnpackedPath());
AppendExtension(extension);
return extension;
}
void ExtensionsToolbarUITest::AppendExtension(
scoped_refptr<const extensions::Extension> extension) {
extensions_.push_back(std::move(extension));
}
void ExtensionsToolbarUITest::DisableExtension(
const extensions::ExtensionId& extension_id) {
extensions::ExtensionRegistrar::Get(browser()->profile())
->DisableExtension(extension_id,
{extensions::disable_reason::DISABLE_USER_ACTION});
}
void ExtensionsToolbarUITest::SetUpIncognitoBrowser() {
incognito_browser_ = CreateIncognitoBrowser();
}
void ExtensionsToolbarUITest::SetUpOnMainThread() {
DialogBrowserTest::SetUpOnMainThread();
host_resolver()->AddRule("*", "127.0.0.1");
views::test::ReduceAnimationDuration(GetExtensionsToolbarContainer());
}
ExtensionsToolbarContainer*
ExtensionsToolbarUITest::GetExtensionsToolbarContainer() const {
return GetExtensionsToolbarContainerForBrowser(browser());
}
ExtensionsToolbarContainer*
ExtensionsToolbarUITest::GetExtensionsToolbarContainerForBrowser(
Browser* browser) const {
return browser->GetBrowserView().toolbar()->extensions_container();
}
std::vector<ToolbarActionView*> ExtensionsToolbarUITest::GetToolbarActionViews()
const {
return GetToolbarActionViewsForBrowser(browser());
}
std::vector<ToolbarActionView*>
ExtensionsToolbarUITest::GetToolbarActionViewsForBrowser(
Browser* browser) const {
std::vector<ToolbarActionView*> views;
for (views::View* view :
GetExtensionsToolbarContainerForBrowser(browser)->children()) {
if (views::IsViewClass<ToolbarActionView>(view)) {
views.push_back(static_cast<ToolbarActionView*>(view));
}
}
return views;
}
std::vector<ToolbarActionView*>
ExtensionsToolbarUITest::GetVisibleToolbarActionViews() const {
auto views = GetToolbarActionViews();
std::erase_if(views, [](views::View* view) { return !view->GetVisible(); });
return views;
}
ExtensionsToolbarButton* ExtensionsToolbarUITest::extensions_button() {
return GetExtensionsToolbarContainer()->GetExtensionsButton();
}
ExtensionsMenuCoordinator* ExtensionsToolbarUITest::menu_coordinator() {
return GetExtensionsToolbarContainer()
->GetExtensionsMenuCoordinatorForTesting();
}
bool ExtensionsToolbarUITest::DidInjectScript(
content::WebContents* web_contents) {
return extensions::browsertest_util::DidChangeTitle(
*web_contents, /*original_title=*/u"OK",
/*changed_title=*/u"success");
}
void ExtensionsToolbarUITest::NavigateTo(const GURL& url) {
content::TestNavigationObserver observer(
browser()->tab_strip_model()->GetActiveWebContents());
ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
EXPECT_TRUE(observer.last_navigation_succeeded());
}
void ExtensionsToolbarUITest::AddHostAccessRequest(
const extensions::Extension& extension,
content::WebContents* web_contents) {
int tab_id = extensions::ExtensionTabUtil::GetTabId(web_contents);
extensions::PermissionsManager::Get(profile())->AddHostAccessRequest(
web_contents, tab_id, extension);
}
void ExtensionsToolbarUITest::ClickButton(views::Button* button) const {
ui::MouseEvent press_event(ui::EventType::kMousePressed, gfx::Point(),
gfx::Point(), base::TimeTicks(),
ui::EF_LEFT_MOUSE_BUTTON, 0);
button->OnMousePressed(press_event);
ui::MouseEvent release_event(ui::EventType::kMouseReleased, gfx::Point(),
gfx::Point(), base::TimeTicks(),
ui::EF_LEFT_MOUSE_BUTTON, 0);
button->OnMouseReleased(release_event);
}
void ExtensionsToolbarUITest::WaitForAnimation() {
views::test::WaitForAnimatingLayoutManager(GetExtensionsToolbarContainer());
}