Commit cf245935 authored by Istiaque Ahmed's avatar Istiaque Ahmed Committed by Commit Bot

[Extension SW] Add a test for management.uninstall.

This CL exercises user gesture code with an actual API
(management.uninstall) that requires user gesture.

The test makes one extension uninstall another extension
via management.uninstall API. The test runs as both event page
and Service Worker based extension.

Bug: 977629
Test: None, test only change to improve SW test coverage.
Change-Id: I21b9fadd14d035909b6fbe4c310e94cd1e9e375e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1696239Reviewed-by: default avatarDavid Bertoni <dbertoni@chromium.org>
Commit-Queue: Istiaque Ahmed <lazyboy@chromium.org>
Cr-Commit-Position: refs/heads/master@{#677126}
parent 5848abe0
// Copyright 2019 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 "chrome/browser/extensions/extension_action_runner.h"
#include "chrome/browser/extensions/extension_apitest.h"
#include "chrome/test/base/ui_test_utils.h"
#include "extensions/browser/extension_dialog_auto_confirm.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/test/extension_test_message_listener.h"
#include "extensions/test/result_catcher.h"
namespace extensions {
namespace {
enum class ContextType {
kEventPage,
kServiceWorker,
};
// Returns the newly added WebContents.
// TODO(lazyboy): We have at least 3 versions of this AddTab within
// //extensions, put this in a central place and use that instead.
content::WebContents* AddTab(Browser* browser, const GURL& url) {
int starting_tab_count = browser->tab_strip_model()->count();
ui_test_utils::NavigateToURLWithDisposition(
browser, url, WindowOpenDisposition::NEW_FOREGROUND_TAB,
ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
int tab_count = browser->tab_strip_model()->count();
EXPECT_EQ(starting_tab_count + 1, tab_count);
return browser->tab_strip_model()->GetActiveWebContents();
}
} // namespace
// Tests management API from a non-persistent extension (event page or
// Service Worker).
//
// TODO(lazyboy): Move ServiceWorkerBasedBackgroundTest.UninstallSelf here.
class ManagementApiNonPersistentApiTest
: public ExtensionApiTest,
public testing::WithParamInterface<ContextType> {
protected:
const Extension* LoadNonPersistentExtension(const char* relative_path) {
return LoadExtensionWithFlags(test_data_dir_.AppendASCII(relative_path),
GetParam() == ContextType::kEventPage
? kFlagNone
: kFlagRunAsServiceWorkerBasedExtension);
}
};
// Tests chrome.management.uninstall with a real user gesture
// (i.e. browserAction.onClicked event).
IN_PROC_BROWSER_TEST_P(ManagementApiNonPersistentApiTest,
UninstallViaBrowserAction) {
const Extension* extension_b = LoadNonPersistentExtension(
"management/uninstall_via_browser_action/extension_b");
ASSERT_TRUE(extension_b);
const ExtensionId extension_b_id = extension_b->id();
ExtensionRegistry* registry = ExtensionRegistry::Get(profile());
// extension_b should be installed.
// Note: For the purpose of this test, just checking whether the extension is
// installed or not (ExtensionRegistry::EVERYTHING)
// is enough. But for clarity, we check for enabled-ness
// (ExtensionRegistry::ENABLED) here.
EXPECT_TRUE(
registry->GetExtensionById(extension_b_id, ExtensionRegistry::ENABLED));
// Load extension_a and wait for browserAction.onClicked listener
// registration.
ExtensionTestMessageListener listener_added("ready", false);
const Extension* extension_a = LoadNonPersistentExtension(
"management/uninstall_via_browser_action/extension_a");
ASSERT_TRUE(extension_a);
EXPECT_TRUE(listener_added.WaitUntilSatisfied());
// We need to accept uninstallation prompt since this is not a
// self-uninstallation.
ScopedTestDialogAutoConfirm auto_confirm_uninstall(
ScopedTestDialogAutoConfirm::ACCEPT);
ResultCatcher catcher;
// Click on browser action to start the test, |extension_a| will uninstall
// |extension_b|.
{
content::WebContents* web_contents = AddTab(browser(), GURL("about:blank"));
ASSERT_TRUE(web_contents);
ExtensionActionRunner::GetForWebContents(
browser()->tab_strip_model()->GetActiveWebContents())
->RunAction(extension_a, true);
}
EXPECT_TRUE(catcher.GetNextResult()) << message_;
// extension_b should be gone.
EXPECT_FALSE(registry->GetExtensionById(extension_b_id,
ExtensionRegistry::EVERYTHING));
}
INSTANTIATE_TEST_SUITE_P(EventPage,
ManagementApiNonPersistentApiTest,
::testing::Values(ContextType::kEventPage));
INSTANTIATE_TEST_SUITE_P(ServiceWorker,
ManagementApiNonPersistentApiTest,
::testing::Values(ContextType::kServiceWorker));
} // namespace extensions
......@@ -1554,6 +1554,7 @@ if (!is_android) {
"../browser/extensions/api/input_ime/input_ime_apitest_chromeos.cc",
"../browser/extensions/api/instance_id/instance_id_apitest.cc",
"../browser/extensions/api/management/management_api_browsertest.cc",
"../browser/extensions/api/management/management_api_non_persistent_apitest.cc",
"../browser/extensions/api/management/management_apitest.cc",
"../browser/extensions/api/management/management_browsertest.cc",
"../browser/extensions/api/messaging/native_messaging_apitest.cc",
......
// Copyright 2019 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.
chrome.browserAction.onClicked.addListener(() => {
// We should be running with a user gesture.
chrome.test.assertTrue(chrome.test.isProcessingUserGesture());
// Uninstall the extension named 'ExtensionB'.
chrome.management.getAll(chrome.test.callbackPass(items => {
var extension = items.find(item => {
return item.name == 'ExtensionB';
});
chrome.test.assertTrue(extension != undefined);
chrome.test.assertTrue(extension.id != undefined);
chrome.management.uninstall(extension.id, chrome.test.callbackPass(() => {
chrome.test.notifyPass();
}));
}));
});
chrome.test.sendMessage('ready');
{
"name": "ExtensionA",
"description": "Uninstalls ExtensionB with management.uninstall",
"version": "1.0",
"manifest_version": 2,
"permissions": ["management"],
// Note: This extension will also be loaded as SW extension in tests.
"background": {"scripts": ["background.js"], "persistent": false},
"browser_action": {}
}
// Copyright 2019 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.
console.log('extension_b does nothing, yet gets uninstalled :(');
{
"name": "ExtensionB",
"description": "Helper extension that gets uninstalled during test.",
"version": "1.0",
"manifest_version": 2,
// Note: This extension will also be loaded as SW extension in tests.
"background": {"scripts": ["background.js"], "persistent": false}
}
......@@ -8,8 +8,9 @@ chrome.browserAction.onClicked.addListener(() => {
chrome.test.assertFalse(initialUserGesture);
// We should be running with a user gesture.
// TODO(lazyboy): isProcessingUserGesture() only performs renderer level
// checks, also call an actual API that requires gesture.
// Note: isProcessingUserGesture() only performs renderer level
// checks. There are other tests that call APIs that use actual
// gesture.
chrome.test.assertTrue(chrome.test.isProcessingUserGesture());
// Call an API so we can check gesture state in the callback.
chrome.tabs.create({url: chrome.runtime.getURL('page.html')}, () => {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment