1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 // TODO(dbeam): test for loading upacked extensions?
7 GEN('#include "chrome/browser/ui/webui/extensions/' +
8 'extension_settings_browsertest.h"');
10 // The id of the extension from |InstallGoodExtension|.
11 var GOOD_EXTENSION_ID = 'ldnnhddmnhbkjipkidpdiheffobcpfmf';
13 // The id of the extension from |InstallErrorsExtension|.
14 var ERROR_EXTENSION_ID = 'pdlpifnclfacjobnmbpngemkalkjamnf';
17 * Test C++ fixture for settings WebUI testing.
19 * @extends {testing.Test}
21 function ExtensionSettingsUIBrowserTest() {}
24 * TestFixture for extension settings WebUI testing.
25 * @extends {testing.Test}
28 function ExtensionSettingsWebUITest() {}
30 ExtensionSettingsWebUITest.prototype = {
31 __proto__: testing.Test.prototype,
37 runAccessibilityChecks: true,
40 accessibilityIssuesAreErrors: true,
43 * A URL to load before starting each test.
47 browsePreload: 'chrome://extensions-frame/',
50 typedefCppFixture: 'ExtensionSettingsUIBrowserTest',
54 testing.Test.disableAnimationsAndTransitions();
58 * Holds an array of steps that should happen in order during a test.
59 * The last step should be |testDone|.
60 * @protected {Array<!Function>}
65 * Advances to the next step in the test. Every step should call this.
68 nextStep: function() {
69 assertTrue(this.steps.length > 0);
70 this.steps.shift().call(this);
74 * Will wait for the page to load before calling the next step. This should be
75 * the first step in every test.
78 waitForPageLoad: function() {
79 assertEquals(this.browsePreload, document.location.href);
80 var extensionList = getRequiredElement('extension-settings-list');
81 extensionList.loadFinished.then(this.nextStep.bind(this));
85 enableDeveloperMode: function() {
86 // Toggling developer mode triggers a page update, so we need to be able to
87 // wait for the update to finish.
88 $('extension-settings-list').resetLoadFinished();
89 var waitForPage = this.waitForPageLoad.bind(this);
90 document.addEventListener('devControlsVisibilityUpdated',
91 function devCallback() {
92 // Callback should only be handled once.
93 document.removeEventListener('devControlsVisibilityUpdated', devCallback);
95 chrome.developerPrivate.getProfileConfiguration(function(profileInfo) {
96 assertTrue(extensionSettings.classList.contains('dev-mode'));
97 assertTrue(profileInfo.inDeveloperMode);
99 // This event isn't thrown because transitions are disabled.
100 // Ensure transition here so that any dependent code does not break.
101 ensureTransitionEndEvent($('dev-controls'), 0);
107 var extensionSettings = getRequiredElement('extension-settings');
108 assertFalse(extensionSettings.classList.contains('dev-mode'));
109 $('toggle-dev-on').click();
113 testDeveloperMode: function() {
114 var next = this.nextStep.bind(this);
115 var checkDevModeIsOff = function() {
116 chrome.developerPrivate.getProfileConfiguration(function(profileInfo) {
117 assertFalse(profileInfo.inDeveloperMode);
121 this.steps = [this.waitForPageLoad,
123 this.enableDeveloperMode,
129 // Flaky: http://crbug.com/505506.
130 // Verify that developer mode doesn't change behavior when the number of
131 // extensions changes.
132 TEST_F('ExtensionSettingsWebUITest', 'DISABLED_testDeveloperModeNoExtensions',
134 this.testDeveloperMode();
137 TEST_F('ExtensionSettingsWebUITest', 'testEmptyExtensionList', function() {
138 var verifyListIsHiddenAndEmpty = function() {
139 assertTrue($('extension-list-wrapper').hidden);
140 assertFalse($('no-extensions').hidden);
141 assertEquals(0, $('extension-settings-list').childNodes.length);
145 this.steps = [this.waitForPageLoad, verifyListIsHiddenAndEmpty, testDone];
149 TEST_F('ExtensionSettingsWebUITest', 'testChromeSendHandled', function() {
150 var testPackExtenion = function() {
151 // This dialog should be hidden at first.
152 assertFalse($('pack-extension-overlay').classList.contains('showing'));
154 // Show the dialog, which triggers a chrome.send() for metrics purposes.
155 cr.dispatchSimpleEvent($('pack-extension'), 'click');
156 assertTrue($('pack-extension-overlay').classList.contains('showing'));
160 this.steps = [this.waitForPageLoad, testPackExtenion, testDone];
165 * @param {chrome.developerPrivate.EventType} eventType
166 * @param {function():void} callback
169 function UpdateListener(eventType, callback) {
170 this.callback_ = callback;
171 this.eventType_ = eventType;
172 this.onItemStateChangedListener_ = this.onItemStateChanged_.bind(this);
173 chrome.developerPrivate.onItemStateChanged.addListener(
174 this.onItemStateChangedListener_);
177 UpdateListener.prototype = {
179 onItemStateChanged_: function(data) {
180 if (this.eventType_ == data.event_type) {
181 window.setTimeout(function() {
182 chrome.developerPrivate.onItemStateChanged.removeListener(
183 this.onItemStateChangedListener_);
190 function BasicExtensionSettingsWebUITest() {}
192 BasicExtensionSettingsWebUITest.prototype = {
193 __proto__: ExtensionSettingsWebUITest.prototype,
196 testGenPreamble: function() {
197 // Install multiple types of extensions to ensure we handle each type.
198 // TODO(devlin): There are more types to add here.
199 GEN(' InstallGoodExtension();');
200 GEN(' InstallErrorsExtension();');
201 GEN(' InstallSharedModule();');
202 GEN(' InstallPackagedApp();');
204 GEN(' SetAutoConfirmUninstall();');
208 verifyDisabledWorks: function() {
209 var listener = new UpdateListener(
210 chrome.developerPrivate.EventType.UNLOADED,
212 var node = getRequiredElement(GOOD_EXTENSION_ID);
213 assertTrue(node.classList.contains('inactive-extension'));
216 chrome.management.setEnabled(GOOD_EXTENSION_ID, false);
220 verifyEnabledWorks: function() {
221 var listener = new UpdateListener(
222 chrome.developerPrivate.EventType.LOADED,
224 var node = getRequiredElement(GOOD_EXTENSION_ID);
225 assertFalse(node.classList.contains('inactive-extension'));
228 chrome.management.setEnabled(GOOD_EXTENSION_ID, true);
232 verifyUninstallWorks: function() {
233 var listener = new UpdateListener(
234 chrome.developerPrivate.EventType.UNINSTALLED,
236 assertEquals(null, $(GOOD_EXTENSION_ID));
239 chrome.test.runWithUserGesture(function() {
240 chrome.management.uninstall(GOOD_EXTENSION_ID);
245 // Verify that developer mode doesn't change behavior when the number of
246 // extensions changes.
247 TEST_F('BasicExtensionSettingsWebUITest', 'testDeveloperModeManyExtensions',
249 this.testDeveloperMode();
252 TEST_F('BasicExtensionSettingsWebUITest', 'testDisable', function() {
253 this.steps = [this.waitForPageLoad, this.verifyDisabledWorks, testDone];
257 TEST_F('BasicExtensionSettingsWebUITest', 'testEnable', function() {
258 this.steps = [this.waitForPageLoad,
259 this.verifyDisabledWorks,
260 this.verifyEnabledWorks,
265 TEST_F('BasicExtensionSettingsWebUITest', 'testUninstall', function() {
266 this.steps = [this.waitForPageLoad, this.verifyUninstallWorks, testDone];
270 TEST_F('BasicExtensionSettingsWebUITest', 'testNonEmptyExtensionList',
272 var verifyListIsNotHiddenAndEmpty = function() {
273 assertFalse($('extension-list-wrapper').hidden);
274 assertTrue($('no-extensions').hidden);
275 assertGT($('extension-settings-list').childNodes.length, 0);
279 this.steps = [this.waitForPageLoad, verifyListIsNotHiddenAndEmpty, testDone];
283 function AutoScrollExtensionSettingsWebUITest() {}
286 * A variation for testing auto-scroll when an id query param is passed in the
289 * @extends {BasicExtensionSettingsWebUITest}
291 AutoScrollExtensionSettingsWebUITest.prototype = {
292 __proto__: BasicExtensionSettingsWebUITest.prototype,
295 browsePreload: 'chrome://extensions-frame/?id=' + GOOD_EXTENSION_ID,
298 testGenPreamble: function() {
299 BasicExtensionSettingsWebUITest.prototype.testGenPreamble.call(this);
300 // The window needs to be sufficiently small in order to ensure a scroll bar
302 GEN(' ShrinkWebContentsView();');
306 TEST_F('AutoScrollExtensionSettingsWebUITest', 'testAutoScroll', function() {
307 var checkHasScrollbar = function() {
308 assertGT(document.body.scrollHeight, document.body.clientHeight);
311 var checkIsScrolled = function() {
312 assertGT(document.body.scrollTop, 0);
315 var checkScrolledToTop = function() {
316 assertEquals(0, document.body.scrollTop);
319 var scrollToTop = function() {
320 document.body.scrollTop = 0;
323 // Test that a) autoscroll works on first page load and b) updating the
324 // page doesn't result in autoscroll triggering again.
325 this.steps = [this.waitForPageLoad,
329 this.enableDeveloperMode,
335 function ErrorConsoleExtensionSettingsWebUITest() {}
337 ErrorConsoleExtensionSettingsWebUITest.prototype = {
338 __proto__: ExtensionSettingsWebUITest.prototype,
341 testGenPreamble: function() {
342 GEN(' EnableErrorConsole();');
343 GEN(' InstallGoodExtension();');
344 GEN(' InstallErrorsExtension();');
348 // Flaky on all platforms: http://crbug.com/499884, http://crbug.com/463245.
349 TEST_F('ErrorConsoleExtensionSettingsWebUITest',
350 'DISABLED_testErrorListButtonVisibility', function() {
351 var testButtonVisibility = function() {
352 var extensionList = $('extension-list-wrapper');
354 var visibleButtons = extensionList.querySelectorAll(
355 '.errors-link:not([hidden])');
356 expectEquals(1, visibleButtons.length);
358 if (visibleButtons.length > 0) {
359 var errorLink = $(ERROR_EXTENSION_ID).querySelector('.errors-link');
360 expectEquals(visibleButtons[0], errorLink);
362 var errorIcon = errorLink.querySelector('img');
363 expectTrue(errorIcon.classList.contains('extension-error-warning-icon'));
366 var hiddenButtons = extensionList.querySelectorAll('.errors-link[hidden]');
367 expectEquals(1, hiddenButtons.length);
372 this.steps = [this.waitForPageLoad,
373 this.enableDeveloperMode,
374 testButtonVisibility,
380 * TestFixture for extension settings WebUI testing (commands config edition).
381 * @extends {testing.Test}
384 function SettingsCommandsExtensionSettingsWebUITest() {}
386 SettingsCommandsExtensionSettingsWebUITest.prototype = {
387 __proto__: ExtensionSettingsWebUITest.prototype,
390 * A URL to load before starting each test.
394 browsePreload: 'chrome://extensions-frame/configureCommands',
397 TEST_F('SettingsCommandsExtensionSettingsWebUITest', 'testChromeSendHandler',
399 // Just navigating to the page should trigger the chrome.send().
400 var assertOverlayVisible = function() {
401 assertTrue($('extension-commands-overlay').classList.contains('showing'));
405 this.steps = [this.waitForPageLoad, assertOverlayVisible, testDone];
409 TEST_F('SettingsCommandsExtensionSettingsWebUITest', 'extensionSettingsUri',
411 var closeCommandOverlay = function() {
412 assertTrue($('extension-commands-overlay').classList.contains('showing'));
413 assertEquals(window.location.href,
414 'chrome://extensions-frame/configureCommands');
416 // Close command overlay.
417 $('extension-commands-dismiss').click();
419 assertFalse($('extension-commands-overlay').classList.contains('showing'));
423 var checkExtensionsUrl = function() {
424 // After closing the overlay, the URL shouldn't include commands overlay
426 assertEquals(window.location.href, 'chrome://extensions-frame/');
430 this.steps = [this.waitForPageLoad,
439 * @extends {ExtensionSettingsWebUITest}
441 function InstallGoodExtensionSettingsWebUITest() {}
443 InstallGoodExtensionSettingsWebUITest.prototype = {
444 __proto__: ExtensionSettingsWebUITest.prototype,
447 testGenPreamble: function() {
448 GEN(' InstallGoodExtension();');
451 emptyTestForAccessibility() {
452 this.steps = [this.waitForPageLoad, testDone];
457 TEST_F('InstallGoodExtensionSettingsWebUITest', 'testAccessibility',
459 this.emptyTestForAccessibility();
462 TEST_F('InstallGoodExtensionSettingsWebUITest', 'showOptions', function() {
463 var showExtensionOptions = function() {
464 var optionsOverlay = extensions.ExtensionOptionsOverlay.getInstance();
465 optionsOverlay.setExtensionAndShow(GOOD_EXTENSION_ID, 'GOOD!', '',
466 this.nextStep.bind(this));
468 // Preferred size changes don't happen in browser tests. Just fake it.
469 document.querySelector('extensionoptions').onpreferredsizechanged(
470 {width: 500, height: 500});
473 this.steps = [this.waitForPageLoad, showExtensionOptions, testDone];
479 * @extends {InstallGoodExtensionSettingsWebUITest}
481 function ManagedExtensionSettingsWebUITest() {}
483 ManagedExtensionSettingsWebUITest.prototype = {
484 __proto__: InstallGoodExtensionSettingsWebUITest.prototype,
487 testGenPreamble: function() {
488 GEN(' AddManagedPolicyProvider();');
489 InstallGoodExtensionSettingsWebUITest.prototype.testGenPreamble.call(this);
493 TEST_F('ManagedExtensionSettingsWebUITest', 'testAccessibility', function() {
494 this.emptyTestForAccessibility();
499 * @extends {InstallGoodExtensionSettingsWebUITest}
501 function OptionsDialogExtensionSettingsWebUITest() {}
503 OptionsDialogExtensionSettingsWebUITest.prototype = {
504 __proto__: InstallGoodExtensionSettingsWebUITest.prototype,
507 browsePreload: ExtensionSettingsWebUITest.prototype.browsePreload +
508 '?options=' + GOOD_EXTENSION_ID,
511 TEST_F('OptionsDialogExtensionSettingsWebUITest', 'testAccessibility',
513 this.emptyTestForAccessibility();