#include <stddef.h>
#include "base/strings/utf_string_conversions.h"
#include "build/build_config.h"
#include "chrome/browser/extensions/extension_action_test_util.h"
#include "chrome/browser/extensions/extension_browsertest.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/browser_window.h"
#include "content/public/test/browser_test.h"
#include "extensions/browser/extension_action.h"
#include "extensions/browser/extension_action_manager.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/common/extension.h"
#include "extensions/common/switches.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
namespace extensions {
namespace {
const std::string kSubscribePageAction = "subscribe_page_action_v2/src";
const std::string kFeedPage = "/feeds/feed.html";
const std::string kNoFeedPage = "/feeds/no_feed.html";
const std::string kHashPageA =
"/extensions/api_test/page_action/hash_change/test_page_A.html";
const std::string kHashPageAHash = kHashPageA + "#asdf";
const std::string kHashPageB =
"/extensions/api_test/page_action/hash_change/test_page_B.html";
using ContextType = extensions::browser_test_util::ContextType;
class PageActionBrowserTest : public ExtensionBrowserTest,
public testing::WithParamInterface<ContextType> {
public:
PageActionBrowserTest() : ExtensionBrowserTest(GetParam()) {}
~PageActionBrowserTest() override = default;
PageActionBrowserTest(const PageActionBrowserTest& other) = delete;
PageActionBrowserTest& operator=(const PageActionBrowserTest& other) = delete;
};
INSTANTIATE_TEST_SUITE_P(PersistentBackground,
PageActionBrowserTest,
::testing::Values(ContextType::kPersistentBackground));
INSTANTIATE_TEST_SUITE_P(ServiceWorker,
PageActionBrowserTest,
::testing::Values(ContextType::kServiceWorkerMV2));
IN_PROC_BROWSER_TEST_P(PageActionBrowserTest, PageActionCrash25562) {
ASSERT_TRUE(embedded_test_server()->Start());
ASSERT_TRUE(LoadExtension(
test_data_dir_.AppendASCII("browsertest")
.AppendASCII("crash_25562")));
GURL feed_url = embedded_test_server()->GetURL(kFeedPage);
ASSERT_TRUE(NavigateToURL(GetActiveWebContents(), feed_url));
ASSERT_TRUE(WaitForPageActionVisibilityChangeTo(1));
}
IN_PROC_BROWSER_TEST_P(PageActionBrowserTest, PageAction) {
ASSERT_TRUE(embedded_test_server()->Start());
ASSERT_TRUE(LoadExtension(
test_data_dir_.AppendASCII(kSubscribePageAction)));
ASSERT_TRUE(WaitForPageActionVisibilityChangeTo(0));
GURL feed_url = embedded_test_server()->GetURL(kFeedPage);
ASSERT_TRUE(NavigateToURL(GetActiveWebContents(), feed_url));
ASSERT_TRUE(WaitForPageActionVisibilityChangeTo(1));
GURL no_feed = embedded_test_server()->GetURL(kNoFeedPage);
ASSERT_TRUE(NavigateToURL(GetActiveWebContents(), no_feed));
ASSERT_TRUE(WaitForPageActionVisibilityChangeTo(0));
}
IN_PROC_BROWSER_TEST_P(PageActionBrowserTest, SameDocumentNavigation) {
ASSERT_TRUE(embedded_test_server()->Start());
base::FilePath extension_path(test_data_dir_.AppendASCII("api_test")
.AppendASCII("page_action")
.AppendASCII("hash_change"));
ASSERT_TRUE(LoadExtension(extension_path));
GURL feed_url = embedded_test_server()->GetURL(kHashPageA);
ASSERT_TRUE(NavigateToURL(GetActiveWebContents(), feed_url));
ASSERT_TRUE(WaitForPageActionVisibilityChangeTo(1));
feed_url = embedded_test_server()->GetURL(kHashPageAHash);
ASSERT_TRUE(NavigateToURL(GetActiveWebContents(), feed_url));
ASSERT_TRUE(WaitForPageActionVisibilityChangeTo(1));
feed_url = embedded_test_server()->GetURL(kHashPageB);
ASSERT_TRUE(NavigateToURL(GetActiveWebContents(), feed_url));
ASSERT_TRUE(WaitForPageActionVisibilityChangeTo(0));
}
IN_PROC_BROWSER_TEST_P(PageActionBrowserTest, UnloadPageAction) {
ASSERT_TRUE(embedded_test_server()->Start());
base::FilePath extension_path(
test_data_dir_.AppendASCII(kSubscribePageAction));
ASSERT_TRUE(LoadExtension(extension_path));
GURL feed_url = embedded_test_server()->GetURL(kFeedPage);
content::WebContents* tab = GetActiveWebContents();
ASSERT_TRUE(NavigateToURL(tab, feed_url));
EXPECT_EQ(1u, extension_action_test_util::GetTotalPageActionCount(tab));
UnloadExtension(last_loaded_extension_id());
EXPECT_EQ(0u, extension_action_test_util::GetTotalPageActionCount(tab));
}
IN_PROC_BROWSER_TEST_P(PageActionBrowserTest, PageActionRefreshCrash) {
ExtensionRegistry* registry = extensions::ExtensionRegistry::Get(profile());
size_t size_before = registry->enabled_extensions().size();
base::FilePath base_path = test_data_dir_.AppendASCII("browsertest")
.AppendASCII("crash_44415");
const Extension* extensionA = LoadExtension(base_path.AppendASCII("ExtA"));
ASSERT_TRUE(extensionA);
ASSERT_TRUE(WaitForPageActionVisibilityChangeTo(1));
ASSERT_EQ(size_before + 1, registry->enabled_extensions().size());
const Extension* extensionB = LoadExtension(base_path.AppendASCII("ExtB"));
ASSERT_TRUE(extensionB);
ASSERT_TRUE(WaitForPageActionVisibilityChangeTo(2));
ASSERT_EQ(size_before + 2, registry->enabled_extensions().size());
std::string idA = extensionA->id();
LOG(INFO) << "Reloading extensionA";
ReloadExtension(extensionA->id());
ASSERT_EQ(size_before + 2, registry->enabled_extensions().size());
extensionA = registry->enabled_extensions().GetByID(idA);
LOG(INFO) << "Reloading extensionB";
ReloadExtension(extensionB->id());
LOG(INFO) << "Reloading extensionA again";
ReloadExtension(extensionA->id());
}
}
}