Files
basilisk55/devtools/client/framework/test/browser_toolbox_options.js
T

318 lines
9.8 KiB
JavaScript

/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
/* import-globals-from shared-head.js */
"use strict";
// Tests that changing preferences in the options panel updates the prefs
// and toggles appropriate things in the toolbox.
var doc = null, toolbox = null, panelWin = null, modifiedPrefs = [];
const {LocalizationHelper} = require("devtools/shared/l10n");
const L10N = new LocalizationHelper("devtools/client/locales/toolbox.properties");
const {PrefObserver} = require("devtools/client/shared/prefs");
add_task(function* () {
const URL = "data:text/html;charset=utf8,test for dynamically registering " +
"and unregistering tools";
registerNewTool();
let tab = yield addTab(URL);
let target = TargetFactory.forTab(tab);
toolbox = yield gDevTools.showToolbox(target);
doc = toolbox.doc;
yield registerNewPerToolboxTool();
yield testSelectTool();
yield testOptionsShortcut();
yield testOptions();
yield testToggleTools();
yield cleanup();
});
function registerNewTool() {
let toolDefinition = {
id: "test-tool",
isTargetSupported: () => true,
visibilityswitch: "devtools.test-tool.enabled",
url: "about:blank",
label: "someLabel"
};
ok(gDevTools, "gDevTools exists");
ok(!gDevTools.getToolDefinitionMap().has("test-tool"),
"The tool is not registered");
gDevTools.registerTool(toolDefinition);
ok(gDevTools.getToolDefinitionMap().has("test-tool"),
"The tool is registered");
}
function registerNewPerToolboxTool() {
let toolDefinition = {
id: "test-pertoolbox-tool",
isTargetSupported: () => true,
visibilityswitch: "devtools.test-pertoolbox-tool.enabled",
url: "about:blank",
label: "perToolboxSomeLabel"
};
ok(gDevTools, "gDevTools exists");
ok(!gDevTools.getToolDefinitionMap().has("test-pertoolbox-tool"),
"The per-toolbox tool is not registered globally");
ok(toolbox, "toolbox exists");
ok(!toolbox.hasAdditionalTool("test-pertoolbox-tool"),
"The per-toolbox tool is not yet registered to the toolbox");
toolbox.addAdditionalTool(toolDefinition);
ok(!gDevTools.getToolDefinitionMap().has("test-pertoolbox-tool"),
"The per-toolbox tool is not registered globally");
ok(toolbox.hasAdditionalTool("test-pertoolbox-tool"),
"The per-toolbox tool has been registered to the toolbox");
}
function* testSelectTool() {
info("Checking to make sure that the options panel can be selected.");
let onceSelected = toolbox.once("options-selected");
toolbox.selectTool("options");
yield onceSelected;
ok(true, "Toolbox selected via selectTool method");
}
function* testOptionsShortcut() {
info("Selecting another tool, then reselecting options panel with keyboard.");
yield toolbox.selectTool("webconsole");
is(toolbox.currentToolId, "webconsole", "webconsole is selected");
synthesizeKeyShortcut(L10N.getStr("toolbox.options.key"));
is(toolbox.currentToolId, "options", "Toolbox selected via shortcut key (1)");
synthesizeKeyShortcut(L10N.getStr("toolbox.options.key"));
is(toolbox.currentToolId, "webconsole", "webconsole is selected (1)");
yield toolbox.selectTool("webconsole");
is(toolbox.currentToolId, "webconsole", "webconsole is selected");
synthesizeKeyShortcut(L10N.getStr("toolbox.help.key"));
is(toolbox.currentToolId, "options", "Toolbox selected via shortcut key (2)");
synthesizeKeyShortcut(L10N.getStr("toolbox.options.key"));
is(toolbox.currentToolId, "webconsole", "webconsole is reselected (2)");
synthesizeKeyShortcut(L10N.getStr("toolbox.help.key"));
is(toolbox.currentToolId, "options", "Toolbox selected via shortcut key (2)");
}
function* testOptions() {
let tool = toolbox.getPanel("options");
panelWin = tool.panelWin;
let prefNodes = tool.panelDoc.querySelectorAll(
"input[type=checkbox][data-pref]");
// Store modified pref names so that they can be cleared on error.
for (let node of tool.panelDoc.querySelectorAll("[data-pref]")) {
let pref = node.getAttribute("data-pref");
modifiedPrefs.push(pref);
}
for (let node of prefNodes) {
let prefValue = GetPref(node.getAttribute("data-pref"));
// Test clicking the checkbox for each options pref
yield testMouseClick(node, prefValue);
// Do again with opposite values to reset prefs
yield testMouseClick(node, !prefValue);
}
let prefSelects = tool.panelDoc.querySelectorAll("select[data-pref]");
for (let node of prefSelects) {
yield testSelect(node);
}
}
function* testSelect(select) {
let pref = select.getAttribute("data-pref");
let options = Array.from(select.options);
info("Checking select for: " + pref);
is(select.options[select.selectedIndex].value, GetPref(pref),
"select starts out selected");
for (let option of options) {
if (options.indexOf(option) === select.selectedIndex) {
continue;
}
let observer = new PrefObserver("devtools.");
let deferred = defer();
let changeSeen = false;
observer.once(pref, () => {
changeSeen = true;
is(GetPref(pref), option.value, "Preference been switched for " + pref);
deferred.resolve();
});
select.selectedIndex = options.indexOf(option);
let changeEvent = new Event("change");
select.dispatchEvent(changeEvent);
yield deferred.promise;
ok(changeSeen, "Correct pref was changed");
observer.destroy();
}
}
function* testMouseClick(node, prefValue) {
let deferred = defer();
let observer = new PrefObserver("devtools.");
let pref = node.getAttribute("data-pref");
let changeSeen = false;
observer.once(pref, () => {
changeSeen = true;
is(GetPref(pref), !prefValue, "New value is correct for " + pref);
deferred.resolve();
});
node.scrollIntoView();
// We use executeSoon here to ensure that the element is in view and
// clickable.
executeSoon(function () {
info("Click event synthesized for pref " + pref);
EventUtils.synthesizeMouseAtCenter(node, {}, panelWin);
});
yield deferred.promise;
ok(changeSeen, "Correct pref was changed");
observer.destroy();
}
function* testToggleTools() {
let toolNodes = panelWin.document.querySelectorAll(
"#default-tools-box input[type=checkbox]:not([data-unsupported])," +
"#additional-tools-box input[type=checkbox]:not([data-unsupported])");
let enabledTools = [...toolNodes].filter(node => node.checked);
let toggleableTools = gDevTools.getDefaultTools()
.filter(tool => {
return tool.visibilityswitch;
})
.concat(gDevTools.getAdditionalTools())
.concat(toolbox.getAdditionalTools());
for (let node of toolNodes) {
let id = node.getAttribute("id");
ok(toggleableTools.some(tool => tool.id === id),
"There should be a toggle checkbox for: " + id);
}
// Store modified pref names so that they can be cleared on error.
for (let tool of toggleableTools) {
let pref = tool.visibilityswitch;
modifiedPrefs.push(pref);
}
// Toggle each tool
for (let node of toolNodes) {
yield toggleTool(node);
}
// Toggle again to reset tool enablement state
for (let node of toolNodes) {
yield toggleTool(node);
}
// Test that a tool can still be added when no tabs are present:
// Disable all tools
for (let node of enabledTools) {
yield toggleTool(node);
}
// Re-enable the tools which are enabled by default
for (let node of enabledTools) {
yield toggleTool(node);
}
// Toggle first, middle, and last tools to ensure that toolbox tabs are
// inserted in order
let firstTool = toolNodes[0];
let middleTool = toolNodes[(toolNodes.length / 2) | 0];
let lastTool = toolNodes[toolNodes.length - 1];
yield toggleTool(firstTool);
yield toggleTool(firstTool);
yield toggleTool(middleTool);
yield toggleTool(middleTool);
yield toggleTool(lastTool);
yield toggleTool(lastTool);
}
function* toggleTool(node) {
let deferred = defer();
let toolId = node.getAttribute("id");
if (node.checked) {
gDevTools.once("tool-unregistered",
checkUnregistered.bind(null, toolId, deferred));
} else {
gDevTools.once("tool-registered",
checkRegistered.bind(null, toolId, deferred));
}
node.scrollIntoView();
EventUtils.synthesizeMouseAtCenter(node, {}, panelWin);
yield deferred.promise;
}
function checkUnregistered(toolId, deferred, event, data) {
if (data == toolId) {
ok(true, "Correct tool removed");
// checking tab on the toolbox
ok(!doc.getElementById("toolbox-tab-" + toolId),
"Tab removed for " + toolId);
} else {
ok(false, "Something went wrong, " + toolId + " was not unregistered");
}
deferred.resolve();
}
function checkRegistered(toolId, deferred, event, data) {
if (data == toolId) {
ok(true, "Correct tool added back");
// checking tab on the toolbox
let button = doc.getElementById("toolbox-tab-" + toolId);
ok(button, "Tab added back for " + toolId);
} else {
ok(false, "Something went wrong, " + toolId + " was not registered");
}
deferred.resolve();
}
function GetPref(name) {
let type = Services.prefs.getPrefType(name);
switch (type) {
case Services.prefs.PREF_STRING:
return Services.prefs.getCharPref(name);
case Services.prefs.PREF_INT:
return Services.prefs.getIntPref(name);
case Services.prefs.PREF_BOOL:
return Services.prefs.getBoolPref(name);
default:
throw new Error("Unknown type");
}
}
function* cleanup() {
gDevTools.unregisterTool("test-tool");
yield toolbox.destroy();
gBrowser.removeCurrentTab();
for (let pref of modifiedPrefs) {
Services.prefs.clearUserPref(pref);
}
toolbox = doc = panelWin = modifiedPrefs = null;
}