Merge mozilla-central to mozilla-inbound

This commit is contained in:
Carsten "Tomcat" Book 2016-01-21 12:29:20 +01:00
Родитель 89af1d5165 adbf945ebf
Коммит 1f6cfe0ec7
245 изменённых файлов: 3500 добавлений и 2030 удалений

Просмотреть файл

@ -21,7 +21,7 @@
<!--
B2G repositories for all targets
-->
<project name="gaia" path="gaia" remote="mozillaorg" revision="efd70ba6a54849dcef696abf1652cf74daa07899"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="619766a1ce78d50fb8a3b5a9e0821c335a0ed7ee"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="35dccb3127db8f39f20b985ad312d2cd44780669"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="99c333dab00ed79baff9e1cf76b320aee8e1c123"/>
<project name="platform_hardware_libhardware_moz" path="hardware/libhardware_moz" remote="b2g" revision="fdf3a143dc777e5f9d33a88373af7ea161d3b440"/>

Просмотреть файл

@ -21,12 +21,12 @@
<!--
B2G repositories for all targets
-->
<project name="gaia" path="gaia" remote="mozillaorg" revision="efd70ba6a54849dcef696abf1652cf74daa07899"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="619766a1ce78d50fb8a3b5a9e0821c335a0ed7ee"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="35dccb3127db8f39f20b985ad312d2cd44780669"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="99c333dab00ed79baff9e1cf76b320aee8e1c123"/>
<project name="platform_hardware_libhardware_moz" path="hardware/libhardware_moz" remote="b2g" revision="fdf3a143dc777e5f9d33a88373af7ea161d3b440"/>
<!-- B2G specific things. -->
<project name="platform_build" path="build" remote="b2g" revision="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54">
<project name="platform_build" path="build" remote="b2g" revision="d3c9acb642baee501cff89e4efdb16b0c7480760">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>

Просмотреть файл

@ -21,12 +21,12 @@
<!--
B2G repositories for all targets
-->
<project name="gaia" path="gaia" remote="mozillaorg" revision="efd70ba6a54849dcef696abf1652cf74daa07899"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="619766a1ce78d50fb8a3b5a9e0821c335a0ed7ee"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="35dccb3127db8f39f20b985ad312d2cd44780669"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="99c333dab00ed79baff9e1cf76b320aee8e1c123"/>
<project name="platform_hardware_libhardware_moz" path="hardware/libhardware_moz" remote="b2g" revision="fdf3a143dc777e5f9d33a88373af7ea161d3b440"/>
<!-- B2G specific things. -->
<project name="platform_build" path="build" remote="b2g" revision="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54">
<project name="platform_build" path="build" remote="b2g" revision="d3c9acb642baee501cff89e4efdb16b0c7480760">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>

Просмотреть файл

@ -21,7 +21,7 @@
<!--
B2G repositories for all targets
-->
<project name="gaia" path="gaia" remote="mozillaorg" revision="efd70ba6a54849dcef696abf1652cf74daa07899"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="619766a1ce78d50fb8a3b5a9e0821c335a0ed7ee"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="35dccb3127db8f39f20b985ad312d2cd44780669"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="99c333dab00ed79baff9e1cf76b320aee8e1c123"/>
<project name="platform_hardware_libhardware_moz" path="hardware/libhardware_moz" remote="b2g" revision="fdf3a143dc777e5f9d33a88373af7ea161d3b440"/>

Просмотреть файл

@ -21,7 +21,7 @@
<!--
B2G repositories for all targets
-->
<project name="gaia" path="gaia" remote="mozillaorg" revision="efd70ba6a54849dcef696abf1652cf74daa07899"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="619766a1ce78d50fb8a3b5a9e0821c335a0ed7ee"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="35dccb3127db8f39f20b985ad312d2cd44780669"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="99c333dab00ed79baff9e1cf76b320aee8e1c123"/>
<project name="platform_hardware_libhardware_moz" path="hardware/libhardware_moz" remote="b2g" revision="fdf3a143dc777e5f9d33a88373af7ea161d3b440"/>

Просмотреть файл

@ -21,12 +21,12 @@
<!--
B2G repositories for all targets
-->
<project name="gaia" path="gaia" remote="mozillaorg" revision="efd70ba6a54849dcef696abf1652cf74daa07899"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="619766a1ce78d50fb8a3b5a9e0821c335a0ed7ee"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="35dccb3127db8f39f20b985ad312d2cd44780669"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="99c333dab00ed79baff9e1cf76b320aee8e1c123"/>
<project name="platform_hardware_libhardware_moz" path="hardware/libhardware_moz" remote="b2g" revision="fdf3a143dc777e5f9d33a88373af7ea161d3b440"/>
<!-- B2G specific things. -->
<project name="platform_build" path="build" remote="b2g" revision="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54">
<project name="platform_build" path="build" remote="b2g" revision="d3c9acb642baee501cff89e4efdb16b0c7480760">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
@ -137,7 +137,7 @@
<default remote="caf" revision="refs/tags/android-4.4.2_r1" sync-j="4"/>
<!-- Emulator specific things -->
<project name="device/generic/armv7-a-neon" path="device/generic/armv7-a-neon" revision="72ffdf71c68a96309212eb13d63560d66db14c9e"/>
<project name="device_generic_goldfish" path="device/generic/goldfish" remote="b2g" revision="49f5591508df408fab7d7d8322681b004a2750f3"/>
<project name="device_generic_goldfish" path="device/generic/goldfish" remote="b2g" revision="566810728cd485ff2f30766499d32ada7cbd487a"/>
<project name="platform_bionic" path="bionic" remote="b2g" revision="3e85c4683c121530c1c3a48c696a569bf5f587e2"/>
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="39bdda3051dd1d96da3ab369bc654290cb8d463c"/>
<project name="platform/external/libnfc-nci" path="external/libnfc-nci" revision="f37bd545063039e30a92f2550ae78c0e6e4e2d08"/>
@ -145,7 +145,7 @@
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="c0dd0098328f3992e1ca09d6d4355729243863d5"/>
<project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="5f4b68c799927b6e078f987b12722c3a6ccd4a45"/>
<project name="platform/development" path="development" revision="5968ff4e13e0d696ad8d972281fc27ae5a12829b"/>
<project name="platform_prebuilts_qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="6a1bb59af65b6485b1090522f66fac95c3f9e22c"/>
<project name="platform_prebuilts_qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="0c0c050518705d49531375012fa2b4e95e1b3693"/>
<project name="android-sdk" path="sdk" remote="b2g" revision="0951179277915335251c5e11d242e4e1a8c2236f"/>
<project name="darwinstreamingserver" path="system/darwinstreamingserver" remote="b2g" revision="cf85968c7f85e0ec36e72c87ceb4837a943b8af6"/>
</manifest>

Просмотреть файл

@ -21,7 +21,7 @@
<!--
B2G repositories for all targets
-->
<project name="gaia" path="gaia" remote="mozillaorg" revision="efd70ba6a54849dcef696abf1652cf74daa07899"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="619766a1ce78d50fb8a3b5a9e0821c335a0ed7ee"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="35dccb3127db8f39f20b985ad312d2cd44780669"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="99c333dab00ed79baff9e1cf76b320aee8e1c123"/>
<project name="platform_hardware_libhardware_moz" path="hardware/libhardware_moz" remote="b2g" revision="fdf3a143dc777e5f9d33a88373af7ea161d3b440"/>

Просмотреть файл

@ -21,7 +21,7 @@
<!--
B2G repositories for all targets
-->
<project name="gaia" path="gaia" remote="mozillaorg" revision="efd70ba6a54849dcef696abf1652cf74daa07899"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="619766a1ce78d50fb8a3b5a9e0821c335a0ed7ee"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="35dccb3127db8f39f20b985ad312d2cd44780669"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="99c333dab00ed79baff9e1cf76b320aee8e1c123"/>
<project name="platform_hardware_libhardware_moz" path="hardware/libhardware_moz" remote="b2g" revision="fdf3a143dc777e5f9d33a88373af7ea161d3b440"/>

Просмотреть файл

@ -21,12 +21,12 @@
<!--
B2G repositories for all targets
-->
<project name="gaia" path="gaia" remote="mozillaorg" revision="efd70ba6a54849dcef696abf1652cf74daa07899"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="619766a1ce78d50fb8a3b5a9e0821c335a0ed7ee"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="35dccb3127db8f39f20b985ad312d2cd44780669"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="99c333dab00ed79baff9e1cf76b320aee8e1c123"/>
<project name="platform_hardware_libhardware_moz" path="hardware/libhardware_moz" remote="b2g" revision="fdf3a143dc777e5f9d33a88373af7ea161d3b440"/>
<!-- B2G specific things. -->
<project name="platform_build" path="build" remote="b2g" revision="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54">
<project name="platform_build" path="build" remote="b2g" revision="d3c9acb642baee501cff89e4efdb16b0c7480760">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>

Просмотреть файл

@ -1,9 +1,9 @@
{
"git": {
"git_revision": "efd70ba6a54849dcef696abf1652cf74daa07899",
"git_revision": "619766a1ce78d50fb8a3b5a9e0821c335a0ed7ee",
"remote": "https://git.mozilla.org/releases/gaia.git",
"branch": ""
},
"revision": "687b7b7814ff8a089fda4c4d6be564305a0a2b69",
"revision": "d74e738cd626558fb9dc289500ad28ae29deab03",
"repo_path": "integration/gaia-central"
}

Просмотреть файл

@ -21,12 +21,12 @@
<!--
B2G repositories for all targets
-->
<project name="gaia" path="gaia" remote="mozillaorg" revision="efd70ba6a54849dcef696abf1652cf74daa07899"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="619766a1ce78d50fb8a3b5a9e0821c335a0ed7ee"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="35dccb3127db8f39f20b985ad312d2cd44780669"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="99c333dab00ed79baff9e1cf76b320aee8e1c123"/>
<project name="platform_hardware_libhardware_moz" path="hardware/libhardware_moz" remote="b2g" revision="fdf3a143dc777e5f9d33a88373af7ea161d3b440"/>
<!-- B2G specific things. -->
<project name="platform_build" path="build" remote="b2g" revision="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54">
<project name="platform_build" path="build" remote="b2g" revision="d3c9acb642baee501cff89e4efdb16b0c7480760">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>

Просмотреть файл

@ -21,7 +21,7 @@
<!--
B2G repositories for all targets
-->
<project name="gaia" path="gaia" remote="mozillaorg" revision="efd70ba6a54849dcef696abf1652cf74daa07899"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="619766a1ce78d50fb8a3b5a9e0821c335a0ed7ee"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="35dccb3127db8f39f20b985ad312d2cd44780669"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="99c333dab00ed79baff9e1cf76b320aee8e1c123"/>
<project name="platform_hardware_libhardware_moz" path="hardware/libhardware_moz" remote="b2g" revision="fdf3a143dc777e5f9d33a88373af7ea161d3b440"/>

Просмотреть файл

@ -21,7 +21,7 @@
<!--
B2G repositories for all targets
-->
<project name="gaia" path="gaia" remote="mozillaorg" revision="efd70ba6a54849dcef696abf1652cf74daa07899"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="619766a1ce78d50fb8a3b5a9e0821c335a0ed7ee"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="35dccb3127db8f39f20b985ad312d2cd44780669"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="99c333dab00ed79baff9e1cf76b320aee8e1c123"/>
<project name="platform_hardware_libhardware_moz" path="hardware/libhardware_moz" remote="b2g" revision="fdf3a143dc777e5f9d33a88373af7ea161d3b440"/>

Просмотреть файл

@ -135,11 +135,17 @@
el.parentNode.removeChild(el);
el = document.getElementById("errorShortDescText_forbidden");
el.parentNode.removeChild(el);
el = document.getElementById("whyForbiddenButton");
el.parentNode.removeChild(el);
} else {
el = document.getElementById("ignoreWarningButton");
el.parentNode.removeChild(el);
el = document.getElementById("reportButton");
el.parentNode.removeChild(el);
// Remove red style: A "forbidden site" does not warrant the same level
// of anxiety as a security concern.
document.documentElement.className = "";
}
// Set sitename
@ -197,7 +203,7 @@
<h1 id="errorTitleText_phishing">&safeb.blocked.phishingPage.title;</h1>
<h1 id="errorTitleText_malware">&safeb.blocked.malwarePage.title;</h1>
<h1 id="errorTitleText_unwanted">&safeb.blocked.unwantedPage.title;</h1>
<h1 id="errorTitleText_forbidden">&safeb.blocked.forbiddenPage.title;</h1>
<h1 id="errorTitleText_forbidden">&safeb.blocked.forbiddenPage.title2;</h1>
</div>
<div id="errorLongContent">
@ -207,7 +213,7 @@
<p id="errorShortDescText_phishing">&safeb.blocked.phishingPage.shortDesc;</p>
<p id="errorShortDescText_malware">&safeb.blocked.malwarePage.shortDesc;</p>
<p id="errorShortDescText_unwanted">&safeb.blocked.unwantedPage.shortDesc;</p>
<p id="errorShortDescText_forbidden">&safeb.blocked.forbiddenPage.shortDesc;</p>
<p id="errorShortDescText_forbidden">&safeb.blocked.forbiddenPage.shortDesc2;</p>
</div>
<!-- Long Description -->
@ -222,6 +228,7 @@
<!-- Commands handled in browser.js -->
<button id="getMeOutButton">&safeb.palm.accept.label;</button>
<button id="reportButton">&safeb.palm.reportPage.label;</button>
<button id="whyForbiddenButton">&safeb.palm.whyForbidden.label;</button>
</div>
</div>
<div id="ignoreWarning">

Просмотреть файл

@ -2913,6 +2913,12 @@ var BrowserOnClick = {
this.ignoreWarningButton(reason);
}
break;
case "whyForbiddenButton":
// This is the "Why is this site blocked" button for family friendly browsing
// for Fennec. There's no desktop focused support page yet.
gBrowser.loadURI("https://support.mozilla.org/kb/controlledaccess");
break;
}
},

Просмотреть файл

@ -6031,8 +6031,11 @@
// visual status to selected until after we receive confirmation that its content has painted.
this._logicallySelected = val;
// If we're non-e10s we should update the visual selection as well at the same time
if (!gMultiProcessBrowser) {
// If we're non-e10s we should update the visual selection as well at the same time,
// *or* if we're e10s and the visually selected tab isn't changing, in which case the
// tab switcher code won't run and update anything else (like the before- and after-
// selected attributes).
if (!gMultiProcessBrowser || (val && this.hasAttribute("visuallyselected"))) {
this._visuallySelected = val;
}

Просмотреть файл

@ -4,4 +4,3 @@ support-files =
file_reflect_cookie_into_title.html
[browser_usercontext.js]
skip-if = e10s

Просмотреть файл

@ -161,7 +161,7 @@ FirefoxProfileMigrator.prototype._getResourcesInternal = function(sourceProfileD
}
}
// FHR related migrations.
// Telemetry related migrations.
let times = {
name: "times", // name is used only by tests.
type: types.OTHERDATA,
@ -178,69 +178,60 @@ FirefoxProfileMigrator.prototype._getResourcesInternal = function(sourceProfileD
);
}
};
let healthReporter = {
name: "healthreporter", // name is used only by tests...
let telemetry = {
name: "telemetry", // name is used only by tests...
type: types.OTHERDATA,
migrate: aCallback => {
// the health-reporter can't have been initialized yet so it's safe to
// copy the SQL file.
let createSubDir = (name) => {
let dir = currentProfileDir.clone();
dir.append(name);
dir.create(Ci.nsIFile.DIRECTORY_TYPE, FileUtils.PERMS_DIRECTORY);
return dir;
};
// We only support the default database name - copied from healthreporter.jsm
const DEFAULT_DATABASE_NAME = "healthreport.sqlite";
let path = OS.Path.join(sourceProfileDir.path, DEFAULT_DATABASE_NAME);
let sqliteFile = FileUtils.File(path);
if (sqliteFile.exists()) {
sqliteFile.copyTo(currentProfileDir, "");
}
// In unusual cases there may be 2 additional files - a "write ahead log"
// (-wal) file and a "shared memory file" (-shm). The wal file contains
// data that will be replayed when the DB is next opened, while the shm
// file is ignored in that case - the replay happens using only the wal.
// So we *do* copy a wal if it exists, but not a shm.
// See https://www.sqlite.org/tempfiles.html for more.
// (Note also we attempt these copies even if we can't find the DB, and
// rely on FHR itself to do the right thing if it can)
path = OS.Path.join(sourceProfileDir.path, DEFAULT_DATABASE_NAME + "-wal");
let sqliteWal = FileUtils.File(path);
if (sqliteWal.exists()) {
sqliteWal.copyTo(currentProfileDir, "");
}
// If the 'healthreport' directory exists we copy everything from it.
let subdir = this._getFileObject(sourceProfileDir, "healthreport");
// If the 'datareporting' directory exists we migrate files from it.
let haveStateFile = false;
let subdir = this._getFileObject(sourceProfileDir, "datareporting");
if (subdir && subdir.isDirectory()) {
// Copy all regular files.
let dest = currentProfileDir.clone();
dest.append("healthreport");
dest.create(Components.interfaces.nsIFile.DIRECTORY_TYPE,
FileUtils.PERMS_DIRECTORY);
// Copy only specific files.
let toCopy = ["state.json", "session-state.json"];
let dest = createSubDir("datareporting");
let enumerator = subdir.directoryEntries;
while (enumerator.hasMoreElements()) {
let file = enumerator.getNext().QueryInterface(Components.interfaces.nsIFile);
if (file.isDirectory()) {
let file = enumerator.getNext().QueryInterface(Ci.nsIFile);
if (file.isDirectory() || toCopy.indexOf(file.leafName) == -1) {
continue;
}
if (file.leafName == "state.json") {
haveStateFile = true;
}
file.copyTo(dest, "");
}
}
// If the 'datareporting' directory exists we copy just state.json
subdir = this._getFileObject(sourceProfileDir, "datareporting");
if (subdir && subdir.isDirectory()) {
let stateFile = this._getFileObject(subdir, "state.json");
if (stateFile) {
let dest = currentProfileDir.clone();
dest.append("datareporting");
dest.create(Components.interfaces.nsIFile.DIRECTORY_TYPE,
FileUtils.PERMS_DIRECTORY);
stateFile.copyTo(dest, "");
if (!haveStateFile) {
// Fall back to migrating the state file that contains the client id from healthreport/.
// We first moved the client id management from the FHR implementation to the datareporting
// service.
// Consequently, we try to migrate an existing FHR state file here as a fallback.
let subdir = this._getFileObject(sourceProfileDir, "healthreport");
if (subdir && subdir.isDirectory()) {
let stateFile = this._getFileObject(subdir, "state.json");
if (stateFile) {
let dest = createSubDir("healthreport");
stateFile.copyTo(dest, "");
}
}
}
aCallback(true);
}
}
return [places, cookies, passwords, formData, dictionary, bookmarksBackups,
session, times, healthReporter].filter(r => r);
session, times, telemetry].filter(r => r);
};
Object.defineProperty(FirefoxProfileMigrator.prototype, "startupOnlyMigrator", {

Просмотреть файл

@ -77,6 +77,13 @@ function writeToFile(dir, leafName, contents) {
outputStream.close();
}
function createSubDir(dir, subDirName) {
let subDir = dir.clone();
subDir.append(subDirName);
subDir.create(Ci.nsIFile.DIRECTORY_TYPE, FileUtils.PERMS_DIRECTORY);
return subDir;
}
function promiseMigrator(name, srcDir, targetDir) {
let migrator = Cc["@mozilla.org/profile/migrator;1?app=browser&type=firefox"]
.createInstance(Ci.nsISupports)
@ -92,150 +99,168 @@ function promiseMigrator(name, srcDir, targetDir) {
throw new Error("failed to find the " + name + " migrator");
}
function promiseFHRMigrator(srcDir, targetDir) {
return promiseMigrator("healthreporter", srcDir, targetDir);
function promiseTelemetryMigrator(srcDir, targetDir) {
return promiseMigrator("telemetry", srcDir, targetDir);
}
add_task(function* test_empty() {
let [srcDir, targetDir] = getTestDirs();
let ok = yield promiseFHRMigrator(srcDir, targetDir);
let ok = yield promiseTelemetryMigrator(srcDir, targetDir);
Assert.ok(ok, "callback should have been true with empty directories");
// check both are empty
checkDirectoryContains(srcDir, {});
checkDirectoryContains(targetDir, {});
});
add_task(function* test_just_sqlite() {
add_task(function* test_migrate_files() {
let [srcDir, targetDir] = getTestDirs();
let contents = "hello there\n\n";
writeToFile(srcDir, "healthreport.sqlite", contents);
let ok = yield promiseFHRMigrator(srcDir, targetDir);
Assert.ok(ok, "callback should have been true with sqlite file copied");
checkDirectoryContains(targetDir, {
"healthreport.sqlite": contents,
// Set up datareporting files, some to copy, some not.
let stateContent = JSON.stringify({
clientId: "68d5474e-19dc-45c1-8e9a-81fca592707c",
});
});
let sessionStateContent = "foobar 5432";
let subDir = createSubDir(srcDir, "datareporting");
writeToFile(subDir, "state.json", stateContent);
writeToFile(subDir, "session-state.json", sessionStateContent);
writeToFile(subDir, "other.file", "do not copy");
add_task(function* test_sqlite_extras() {
let [srcDir, targetDir] = getTestDirs();
let archived = createSubDir(subDir, "archived");
writeToFile(archived, "other.file", "do not copy");
let contents_sqlite = "hello there\n\n";
writeToFile(srcDir, "healthreport.sqlite", contents_sqlite);
// Set up FHR files, they should not be copied.
writeToFile(srcDir, "healthreport.sqlite", "do not copy");
writeToFile(srcDir, "healthreport.sqlite-wal", "do not copy");
subDir = createSubDir(srcDir, "healthreport");
writeToFile(subDir, "state.json", "do not copy");
writeToFile(subDir, "other.file", "do not copy");
let contents_wal = "this is the wal\n\n";
writeToFile(srcDir, "healthreport.sqlite-wal", contents_wal);
// and the -shm - this should *not* be copied.
writeToFile(srcDir, "healthreport.sqlite-shm", "whatever");
let ok = yield promiseFHRMigrator(srcDir, targetDir);
Assert.ok(ok, "callback should have been true with sqlite file copied");
// Perform migration.
let ok = yield promiseTelemetryMigrator(srcDir, targetDir);
Assert.ok(ok, "callback should have been true with important telemetry files copied");
checkDirectoryContains(targetDir, {
"healthreport.sqlite": contents_sqlite,
"healthreport.sqlite-wal": contents_wal,
});
});
add_task(function* test_sqlite_healthreport_not_dir() {
let [srcDir, targetDir] = getTestDirs();
let contents = "hello there\n\n";
writeToFile(srcDir, "healthreport.sqlite", contents);
writeToFile(srcDir, "healthreport", "I'm a file but should be a directory");
let ok = yield promiseFHRMigrator(srcDir, targetDir);
Assert.ok(ok, "callback should have been true even though the directory was a file");
// We should have only the sqlite file
checkDirectoryContains(targetDir, {
"healthreport.sqlite": contents,
});
});
add_task(function* test_sqlite_healthreport_empty() {
let [srcDir, targetDir] = getTestDirs();
let contents = "hello there\n\n";
writeToFile(srcDir, "healthreport.sqlite", contents);
// create an empty 'healthreport' subdir.
let subDir = srcDir.clone();
subDir.append("healthreport");
subDir.create(Ci.nsIFile.DIRECTORY_TYPE, FileUtils.PERMS_DIRECTORY);
let ok = yield promiseFHRMigrator(srcDir, targetDir);
Assert.ok(ok, "callback should have been true");
// we should end up with the .sqlite file and an empty subdir in the target.
checkDirectoryContains(targetDir, {
"healthreport.sqlite": contents,
"healthreport": {},
});
});
add_task(function* test_sqlite_healthreport_contents() {
let [srcDir, targetDir] = getTestDirs();
let contents = "hello there\n\n";
writeToFile(srcDir, "healthreport.sqlite", contents);
// create an empty 'healthreport' subdir.
let subDir = srcDir.clone();
subDir.append("healthreport");
subDir.create(Ci.nsIFile.DIRECTORY_TYPE, FileUtils.PERMS_DIRECTORY);
writeToFile(subDir, "file1", "this is file 1");
writeToFile(subDir, "file2", "this is file 2");
let ok = yield promiseFHRMigrator(srcDir, targetDir);
Assert.ok(ok, "callback should have been true");
// we should end up with the .sqlite file and an empty subdir in the target.
checkDirectoryContains(targetDir, {
"healthreport.sqlite": contents,
"healthreport": {
"file1": "this is file 1",
"file2": "this is file 2",
"datareporting": {
"state.json": stateContent,
"session-state.json": sessionStateContent,
},
});
});
add_task(function* test_fallback_fhr_state() {
let [srcDir, targetDir] = getTestDirs();
// Test that we fall back to migrating FHR state if the datareporting
// state file does not exist.
let stateContent = JSON.stringify({
clientId: "68d5474e-19dc-45c1-8e9a-81fca592707c",
});
let subDir = createSubDir(srcDir, "healthreport");
writeToFile(subDir, "state.json", stateContent);
// Perform migration.
let ok = yield promiseTelemetryMigrator(srcDir, targetDir);
Assert.ok(ok, "callback should have been true");
checkDirectoryContains(targetDir, {
"healthreport": {
"state.json": stateContent,
},
});
});
add_task(function* test_datareporting_not_dir() {
let [srcDir, targetDir] = getTestDirs();
writeToFile(srcDir, "datareporting", "I'm a file but should be a directory");
let ok = yield promiseTelemetryMigrator(srcDir, targetDir);
Assert.ok(ok, "callback should have been true even though the directory was a file");
checkDirectoryContains(targetDir, {});
});
add_task(function* test_datareporting_empty() {
let [srcDir, targetDir] = getTestDirs();
// create an empty 'datareporting' subdir.
let subDir = srcDir.clone();
subDir.append("datareporting");
subDir.create(Ci.nsIFile.DIRECTORY_TYPE, FileUtils.PERMS_DIRECTORY);
let ok = yield promiseFHRMigrator(srcDir, targetDir);
// Migrate with an empty 'datareporting' subdir.
let subDir = createSubDir(srcDir, "datareporting");
let ok = yield promiseTelemetryMigrator(srcDir, targetDir);
Assert.ok(ok, "callback should have been true");
// we should end up with nothing at all in the destination - state.json was
// missing so we didn't even create the target dir.
// We should end up with no migrated files.
checkDirectoryContains(targetDir, {
"datareporting": {},
});
});
add_task(function* test_healthreport_empty() {
let [srcDir, targetDir] = getTestDirs();
// Migrate with no 'datareporting' and an empty 'healthreport' subdir.
let subDir = createSubDir(srcDir, "healthreport");
let ok = yield promiseTelemetryMigrator(srcDir, targetDir);
Assert.ok(ok, "callback should have been true");
// We should end up with no migrated files.
checkDirectoryContains(targetDir, {});
});
add_task(function* test_datareporting_many() {
let [srcDir, targetDir] = getTestDirs();
// create an empty 'datareporting' subdir.
let subDir = srcDir.clone();
subDir.append("datareporting");
subDir.create(Ci.nsIFile.DIRECTORY_TYPE, FileUtils.PERMS_DIRECTORY);
writeToFile(subDir, "state.json", "should be copied");
// Create some datareporting files.
let subDir = createSubDir(srcDir, "datareporting");
let shouldBeCopied = "should be copied";
writeToFile(subDir, "state.json", shouldBeCopied);
writeToFile(subDir, "session-state.json", shouldBeCopied);
writeToFile(subDir, "something.else", "should not");
createSubDir(subDir, "emptyDir");
let ok = yield promiseFHRMigrator(srcDir, targetDir);
let ok = yield promiseTelemetryMigrator(srcDir, targetDir);
Assert.ok(ok, "callback should have been true");
checkDirectoryContains(targetDir, {
"datareporting" : {
"state.json": "should be copied",
"state.json": shouldBeCopied,
"session-state.json": shouldBeCopied,
}
});
});
add_task(function* test_no_session_state() {
let [srcDir, targetDir] = getTestDirs();
// Check that migration still works properly if we only have state.json.
let subDir = createSubDir(srcDir, "datareporting");
let stateContent = "abcd984";
writeToFile(subDir, "state.json", stateContent);
let ok = yield promiseTelemetryMigrator(srcDir, targetDir);
Assert.ok(ok, "callback should have been true");
checkDirectoryContains(targetDir, {
"datareporting" : {
"state.json": stateContent,
}
});
});
add_task(function* test_no_state() {
let [srcDir, targetDir] = getTestDirs();
// Check that migration still works properly if we only have session-state.json.
let subDir = createSubDir(srcDir, "datareporting");
let sessionStateContent = "abcd512";
writeToFile(subDir, "session-state.json", sessionStateContent);
let ok = yield promiseTelemetryMigrator(srcDir, targetDir);
Assert.ok(ok, "callback should have been true");
checkDirectoryContains(targetDir, {
"datareporting" : {
"session-state.json": sessionStateContent,
}
});
});

Просмотреть файл

@ -12,7 +12,7 @@ skip-if = os != "mac" # Relies on ULibDir
[test_Chrome_passwords.js]
skip-if = os != "win"
[test_Edge_availability.js]
[test_fx_fhr.js]
[test_fx_telemetry.js]
[test_IE_bookmarks.js]
skip-if = os != "win"
[test_IE_cookies.js]

Просмотреть файл

@ -11,15 +11,20 @@ function retrieveUserContextId(browser) {
add_task(function() {
for (let i = 0; i < 3; ++i) {
let tab = gBrowser.addTab("about:blank");
let tab = gBrowser.addTab("http://example.com/", {userContextId: i});
let browser = tab.linkedBrowser;
yield promiseBrowserLoaded(browser);
yield promiseTabState(tab, { userContextId: i, entries: [{ url: "http://example.com/" }] });
let userContextId = yield retrieveUserContextId(browser);
let tab2 = gBrowser.duplicateTab(tab);
let browser2 = tab2.linkedBrowser;
yield promiseTabRestored(tab2)
let userContextId = yield retrieveUserContextId(browser2);
is(userContextId, i, "The docShell has the correct userContextId");
yield promiseRemoveTab(tab);
yield promiseRemoveTab(tab2);
}
});

Просмотреть файл

@ -6,6 +6,7 @@
<!ENTITY safeb.palm.decline.label "Ignore this warning">
<!ENTITY safeb.palm.notforgery.label2 "This isn't a web forgery…">
<!ENTITY safeb.palm.reportPage.label "Why was this page blocked?">
<!ENTITY safeb.palm.whyForbidden.label "Why was this page blocked?">
<!ENTITY safeb.blocked.malwarePage.title "Reported Attack Page!">
<!-- Localization note (safeb.blocked.malwarePage.shortDesc) - Please don't translate the contents of the <span id="malware_sitename"/> tag. It will be replaced at runtime with a domain name (e.g. www.badsite.com) -->
@ -22,7 +23,7 @@
<!ENTITY safeb.blocked.phishingPage.shortDesc "This web page at <span id='phishing_sitename'/> has been reported as a web forgery and has been blocked based on your security preferences.">
<!ENTITY safeb.blocked.phishingPage.longDesc "<p>Web forgeries are designed to trick you into revealing personal or financial information by imitating sources you may trust.</p><p>Entering any information on this web page may result in identity theft or other fraud.</p>">
<!ENTITY safeb.blocked.forbiddenPage.title "Forbidden Site">
<!-- Localization note (safeb.blocked.forbiddenPage.shortDesc) - Please don't translate the contents of the <span id="forbidden_sitename"/> tag. It will be replaced at runtime with a domain name (e.g. www.badsite.com) -->
<!ENTITY safeb.blocked.forbiddenPage.shortDesc "This Web page at <span id='forbidden_sitename'/> has been blocked based on your browser configuration.">
<!ENTITY safeb.blocked.forbiddenPage.title2 "Blocked Site">
<!-- Localization note (safeb.blocked.forbiddenPage.shortDesc2) - Please don't translate the contents of the <span id="forbidden_sitename"/> tag. It will be replaced at runtime with a domain name (e.g. www.badsite.com) -->
<!ENTITY safeb.blocked.forbiddenPage.shortDesc2 "The Web page at <span id='forbidden_sitename'/> has been blocked by your admin profile.">

Просмотреть файл

@ -26,5 +26,9 @@ DIRS += [
if CONFIG['MAKENSISU']:
DIRS += ['installer/windows']
TEST_DIRS += [
'tools/mozscreenshots',
]
DIST_SUBDIR = 'browser'
export('DIST_SUBDIR')

Просмотреть файл

@ -0,0 +1,7 @@
[DEFAULT]
subsuite = screenshots
support-files =
head.js
[browser_screenshots.js]
tags = screenshots

Просмотреть файл

@ -0,0 +1,18 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const env = Cc["@mozilla.org/process/environment;1"].getService(Ci.nsIEnvironment);
add_task(function* test() {
let { TestRunner } = Cu.import("chrome://mozscreenshots/content/TestRunner.jsm", {});
let sets = ["TabsInTitlebar", "Tabs", "WindowSize", "Toolbars", "LightweightThemes"];
let setsEnv = env.get("MOZSCREENSHOTS_SETS");
if (setsEnv) {
sets = setsEnv.trim().split(",");
}
yield TestRunner.start(sets);
});

Просмотреть файл

@ -0,0 +1,20 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const {AddonWatcher} = Cu.import("resource://gre/modules/AddonWatcher.jsm", {});
let TestRunner;
function setup() {
requestLongerTimeout(10);
info("Checking for mozscreenshots extension");
AddonManager.getAddonByID("mozscreenshots@mozilla.org", function(aAddon) {
isnot(aAddon, null, "The mozscreenshots extension should be installed");
AddonWatcher.ignoreAddonPermanently(aAddon.id);
});
}
add_task(setup);

Просмотреть файл

@ -0,0 +1,11 @@
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
BROWSER_CHROME_MANIFESTS += ['browser.ini']
TEST_DIRS += [
'mozscreenshots/extension',
]

Просмотреть файл

@ -0,0 +1,12 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
TEST_EXTENSIONS_DIR = $(DEPTH)/_tests/testing/mochitest/extensions
GENERATED_DIRS = $(TEST_EXTENSIONS_DIR)
XPI_PKGNAME = mozscreenshots@mozilla.org
include $(topsrcdir)/config/rules.mk
libs::
(cd $(DIST)/xpi-stage && tar $(TAR_CREATE_FLAGS) - $(XPI_NAME)) | (cd $(TEST_EXTENSIONS_DIR) && tar -xf -)

Просмотреть файл

@ -0,0 +1,175 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
this.EXPORTED_SYMBOLS = ["Screenshot"];
const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/Task.jsm");
Cu.import("resource://gre/modules/Timer.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/osfile.jsm");
// Create a new instance of the ConsoleAPI so we can control the maxLogLevel with a pref.
// See LOG_LEVELS in Console.jsm. Common examples: "All", "Info", "Warn", & "Error".
const PREF_LOG_LEVEL = "extensions.mozscreenshots@mozilla.org.loglevel";
XPCOMUtils.defineLazyGetter(this, "log", () => {
let ConsoleAPI = Cu.import("resource://gre/modules/Console.jsm", {}).ConsoleAPI;
let consoleOptions = {
maxLogLevel: "info",
maxLogLevelPref: PREF_LOG_LEVEL,
prefix: "mozscreenshots",
};
return new ConsoleAPI(consoleOptions);
});
let Screenshot = {
_extensionPath: null,
_path: null,
_imagePrefix: "",
_imageExtension: ".png",
_screenshotFunction: null,
init(path, extensionPath, imagePrefix = "") {
this._path = path;
let dir = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
dir.initWithPath(this._path);
if (!dir.exists()) {
dir.create(Ci.nsIFile.DIRECTORY_TYPE, parseInt("0755", 8));
}
this._extensionPath = extensionPath;
this._imagePrefix = imagePrefix;
switch (Services.appinfo.OS) {
case "WINNT":
this._screenshotFunction = this._screenshotWindows;
break;
case "Darwin":
this._screenshotFunction = this._screenshotOSX;
break;
case "Linux":
this._screenshotFunction = this._screenshotLinux;
break;
default:
throw new Error("Unsupported operating system");
break;
}
},
_buildImagePath(baseName) {
return OS.Path.join(this._path, this._imagePrefix + baseName + this._imageExtension);
},
// Capture the whole screen using an external application.
captureExternal(filename) {
let imagePath = this._buildImagePath(filename);
return this._screenshotFunction(imagePath).then(() => {
log.debug("saved screenshot: " + filename);
});
},
///// helpers /////
_screenshotWindows(filename) {
return new Promise((resolve, reject) => {
let exe = Services.dirsvc.get("GreBinD", Ci.nsIFile);
exe.append("screenshot.exe");
if (!exe.exists()) {
exe = this._extensionPath.QueryInterface(Ci.nsIFileURL).file;
exe.append("lib");
exe.append("screenshot.exe");
}
let process = Cc["@mozilla.org/process/util;1"].createInstance(Ci.nsIProcess);
process.init(exe);
let args = [filename];
process.runAsync(args, args.length, this._processObserver(resolve, reject));
});
},
_screenshotOSX: Task.async(function*(filename) {
let screencapture = (windowID = null) => {
return new Promise((resolve, reject) => {
// Get the screencapture executable
let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
file.initWithPath("/usr/sbin/screencapture");
let process = Cc["@mozilla.org/process/util;1"].createInstance(Ci.nsIProcess);
process.init(file);
// Run the process.
let args = ["-x", "-t", "png"];
// Darwin version number for OS X 10.6 is 10.x
if (windowID && Services.sysinfo.getProperty("version").indexOf("10.") !== 0) {
// Capture only that window on 10.7+
args.push("-l");
args.push(windowID);
}
args.push(filename);
process.runAsync(args, args.length, this._processObserver(resolve, reject));
});
};
function readWindowID() {
let decoder = new TextDecoder();
let promise = OS.File.read("/tmp/mozscreenshots-windowid");
return promise.then(function onSuccess(array) {
return decoder.decode(array);
});
}
let promiseWindowID = () => {
return new Promise((resolve, reject) => {
// Get the window ID of the application (assuming its front-most)
let osascript = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
osascript.initWithPath("/bin/bash");
let osascriptP = Cc["@mozilla.org/process/util;1"].createInstance(Ci.nsIProcess);
osascriptP.init(osascript);
let osaArgs = ["-c", "/usr/bin/osascript -e 'tell application (path to frontmost application as text) to set winID to id of window 1' > /tmp/mozscreenshots-windowid"];
osascriptP.runAsync(osaArgs, osaArgs.length, this._processObserver(resolve, reject));
});
};
yield promiseWindowID();
let windowID = yield readWindowID();
yield screencapture(windowID);
}),
_screenshotLinux(filename) {
return new Promise((resolve, reject) => {
let file = Services.dirsvc.get("GreBinD", Ci.nsIFile);
file.append("screentopng");
let process = Cc["@mozilla.org/process/util;1"].createInstance(Ci.nsIProcess);
process.init(file);
let args = [filename];
process.runAsync(args, args.length, this._processObserver(resolve, reject));
});
},
_processObserver(resolve, reject) {
return {
observe(subject, topic, data) {
switch (topic) {
case "process-finished":
try {
// Wait 1s after process to resolve
setTimeout(resolve, 1000);
} catch (ex) {
reject(ex);
}
break;
default:
reject(topic);
break;
};
},
};
},
};

Просмотреть файл

@ -0,0 +1,256 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
this.EXPORTED_SYMBOLS = ["TestRunner"];
const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
const defaultSetNames = ["TabsInTitlebar", "Tabs", "WindowSize", "Toolbars", "LightweightThemes"];
const env = Cc["@mozilla.org/process/environment;1"].getService(Ci.nsIEnvironment);
Cu.import("resource://gre/modules/FileUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/Task.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/osfile.jsm");
Cu.import("chrome://mozscreenshots/content/Screenshot.jsm");
// Create a new instance of the ConsoleAPI so we can control the maxLogLevel with a pref.
// See LOG_LEVELS in Console.jsm. Common examples: "All", "Info", "Warn", & "Error".
const PREF_LOG_LEVEL = "extensions.mozscreenshots@mozilla.org.loglevel";
XPCOMUtils.defineLazyGetter(this, "log", () => {
let ConsoleAPI = Cu.import("resource://gre/modules/Console.jsm", {}).ConsoleAPI;
let consoleOptions = {
maxLogLevel: "info",
maxLogLevelPref: PREF_LOG_LEVEL,
prefix: "mozscreenshots",
};
return new ConsoleAPI(consoleOptions);
});
this.TestRunner = {
combos: null,
completedCombos: 0,
currentComboIndex: 0,
_lastCombo: null,
_libDir: null,
init(extensionPath) {
let subDirs = ["mozscreenshots",
(new Date()).toISOString().replace(/:/g, "-") + "_" + Services.appinfo.OS];
let screenshotPath = FileUtils.getFile("TmpD", subDirs).path;
const MOZ_UPLOAD_DIR = env.get("MOZ_UPLOAD_DIR");
if (MOZ_UPLOAD_DIR) {
screenshotPath = MOZ_UPLOAD_DIR;
}
log.info("Saving screenshots to:", screenshotPath);
log.debug("TestRunner.init");
let screenshotPrefix = Services.appinfo.appBuildID + "_";
Screenshot.init(screenshotPath, extensionPath, screenshotPrefix);
this._libDir = extensionPath.QueryInterface(Ci.nsIFileURL).file.clone();
this._libDir.append("chrome");
this._libDir.append("mozscreenshots");
this._libDir.append("lib");
// Setup some prefs
Services.prefs.setCharPref("browser.aboutHomeSnippets.updateUrl", "data:");
Services.prefs.setCharPref("extensions.ui.lastCategory", "addons://list/extension");
// Don't let the caret blink since it causes false positives for image diffs
Services.prefs.setIntPref("ui.caretBlinkTime", -1);
},
/**
* Load specified sets, execute all combinations of them, and capture screenshots.
*/
start(setNames = null) {
setNames = setNames || defaultSetNames;
let sets = this.loadSets(setNames);
log.info(sets.length + " sets:", setNames);
this.combos = new LazyProduct(sets);
log.info(this.combos.length + " combinations");
this.currentComboIndex = this.completedCombos = 0;
this._lastCombo = null;
return Task.spawn(function* doStart() {
for (let i = 0; i < this.combos.length;
i++){
this.currentComboIndex = i;
yield* this._performCombo(this.combos.item(this.currentComboIndex));
}
log.info("Done: Completed " + this.completedCombos + " out of " +
this.combos.length + " configurations.");
this.cleanup();
}.bind(this));
},
/**
* Load sets of configurations from JSMs.
* @param {String[]} setNames - array of set names (e.g. ["Tabs", "WindowSize"].
* @return {Object[]} Array of sets containing `name` and `configurations` properties.
*/
loadSets(setNames) {
let sets = [];
for (let setName of setNames) {
try {
let imported = {};
Cu.import("chrome://mozscreenshots/content/configurations/" + setName + ".jsm",
imported);
imported[setName].init(this._libDir);
let configurationNames = Object.keys(imported[setName].configurations);
if (!configurationNames.length) {
throw new Error(setName + " has no configurations for this environment");
}
for (let config of configurationNames) {
// Automatically set the name property of the configuration object to
// its name from the configuration object.
imported[setName].configurations[config].name = config;
}
sets.push(imported[setName].configurations);
} catch (ex) {
log.error("Error loading set: " + setName);
log.error(ex);
throw ex;
}
}
return sets;
},
cleanup() {
let browserWindow = Services.wm.getMostRecentWindow("navigator:browser");
let gBrowser = browserWindow.gBrowser;
while (gBrowser.tabs.length > 1) {
gBrowser.removeTab(gBrowser.selectedTab, {animate: false});
}
gBrowser.unpinTab(gBrowser.selectedTab);
gBrowser.selectedBrowser.loadURI("data:text/html;charset=utf-8,<h1>Done!");
browserWindow.restore();
},
///// helpers /////
_performCombo: function*(combo) {
let paddedComboIndex = padLeft(this.currentComboIndex + 1, String(this.combos.length).length);
log.info("Combination " + paddedComboIndex + "/" + this.combos.length + ": " +
this._comboName(combo).substring(1));
function changeConfig(config) {
log.debug("calling " + config.name);
let promise = config.applyConfig();
log.debug("called " + config.name);
return promise;
}
try {
// First go through and actually apply all of the configs
for (let i = 0; i < combo.length; i++) {
let config = combo[i];
if (!this._lastCombo || config !== this._lastCombo[i]) {
log.debug("promising", config.name);
yield changeConfig(config);
}
}
// Update the lastCombo since it's now been applied regardless of whether it's accepted below.
log.debug("fulfilled all applyConfig so setting lastCombo.");
this._lastCombo = combo;
// Then ask configs if the current setup is valid. We can't can do this in
// the applyConfig methods of the config since it doesn't know what configs
// later in the loop will do that may invalidate the combo.
for (let i = 0; i < combo.length; i++) {
let config = combo[i];
// A configuration can specify an optional verifyConfig method to indicate
// if the current config is valid for a screenshot. This gets called even
// if the this config was used in the lastCombo since another config may
// have invalidated it.
if (config.verifyConfig) {
log.debug("checking if the combo is valid with", config.name);
yield config.verifyConfig();
}
}
} catch (ex) {
log.warn("\tskipped configuration: " + ex);
// Don't set lastCombo here so that we properly know which configurations
// need to be applied since the last screenshot
// Return so we don't take a screenshot.
return;
}
yield this._onConfigurationReady(combo);
},
_onConfigurationReady(combo) {
let delayedScreenshot = () => {
let filename = padLeft(this.currentComboIndex + 1,
String(this.combos.length).length) + this._comboName(combo);
return Screenshot.captureExternal(filename)
.then(() => {
this.completedCombos++;
});
};
log.debug("_onConfigurationReady");
return Task.spawn(delayedScreenshot);
},
_comboName(combo) {
return combo.reduce(function(a, b) {
return a + "_" + b.name;
}, "");
},
};
/**
* Helper to lazily compute the Cartesian product of all of the sets of configurations.
**/
function LazyProduct(sets) {
/**
* An entry for each set with the value being:
* [the number of permutations of the sets with lower index,
* the number of items in the set at the index]
*/
this.sets = sets;
this.lookupTable = [];
let combinations = 1;
for (let i = this.sets.length - 1; i >= 0; i--) {
let set = this.sets[i];
let setLength = Object.keys(set).length;
this.lookupTable[i] = [combinations, setLength];
combinations *= setLength;
}
}
LazyProduct.prototype = {
get length() {
let last = this.lookupTable[0];
if (!last)
return 0;
return last[0] * last[1];
},
item(n) {
// For set i, get the item from the set with the floored value of
// (n / the number of permutations of the sets already chosen from) modulo the length of set i
let result = [];
for (let i = this.sets.length - 1; i >= 0; i--) {
let priorCombinations = this.lookupTable[i][0];
let setLength = this.lookupTable[i][1];
let keyIndex = Math.floor(n / priorCombinations) % setLength;
let keys = Object.keys(this.sets[i]);
result[i] = this.sets[i][keys[keyIndex]];
}
return result;
},
};
function padLeft(number, width, padding = "0") {
return padding.repeat(Math.max(0, width - String(number).length)) + number;
}

Просмотреть файл

@ -0,0 +1,72 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/*
#if 0
Workaround a build system bug where this file doesn't get packaged if not pre-processed.
#endif
*/
"use strict";
const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
const env = Cc["@mozilla.org/process/environment;1"].getService(Ci.nsIEnvironment);
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/AddonManager.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/Timer.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "TestRunner",
"chrome://mozscreenshots/content/TestRunner.jsm");
function install(data, reason) {
if (!isAppSupported()) {
uninstallExtension(data);
return;
}
AddonManager.getAddonByID(data.id, function(addon) {
// Enable on install in case the user disabled a prior version
if (addon) {
addon.userDisabled = false;
}
});
}
function startup(data, reason) {
if (!isAppSupported()) {
uninstallExtension(data);
return;
}
AddonManager.getAddonByID(data.id, function(addon) {
let extensionPath = addon.getResourceURI();
TestRunner.init(extensionPath);
});
}
function shutdown(data, reason) { }
function uninstall(data, reason) { }
/**
* @return boolean whether the test suite applies to the application.
*/
function isAppSupported() {
return true;
}
function uninstallExtension(data) {
AddonManager.getAddonByID(data.id, function(addon) {
addon.uninstall();
});
}
function startRun() {
let env = Cc["@mozilla.org/process/environment;1"]
.getService(Ci.nsIEnvironment);
let setsEnv = env.get("MOZSCREENSHOTS_SETS");
let sets = setsEnv ? setsEnv.split(",") : null;
TestRunner.start(sets);
}

Просмотреть файл

@ -0,0 +1,84 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
this.EXPORTED_SYMBOLS = ["AppMenu"];
const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/Task.jsm");
this.AppMenu = {
init(libDir) {},
configurations: {
appMenuClosed: {
applyConfig: Task.async(function*() {
let browserWindow = Services.wm.getMostRecentWindow("navigator:browser");
browserWindow.PanelUI.hide();
}),
},
appMenuMainView: {
applyConfig() {
let browserWindow = Services.wm.getMostRecentWindow("navigator:browser");
let promise = browserWindow.PanelUI.show();
browserWindow.PanelUI.showMainView();
return promise;
},
},
appMenuHistorySubview: {
applyConfig() {
// History has a footer
if (isCustomizing()) {
return Promise.reject("Can't show subviews while customizing");
}
let browserWindow = Services.wm.getMostRecentWindow("navigator:browser");
let promise = browserWindow.PanelUI.show();
return promise.then(() => {
browserWindow.PanelUI.showMainView();
browserWindow.document.getElementById("history-panelmenu").click();
});
},
verifyConfig: verifyConfigHelper,
},
appMenuHelpSubview: {
applyConfig() {
if (isCustomizing()) {
return Promise.reject("Can't show subviews while customizing");
}
let browserWindow = Services.wm.getMostRecentWindow("navigator:browser");
let promise = browserWindow.PanelUI.show();
return promise.then(() => {
browserWindow.PanelUI.showMainView();
browserWindow.document.getElementById("PanelUI-help").click();
});
},
verifyConfig: verifyConfigHelper,
},
},
};
function verifyConfigHelper() {
if (isCustomizing()) {
return Promise.reject("AppMenu verifyConfigHelper");
}
return Promise.resolve("AppMenu verifyConfigHelper");
}
function isCustomizing() {
let browserWindow = Services.wm.getMostRecentWindow("navigator:browser");
if (browserWindow.document.documentElement.hasAttribute("customizing")) {
return true;
}
return false;
}

Просмотреть файл

@ -0,0 +1,87 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
this.EXPORTED_SYMBOLS = ["Buttons"];
const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
Cu.import("resource:///modules/CustomizableUI.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/Task.jsm");
this.Buttons = {
init(libDir) {
createWidget();
},
configurations: {
navBarButtons: {
applyConfig: Task.async(() =>{
let browserWindow = Services.wm.getMostRecentWindow("navigator:browser");
CustomizableUI.addWidgetToArea("screenshot-widget", CustomizableUI.AREA_NAVBAR);
}),
},
tabsToolbarButtons: {
applyConfig: Task.async(() => {
let browserWindow = Services.wm.getMostRecentWindow("navigator:browser");
CustomizableUI.addWidgetToArea("screenshot-widget", CustomizableUI.AREA_TABSTRIP);
}),
},
menuPanelButtons: {
applyConfig: Task.async(() => {
CustomizableUI.addWidgetToArea("screenshot-widget", CustomizableUI.AREA_PANEL);
}),
verifyConfig() {
let browserWindow = Services.wm.getMostRecentWindow("navigator:browser");
if (browserWindow.PanelUI.panel.state == "closed") {
return Promise.reject("The button isn't shown when the panel isn't open.");
}
return Promise.resolve("menuPanelButtons.verifyConfig");
},
},
custPaletteButtons: {
applyConfig: Task.async(() => {
CustomizableUI.removeWidgetFromArea("screenshot-widget");
}),
verifyConfig() {
let browserWindow = Services.wm.getMostRecentWindow("navigator:browser");
if (browserWindow.document.documentElement.getAttribute("customizing") != "true") {
return Promise.reject("The button isn't shown when we're not in customize mode.");
}
return Promise.resolve("custPaletteButtons.verifyConfig");
},
},
},
};
function createWidget() {
let id = "screenshot-widget";
let spec = {
id: id,
label: "My Button",
removable: true,
tooltiptext: "",
type: "button",
};
CustomizableUI.createWidget(spec);
// Append a <style> for the image
let browserWindow = Services.wm.getMostRecentWindow("navigator:browser");
let st = browserWindow.document.createElementNS("http://www.w3.org/1999/xhtml", "style");
let styles = "" +
"#screenshot-widget > .toolbarbutton-icon {" +
" list-style-image: url(chrome://browser/skin/Toolbar.png);" +
" -moz-image-region: rect(0px, 18px, 18px, 0px);" +
"}";
st.appendChild(browserWindow.document.createTextNode(styles));
browserWindow.document.documentElement.appendChild(st);
}

Просмотреть файл

@ -0,0 +1,61 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
this.EXPORTED_SYMBOLS = ["CustomizeMode"];
const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/Timer.jsm");
this.CustomizeMode = {
init(libDir) {},
configurations: {
notCustomizing: {
applyConfig() {
return new Promise((resolve) => {
let browserWindow = Services.wm.getMostRecentWindow("navigator:browser");
if (!browserWindow.document.documentElement.hasAttribute("customizing")) {
resolve("notCustomizing: already not customizing");
return;
}
function onCustomizationEnds() {
browserWindow.gNavToolbox.removeEventListener("aftercustomization",
onCustomizationEnds);
// Wait for final changes
setTimeout(() => resolve("notCustomizing: onCustomizationEnds"), 500);
}
browserWindow.gNavToolbox.addEventListener("aftercustomization",
onCustomizationEnds);
browserWindow.gCustomizeMode.exit();
});
},
},
customizing: {
applyConfig() {
return new Promise((resolve) => {
let browserWindow = Services.wm.getMostRecentWindow("navigator:browser");
if (browserWindow.document.documentElement.hasAttribute("customizing")) {
resolve("customizing: already customizing");
return;
}
function onCustomizing() {
browserWindow.gNavToolbox.removeEventListener("customizationready",
onCustomizing);
// Wait for final changes
setTimeout(() => resolve("customizing: onCustomizing"), 500);
}
browserWindow.gNavToolbox.addEventListener("customizationready",
onCustomizing);
browserWindow.gCustomizeMode.enter();
});
},
},
},
};

Просмотреть файл

@ -0,0 +1,42 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
this.EXPORTED_SYMBOLS = ["DevEdition"];
const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
const THEME_ID = "firefox-devedition@mozilla.org";
Cu.import("resource://gre/modules/LightweightThemeManager.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/Task.jsm");
this.DevEdition = {
init(libDir) {},
configurations: {
devEditionLight: {
applyConfig: Task.async(() => {
Services.prefs.setCharPref("devtools.theme", "light");
LightweightThemeManager.currentTheme = LightweightThemeManager.getUsedTheme(THEME_ID);
Services.prefs.setBoolPref("browser.devedition.theme.showCustomizeButton", true);
}),
},
devEditionDark: {
applyConfig: Task.async(() => {
Services.prefs.setCharPref("devtools.theme", "dark");
LightweightThemeManager.currentTheme = LightweightThemeManager.getUsedTheme(THEME_ID);
Services.prefs.setBoolPref("browser.devedition.theme.showCustomizeButton", true);
}),
},
devEditionOff: {
applyConfig: Task.async(() => {
Services.prefs.clearUserPref("devtools.theme");
LightweightThemeManager.currentTheme = null;
Services.prefs.clearUserPref("browser.devedition.theme.showCustomizeButton");
}),
},
},
};

Просмотреть файл

@ -0,0 +1,50 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
this.EXPORTED_SYMBOLS = ["DevTools"];
const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
Cu.import("resource://devtools/client/framework/gDevTools.jsm");
Cu.import("resource://gre/modules/Services.jsm");
let { devtools } = Cu.import("resource://gre/modules/devtools/Loader.jsm", {});
let TargetFactory = devtools.TargetFactory;
function getTargetForSelectedTab() {
let browserWindow = Services.wm.getMostRecentWindow("navigator:browser");
let target = TargetFactory.forTab(browserWindow.gBrowser.selectedTab);
return target;
}
this.DevTools = {
init(libDir) {
let panels = ["options", "webconsole", "inspector", "jsdebugger", "netmonitor"];
panels.forEach(panel => {
this.configurations[panel] = {};
this.configurations[panel].applyConfig = () => {
return gDevTools.showToolbox(getTargetForSelectedTab(), panel, "bottom");
};
});
},
configurations: {
bottomToolbox: {
applyConfig() {
return gDevTools.showToolbox(getTargetForSelectedTab(), "inspector", "bottom");
},
},
sideToolbox: {
applyConfig() {
return gDevTools.showToolbox(getTargetForSelectedTab(), "inspector", "side");
},
},
undockedToolbox: {
applyConfig() {
return gDevTools.showToolbox(getTargetForSelectedTab(), "inspector", "window");
},
}
},
};

Просмотреть файл

@ -0,0 +1,92 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
this.EXPORTED_SYMBOLS = ["LightweightThemes"];
const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
Cu.import("resource://gre/modules/LightweightThemeManager.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/Task.jsm");
Cu.import("resource://gre/modules/Timer.jsm");
this.LightweightThemes = {
init(libDir) {
// convert -size 3000x200 canvas:black black_theme.png
let blackImage = libDir.clone();
blackImage.append("black_theme.png");
this._blackImageURL = Services.io.newFileURI(blackImage).spec;
// convert -size 3000x200 canvas:white white_theme.png
let whiteImage = libDir.clone();
whiteImage.append("white_theme.png");
this._whiteImageURL = Services.io.newFileURI(whiteImage).spec;
},
configurations: {
noLWT: {
applyConfig: Task.async(function*() {
LightweightThemeManager.currentTheme = null;
}),
},
darkLWT: {
applyConfig() {
LightweightThemeManager.setLocalTheme({
id: "black",
name: "black",
headerURL: LightweightThemes._blackImageURL,
footerURL: LightweightThemes._blackImageURL,
textcolor: "#ffffff",
accentcolor: "#111111",
});
// Wait for LWT listener
return new Promise(resolve => {
setTimeout(() => {
resolve("darkLWT");
}, 500);
});
},
verifyConfig: verifyConfigHelper,
},
lightLWT: {
applyConfig() {
LightweightThemeManager.setLocalTheme({
id: "white",
name: "white",
headerURL: LightweightThemes._whiteImageURL,
footerURL: LightweightThemes._whiteImageURL,
textcolor: "#000000",
accentcolor: "#eeeeee",
});
// Wait for LWT listener
return new Promise(resolve => {
setTimeout(() => {
resolve("lightLWT");
}, 500);
});
},
verifyConfig: verifyConfigHelper,
},
},
};
function verifyConfigHelper() {
return new Promise((resolve, reject) => {
let browserWindow = Services.wm.getMostRecentWindow("navigator:browser");
if (browserWindow.document.documentElement.hasAttribute("lwtheme")) {
resolve("verifyConfigHelper");
} else {
reject("The @lwtheme attribute wasn't present so themes may not be available");
}
});
}

Просмотреть файл

@ -0,0 +1,53 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
this.EXPORTED_SYMBOLS = ["Preferences"];
const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/Timer.jsm");
this.Preferences = {
init(libDir) {
Services.prefs.setBoolPref("browser.preferences.inContent", true);
let panes = [
["paneGeneral", null],
["paneSearch", null],
["paneContent", null],
["paneApplications", null],
["panePrivacy", null],
["paneSecurity", null],
["paneSync", null],
["paneAdvanced", "generalTab"],
["paneAdvanced", "dataChoicesTab"],
["paneAdvanced", "networkTab"],
["paneAdvanced", "updateTab"],
["paneAdvanced", "encryptionTab"],
];
for (let [primary, advanced] of panes) {
let configName = primary + ("-" + advanced || "");
this.configurations[configName] = {};
this.configurations[configName].applyConfig = prefHelper.bind(null, primary, advanced);
}
},
configurations: {},
};
function prefHelper(primary, advanced) {
return new Promise((resolve) => {
let browserWindow = Services.wm.getMostRecentWindow("navigator:browser");
if (primary == "paneAdvanced") {
browserWindow.openAdvancedPreferences(advanced);
} else {
browserWindow.openPreferences(primary);
}
setTimeout(resolve, 50);
});
}

Просмотреть файл

@ -0,0 +1,143 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
this.EXPORTED_SYMBOLS = ["Tabs"];
const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
const CUST_TAB = "chrome://browser/skin/customizableui/customizeFavicon.ico";
const PREFS_TAB = "chrome://browser/skin/preferences/in-content/favicon.ico";
const DEFAULT_FAVICON_TAB = `data:text/html,<meta charset="utf-8">
<title>No favicon</title>`;
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/Task.jsm");
this.Tabs = {
init(libDir) {},
configurations: {
fiveTabs: {
applyConfig: Task.async(function*() {
fiveTabsHelper();
let browserWindow = Services.wm.getMostRecentWindow("navigator:browser");
hoverTab(browserWindow.gBrowser.tabs[3]);
}),
},
fourPinned: {
applyConfig: Task.async(function*() {
fiveTabsHelper();
let browserWindow = Services.wm.getMostRecentWindow("navigator:browser");
let tab = browserWindow.gBrowser.addTab(PREFS_TAB);
browserWindow.gBrowser.pinTab(tab);
tab = browserWindow.gBrowser.addTab(CUST_TAB);
browserWindow.gBrowser.pinTab(tab);
tab = browserWindow.gBrowser.addTab("about:privatebrowsing");
browserWindow.gBrowser.pinTab(tab);
tab = browserWindow.gBrowser.addTab("about:home");
browserWindow.gBrowser.pinTab(tab);
browserWindow.gBrowser.selectTabAtIndex(5);
hoverTab(browserWindow.gBrowser.tabs[2]);
// also hover the new tab button
let newTabButton = browserWindow.document.getAnonymousElementByAttribute(browserWindow.
gBrowser.tabContainer, "class", "tabs-newtab-button");
hoverTab(newTabButton);
browserWindow.gBrowser.tabs[browserWindow.gBrowser.tabs.length - 1].
setAttribute("beforehovered", true);
}),
},
twoPinnedWithOverflow: {
applyConfig: Task.async(function*() {
fiveTabsHelper();
let browserWindow = Services.wm.getMostRecentWindow("navigator:browser");
browserWindow.gBrowser.loadTabs([
"about:addons",
"about:home",
DEFAULT_FAVICON_TAB,
"about:newtab",
"about:addons",
"about:home",
DEFAULT_FAVICON_TAB,
"about:newtab",
"about:addons",
"about:home",
DEFAULT_FAVICON_TAB,
"about:newtab",
"about:addons",
"about:home",
DEFAULT_FAVICON_TAB,
"about:newtab",
"about:addons",
"about:home",
DEFAULT_FAVICON_TAB,
"about:newtab",
"about:addons",
"about:home",
DEFAULT_FAVICON_TAB,
"about:newtab",
"about:addons",
"about:home",
DEFAULT_FAVICON_TAB,
"about:newtab",
], true, true);
let tab = browserWindow.gBrowser.addTab(PREFS_TAB);
browserWindow.gBrowser.pinTab(tab);
tab = browserWindow.gBrowser.addTab(CUST_TAB);
browserWindow.gBrowser.pinTab(tab);
browserWindow.gBrowser.selectTabAtIndex(4);
hoverTab(browserWindow.gBrowser.tabs[6]);
}),
},
},
};
/* helpers */
function fiveTabsHelper() {
// some with no favicon and some with. Selected tab in middle.
closeAllButOneTab("about:addons");
let browserWindow = Services.wm.getMostRecentWindow("navigator:browser");
browserWindow.gBrowser.loadTabs([
"about:addons",
"about:home",
DEFAULT_FAVICON_TAB,
"about:newtab",
CUST_TAB,
], true, true);
browserWindow.gBrowser.selectTabAtIndex(1);
}
function closeAllButOneTab(url = "about:blank") {
let browserWindow = Services.wm.getMostRecentWindow("navigator:browser");
let gBrowser = browserWindow.gBrowser;
// Close all tabs except the last so we don't quit the browser.
while (gBrowser.tabs.length > 1)
gBrowser.removeTab(gBrowser.selectedTab, {animate: false});
gBrowser.selectedBrowser.loadURI(url);
if (gBrowser.selectedTab.pinned)
gBrowser.unpinTab(gBrowser.selectedTab);
let newTabButton = browserWindow.document.getAnonymousElementByAttribute(browserWindow.gBrowser.tabContainer, "class", "tabs-newtab-button");
hoverTab(newTabButton, false);
}
function hoverTab(tab, hover = true) {
const inIDOMUtils = Cc["@mozilla.org/inspector/dom-utils;1"].getService(Ci.inIDOMUtils);
if (hover) {
inIDOMUtils.addPseudoClassLock(tab, ":hover");
} else {
inIDOMUtils.clearPseudoClassLocks(tab);
}
// XXX TODO: this isn't necessarily testing what we ship
if (tab.nextElementSibling)
tab.nextElementSibling.setAttribute("afterhovered", hover || null);
if (tab.previousElementSibling)
tab.previousElementSibling.setAttribute("beforehovered", hover || null);
}

Просмотреть файл

@ -0,0 +1,37 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
this.EXPORTED_SYMBOLS = ["TabsInTitlebar"];
const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
const PREF_TABS_IN_TITLEBAR = "browser.tabs.drawInTitlebar";
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/Task.jsm");
this.TabsInTitlebar = {
init(libDir) {},
configurations: {
tabsInTitlebar: {
applyConfig: Task.async(function*() {
if (Services.appinfo.OS == "Linux") {
return Promise.reject("TabsInTitlebar isn't supported on Linux");
}
Services.prefs.setBoolPref(PREF_TABS_IN_TITLEBAR, true);
}),
},
tabsOutsideTitlebar: {
applyConfig: Task.async(function*() {
Services.prefs.setBoolPref(PREF_TABS_IN_TITLEBAR, false);
}),
},
},
};

Просмотреть файл

@ -0,0 +1,56 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
this.EXPORTED_SYMBOLS = ["Toolbars"];
const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/Task.jsm");
this.Toolbars = {
init(libDir) {},
configurations: {
onlyNavBar: {
applyConfig: Task.async(function*() {
let browserWindow = Services.wm.getMostRecentWindow("navigator:browser");
let personalToolbar = browserWindow.document.getElementById("PersonalToolbar");
browserWindow.setToolbarVisibility(personalToolbar, false);
toggleMenubarIfNecessary(false);
}),
},
allToolbars: {
applyConfig: Task.async(function*() { // Boookmarks and menubar
let browserWindow = Services.wm.getMostRecentWindow("navigator:browser");
let personalToolbar = browserWindow.document.getElementById("PersonalToolbar");
browserWindow.setToolbarVisibility(personalToolbar, true);
toggleMenubarIfNecessary(true);
}),
verifyConfig: Task.async(function*() {
let browserWindow = Services.wm.getMostRecentWindow("navigator:browser");
if (browserWindow.fullScreen) {
return Promise.reject("The bookmark toolbar and menubar are not shown in fullscreen.");
}
}),
},
},
};
///// helpers /////
function toggleMenubarIfNecessary(visible) {
let browserWindow = Services.wm.getMostRecentWindow("navigator:browser");
// The menubar is not shown on OS X or while in fullScreen
if (Services.appinfo.OS != "Darwin" /*&& !browserWindow.fullScreen*/) {
let menubar = browserWindow.document.getElementById("toolbar-menubar");
browserWindow.setToolbarVisibility(menubar, visible);
}
}

Просмотреть файл

@ -0,0 +1,60 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
this.EXPORTED_SYMBOLS = ["WindowSize"];
const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/Task.jsm");
Cu.import("resource://gre/modules/Timer.jsm");
this.WindowSize = {
init(libDir) {
Services.prefs.setBoolPref("browser.fullscreen.autohide", false);
},
configurations: {
maximized: {
applyConfig: Task.async(function*() {
let browserWindow = Services.wm.getMostRecentWindow("navigator:browser");
browserWindow.fullScreen = false;
// Wait for the Lion fullscreen transition to end as there doesn't seem to be an event
// and trying to maximize while still leaving fullscreen doesn't work.
yield new Promise((resolve, reject) => {
setTimeout(function waitToLeaveFS() {
browserWindow.maximize();
resolve();
}, Services.appinfo.OS == "Darwin" ? 1500 : 0);
});
}),
},
normal: {
applyConfig: Task.async(() => {
let browserWindow = Services.wm.getMostRecentWindow("navigator:browser");
browserWindow.fullScreen = false;
browserWindow.restore();
}),
},
fullScreen: {
applyConfig: Task.async(function*() {
let browserWindow = Services.wm.getMostRecentWindow("navigator:browser");
browserWindow.fullScreen = true;
// OS X Lion fullscreen transition takes a while
yield new Promise((resolve, reject) => {
setTimeout(function waitAfterEnteringFS() {
resolve();
}, Services.appinfo.OS == "Darwin" ? 1500 : 0);
});
}),
},
},
};

Просмотреть файл

@ -0,0 +1,33 @@
<?xml version="1.0"?>
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:em="http://www.mozilla.org/2004/em-rdf#">
<Description about="urn:mozilla:install-manifest">
<em:id>mozscreenshots@mozilla.org</em:id>
#expand <em:version>__MOZILLA_VERSION_U__</em:version>
<em:bootstrap>true</em:bootstrap>
<!-- for running custom screenshot binaries -->
<em:unpack>true</em:unpack>
<!-- Front End MetaData -->
<em:name>mozscreenshots</em:name>
<em:description>Take screenshots of Mozilla applications in various UI configurations.</em:description>
<em:creator>Mozilla</em:creator>
<em:targetApplication>
<Description>
<!-- Firefox -->
<em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
#expand <em:minVersion>__MOZILLA_VERSION_U__</em:minVersion>
<em:maxVersion>*</em:maxVersion>
</Description>
</em:targetApplication>
</Description>
</RDF>

Просмотреть файл

@ -0,0 +1,6 @@
mozscreenshots.jar:
% content mozscreenshots chrome/mozscreenshots/
Screenshot.jsm
TestRunner.jsm
configurations/ (configurations/*.jsm)
lib/ (lib/*.png)

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 343 B

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 522 B

Просмотреть файл

@ -0,0 +1,17 @@
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
XPI_NAME = 'mozscreenshots'
JAR_MANIFESTS += ['jar.mn']
USE_EXTENSION_MANIFEST = True
NO_JS_MANIFEST = True
FINAL_TARGET_PP_FILES += [
'bootstrap.js',
'install.rdf',
]

Просмотреть файл

@ -81,8 +81,6 @@ var CallsListView = Heritage.extend(WidgetMethods, {
gutter.appendChild(index);
contents.appendChild(gutter);
// Not all function calls have a caller that was stringified (e.g.
// context calls have a "gl" or "ctx" caller preview).
if (call.callerPreview) {
let context = document.createElement("label");
context.className = "plain call-item-context";

Просмотреть файл

@ -40,7 +40,7 @@ function* ifTestingSupported() {
is(functionCalls[0].line, 25,
"The called function's line is correct.");
is(functionCalls[0].callerPreview, "ctx",
is(functionCalls[0].callerPreview, "Object",
"The called function's caller preview is correct.");
is(functionCalls[0].argsPreview, "0, 0, 128, 128",
"The called function's args preview is correct.");

Просмотреть файл

@ -41,7 +41,7 @@ function* ifTestingSupported() {
"The first called function's line is correct.");
is(functionCalls[0].argsPreview, "0, 0, 128, 128",
"The first called function's args preview is correct.");
is(functionCalls[0].callerPreview, "ctx",
is(functionCalls[0].callerPreview, "Object",
"The first called function's caller preview is correct.");
is(functionCalls[6].type, CallWatcherFront.METHOD_FUNCTION,
@ -54,7 +54,7 @@ function* ifTestingSupported() {
"The penultimate called function's line is correct.");
is(functionCalls[6].argsPreview, "10, 10, 55, 50",
"The penultimate called function's args preview is correct.");
is(functionCalls[6].callerPreview, "ctx",
is(functionCalls[6].callerPreview, "Object",
"The penultimate called function's caller preview is correct.");
is(functionCalls[7].type, CallWatcherFront.METHOD_FUNCTION,
@ -67,7 +67,7 @@ function* ifTestingSupported() {
"The last called function's line is correct.");
ok(functionCalls[7].argsPreview.includes("Function"),
"The last called function's args preview is correct.");
is(functionCalls[7].callerPreview, "",
is(functionCalls[7].callerPreview, "Object",
"The last called function's caller preview is correct.");
yield removeTab(target.tab);

Просмотреть файл

@ -41,7 +41,7 @@ function* ifTestingSupported() {
"The first called function's line is correct.");
is(functionCalls[0].argsPreview, "0, 0, 128, 128",
"The first called function's args preview is correct.");
is(functionCalls[0].callerPreview, "ctx",
is(functionCalls[0].callerPreview, "Object",
"The first called function's caller preview is correct.");
is(functionCalls[6].type, CallWatcherFront.METHOD_FUNCTION,
@ -54,7 +54,7 @@ function* ifTestingSupported() {
"The penultimate called function's line is correct.");
is(functionCalls[6].argsPreview, "10, 10, 55, 50",
"The penultimate called function's args preview is correct.");
is(functionCalls[6].callerPreview, "ctx",
is(functionCalls[6].callerPreview, "Object",
"The penultimate called function's caller preview is correct.");
is(functionCalls[7].type, CallWatcherFront.METHOD_FUNCTION,
@ -67,7 +67,7 @@ function* ifTestingSupported() {
"The last called function's line is correct.");
ok(functionCalls[7].argsPreview.includes("Function"),
"The last called function's args preview is correct.");
is(functionCalls[7].callerPreview, "",
is(functionCalls[7].callerPreview, "Object",
"The last called function's caller preview is correct.");
let firstNonDrawCall = yield functionCalls[1].getDetails();

Просмотреть файл

@ -21,22 +21,22 @@ function* ifTestingSupported() {
"All the function calls should now be displayed in the UI.");
testItem(CallsListView.getItemAtIndex(0),
"1", "ctx", "clearRect", "(0, 0, 128, 128)", "doc_simple-canvas.html:25");
"1", "Object", "clearRect", "(0, 0, 128, 128)", "doc_simple-canvas.html:25");
testItem(CallsListView.getItemAtIndex(1),
"2", "ctx", "fillStyle", " = rgb(192, 192, 192)", "doc_simple-canvas.html:20");
"2", "Object", "fillStyle", " = rgb(192, 192, 192)", "doc_simple-canvas.html:20");
testItem(CallsListView.getItemAtIndex(2),
"3", "ctx", "fillRect", "(0, 0, 128, 128)", "doc_simple-canvas.html:21");
"3", "Object", "fillRect", "(0, 0, 128, 128)", "doc_simple-canvas.html:21");
testItem(CallsListView.getItemAtIndex(3),
"4", "ctx", "fillStyle", " = rgba(0, 0, 192, 0.5)", "doc_simple-canvas.html:20");
"4", "Object", "fillStyle", " = rgba(0, 0, 192, 0.5)", "doc_simple-canvas.html:20");
testItem(CallsListView.getItemAtIndex(4),
"5", "ctx", "fillRect", "(30, 30, 55, 50)", "doc_simple-canvas.html:21");
"5", "Object", "fillRect", "(30, 30, 55, 50)", "doc_simple-canvas.html:21");
testItem(CallsListView.getItemAtIndex(5),
"6", "ctx", "fillStyle", " = rgba(192, 0, 0, 0.5)", "doc_simple-canvas.html:20");
"6", "Object", "fillStyle", " = rgba(192, 0, 0, 0.5)", "doc_simple-canvas.html:20");
testItem(CallsListView.getItemAtIndex(6),
"7", "ctx", "fillRect", "(10, 10, 55, 50)", "doc_simple-canvas.html:21");
"7", "Object", "fillRect", "(10, 10, 55, 50)", "doc_simple-canvas.html:21");
testItem(CallsListView.getItemAtIndex(7),
"8", "", "requestAnimationFrame", "(Function)", "doc_simple-canvas.html:30");
@ -53,7 +53,7 @@ function* ifTestingSupported() {
is($(".call-item-context", item.target).getAttribute("value"), context,
"The item's context label has the correct text.");
} else {
is($(".call-item-context", item.target), null,
is($(".call-item-context", item.target) + "", "[object XULElement]",
"The item's context label should not be available.");
}

Просмотреть файл

@ -40,7 +40,7 @@ function* ifTestingSupported() {
"The visible item's line has the expected value.");
is(CallsListView.visibleItems[0].attachment.actor.argsPreview, "0, 0, 128, 128",
"The visible item's args have the expected value.");
is(CallsListView.visibleItems[0].attachment.actor.callerPreview, "ctx",
is(CallsListView.visibleItems[0].attachment.actor.callerPreview, "Object",
"The visible item's caller has the expected value.");
let secondRecordingFinished = once(window, EVENTS.SNAPSHOT_RECORDING_FINISHED);

Просмотреть файл

@ -28,7 +28,10 @@ let promise = require("promise");
const TEST_DIR = gTestPath.substr(0, gTestPath.lastIndexOf("/"));
const CHROME_URL_ROOT = TEST_DIR + "/";
const URL_ROOT = CHROME_URL_ROOT.replace("chrome://mochitests/content/", "http://example.com/");
const URL_ROOT = CHROME_URL_ROOT.replace("chrome://mochitests/content/",
"http://example.com/");
const URL_ROOT_SSL = CHROME_URL_ROOT.replace("chrome://mochitests/content/",
"https://example.com/");
// All test are asynchronous
waitForExplicitFinish();

Просмотреть файл

@ -8,7 +8,7 @@
const {PropertyView} =
require("devtools/client/inspector/computed/computed");
const TEST_URI = TEST_URL_ROOT + "doc_matched_selectors.html";
const TEST_URI = URL_ROOT + "doc_matched_selectors.html";
add_task(function*() {
yield addTab(TEST_URI);

Просмотреть файл

@ -7,7 +7,7 @@
// Tests that we correctly display appropriate media query titles in the
// property view.
const TEST_URI = TEST_URL_ROOT + "doc_media_queries.html";
const TEST_URI = URL_ROOT + "doc_media_queries.html";
var {PropertyView} = require("devtools/client/inspector/computed/computed");
var {CssLogic} = require("devtools/shared/inspector/css-logic");

Просмотреть файл

@ -7,7 +7,7 @@
// Tests that the computed view shows the original source link when source maps
// are enabled.
const TESTCASE_URI = TEST_URL_ROOT_SSL + "doc_sourcemaps.html";
const TESTCASE_URI = URL_ROOT_SSL + "doc_sourcemaps.html";
const PREF = "devtools.styleeditor.source-maps-enabled";
const SCSS_LOC = "doc_sourcemaps.scss:4";
const CSS_LOC = "doc_sourcemaps.css:1";

Просмотреть файл

@ -6,7 +6,7 @@
// Tests that pseudoelements are displayed correctly in the rule view.
const TEST_URI = TEST_URL_ROOT + "doc_pseudoelement.html";
const TEST_URI = URL_ROOT + "doc_pseudoelement.html";
add_task(function*() {
yield addTab(TEST_URI);

Просмотреть файл

@ -19,7 +19,9 @@ add_task(function*() {
info("Changing the node's style and waiting for the update");
let onUpdated = inspector.once("computed-view-refreshed");
getNode("#testdiv").style.cssText = "font-size: 15px; color: red;";
// FIXME: use the testActor to set style on the node.
content.document.querySelector("#testdiv")
.style.cssText = "font-size: 15px; color: red;";
yield onUpdated;
fontSize = getComputedViewPropertyValue(view, "font-size");

Просмотреть файл

@ -44,7 +44,7 @@ add_task(function*() {
yield checkSelectAll(view);
});
function checkCopySelection(view) {
function* checkCopySelection(view) {
info("Testing selection copy");
let contentDocument = view.styleDocument;
@ -63,16 +63,15 @@ function checkCopySelection(view) {
"font-size: 16px;[\\r\\n]+" +
"font-variant-caps: small-caps;[\\r\\n]*";
return waitForClipboard(() => {
fireCopyEvent(props[0]);
}, () => {
return checkClipboardData(expectedPattern);
}).then(() => {}, () => {
try {
yield waitForClipboard(() => fireCopyEvent(props[0]),
() => checkClipboardData(expectedPattern));
} catch (e) {
failedClipboard(expectedPattern);
});
}
}
function checkSelectAll(view) {
function* checkSelectAll(view) {
info("Testing select-all copy");
let contentDoc = view.styleDocument;
@ -86,13 +85,12 @@ function checkSelectAll(view) {
"font-size: 16px;[\\r\\n]+" +
"font-variant-caps: small-caps;[\\r\\n]*";
return waitForClipboard(() => {
fireCopyEvent(prop);
}, () => {
return checkClipboardData(expectedPattern);
}).then(() => {}, () => {
try {
yield waitForClipboard(() => fireCopyEvent(prop),
() => checkClipboardData(expectedPattern));
} catch (e) {
failedClipboard(expectedPattern);
});
}
}
function checkClipboardData(expectedPattern) {

Просмотреть файл

@ -1,137 +1,31 @@
/* 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/ */
"use strict";
let Cu = Components.utils;
let {gDevTools} = Cu.import("resource://devtools/client/framework/gDevTools.jsm", {});
let {require} = Cu.import("resource://devtools/shared/Loader.jsm", {});
let {TargetFactory} = require("devtools/client/framework/target");
let {CssComputedView} =
require("devtools/client/inspector/computed/computed");
let DevToolsUtils = require("devtools/shared/DevToolsUtils");
let promise = require("promise");
let {console} =
Components.utils.import("resource://gre/modules/Console.jsm", {});
// Import the inspector's head.js first (which itself imports shared-head.js).
Services.scriptloader.loadSubScript(
"chrome://mochitests/content/browser/devtools/client/inspector/test/head.js",
this);
// All tests are asynchronous
waitForExplicitFinish();
const TEST_URL_ROOT =
"http://example.com/browser/devtools/client/inspector/computed/test/";
const TEST_URL_ROOT_SSL =
"https://example.com/browser/devtools/client/inspector/computed/test/";
const ROOT_TEST_DIR = getRootDirectory(gTestPath);
const FRAME_SCRIPT_URL = ROOT_TEST_DIR + "doc_frame_script.js";
// Auto clean-up when a test ends
registerCleanupFunction(function*() {
let target = TargetFactory.forTab(gBrowser.selectedTab);
yield gDevTools.closeToolbox(target);
while (gBrowser.tabs.length > 1) {
gBrowser.removeCurrentTab();
}
});
// Uncomment this pref to dump all devtools emitted events to the console.
// Services.prefs.setBoolPref("devtools.dump.emit", true);
// Set the testing flag on gDevTools and reset it when the test ends
DevToolsUtils.testing = true;
registerCleanupFunction(() => DevToolsUtils.testing = false);
// Clean-up all prefs that might have been changed during a test run
// (safer here because if the test fails, then the pref is never reverted)
registerCleanupFunction(() => {
Services.prefs.clearUserPref("devtools.inspector.activeSidebar");
Services.prefs.clearUserPref("devtools.dump.emit");
Services.prefs.clearUserPref("devtools.defaultColorUnit");
});
/**
* The functions found below are here to ease test development and maintenance.
* Most of these functions are stateless and will require some form of context
* (the instance of the current toolbox, or inspector panel for instance).
*
* Most of these functions are async too and return promises.
*
* All tests should follow the following pattern:
*
* add_task(function*() {
* yield addTab(TEST_URI);
* let {toolbox, inspector, view} = yield openComputedView();
*
* yield selectNode("#test", inspector);
* yield someAsyncTestFunction(view);
* });
*
* add_task is the way to define the testcase in the test file. It accepts
* a single generator-function argument.
* The generator function should yield any async call.
*
* There is no need to clean tabs up at the end of a test as this is done
* automatically.
*
* It is advised not to store any references on the global scope. There
* shouldn't be a need to anyway. Thanks to add_task, test steps, even
* though asynchronous, can be described in a nice flat way, and
* if/for/while/... control flow can be used as in sync code, making it
* possible to write the outline of the test case all in add_task, and delegate
* actual processing and assertions to other functions.
* Open the toolbox, with the inspector tool visible, and the computed-view
* sidebar tab selected.
* @return a promise that resolves when the inspector is ready and the computed
* view is visible and ready
*/
/* *********************************************
* UTILS
* *********************************************
* General test utilities.
* Add new tabs, open the toolbox and switch to the various panels, select
* nodes, get node references, ...
*/
/**
* Add a new test tab in the browser and load the given url.
*
* @param {String} url
* The url to be loaded in the new tab
* @return a promise that resolves to the tab object when the url is loaded
*/
function addTab(url) {
info("Adding a new tab with URL: '" + url + "'");
let def = promise.defer();
window.focus();
let tab = window.gBrowser.selectedTab = window.gBrowser.addTab(url);
let browser = tab.linkedBrowser;
info("Loading the helper frame script " + FRAME_SCRIPT_URL);
browser.messageManager.loadFrameScript(FRAME_SCRIPT_URL, false);
browser.addEventListener("load", function onload() {
browser.removeEventListener("load", onload, true);
info("URL '" + url + "' loading complete");
def.resolve(tab);
}, true);
return def.promise;
}
/**
* Simple DOM node accesor function that takes either a node or a string css
* selector as argument and returns the corresponding node
*
* @param {String|DOMNode} nodeOrSelector
* @return {DOMNode|CPOW} Note that in e10s mode a CPOW object is returned which
* doesn't implement *all* of the DOMNode's properties
*/
function getNode(nodeOrSelector) {
info("Getting the node for '" + nodeOrSelector + "'");
return typeof nodeOrSelector === "string" ?
content.document.querySelector(nodeOrSelector) :
nodeOrSelector;
function openComputedView() {
return openInspectorSidebarTab("computedview").then(objects => {
return {
toolbox: objects.toolbox,
inspector: objects.inspector,
view: objects.view.view
};
});
}
/**
@ -146,187 +40,6 @@ function getNodeFront(selector, {walker}) {
return walker.querySelector(walker.rootNode, selector);
}
/*
* Set the inspector's current selection to a node or to the first match of the
* given css selector.
*
* @param {String|NodeFront} data
* The node to select
* @param {InspectorPanel} inspector
* The instance of InspectorPanel currently loaded in the toolbox
* @param {String} reason
* Defaults to "test" which instructs the inspector not
* to highlight the node upon selection
* @return {Promise} Resolves when the inspector is updated with the new node
*/
var selectNode = Task.async(function*(data, inspector, reason="test") {
info("Selecting the node for '" + data + "'");
let nodeFront = data;
if (!data._form) {
nodeFront = yield getNodeFront(data, inspector);
}
let updated = inspector.once("inspector-updated");
inspector.selection.setNodeFront(nodeFront, reason);
yield updated;
});
/**
* Open the toolbox, with the inspector tool visible.
*
* @return a promise that resolves when the inspector is ready
*/
var openInspector = Task.async(function*() {
info("Opening the inspector");
let target = TargetFactory.forTab(gBrowser.selectedTab);
let inspector, toolbox;
// Checking if the toolbox and the inspector are already loaded
// The inspector-updated event should only be waited for if the inspector
// isn't loaded yet
toolbox = gDevTools.getToolbox(target);
if (toolbox) {
inspector = toolbox.getPanel("inspector");
if (inspector) {
info("Toolbox and inspector already open");
return {
toolbox: toolbox,
inspector: inspector
};
}
}
info("Opening the toolbox");
toolbox = yield gDevTools.showToolbox(target, "inspector");
yield waitForToolboxFrameFocus(toolbox);
inspector = toolbox.getPanel("inspector");
info("Waiting for the inspector to update");
yield inspector.once("inspector-updated");
return {
toolbox: toolbox,
inspector: inspector
};
});
/**
* Wait for the toolbox frame to receive focus after it loads
*
* @param {Toolbox} toolbox
* @return a promise that resolves when focus has been received
*/
function waitForToolboxFrameFocus(toolbox) {
info("Making sure that the toolbox's frame is focused");
let def = promise.defer();
let win = toolbox.frame.contentWindow;
waitForFocus(def.resolve, win);
return def.promise;
}
/**
* Open the toolbox, with the inspector tool visible, and the sidebar that
* corresponds to the given id selected
*
* @return a promise that resolves when the inspector is ready and the sidebar
* view is visible and ready
*/
var openInspectorSideBar = Task.async(function*(id) {
let {toolbox, inspector} = yield openInspector();
if (!hasSideBarTab(inspector, id)) {
info("Waiting for the " + id + " sidebar to be ready");
yield inspector.sidebar.once(id + "-ready");
}
info("Selecting the " + id + " sidebar");
inspector.sidebar.select(id);
return {
toolbox: toolbox,
inspector: inspector,
view: inspector.sidebar.getWindowForTab(id)[id].view
};
});
/**
* Open the toolbox, with the inspector tool visible, and the computed-view
* sidebar tab selected.
*
* @return a promise that resolves when the inspector is ready and the computed
* view is visible and ready
*/
function openComputedView() {
return openInspectorSideBar("computedview");
}
/**
* Wait for eventName on target to be delivered a number of times.
*
* @param {Object} target
* An observable object that either supports on/off or
* addEventListener/removeEventListener
* @param {String} eventName
* @param {Number} numTimes
* Number of deliveries to wait for.
* @param {Boolean} useCapture
* Optional, for addEventListener/removeEventListener
* @return A promise that resolves when the event has been handled
*/
function waitForNEvents(target, eventName, numTimes, useCapture = false) {
info("Waiting for event: '" + eventName + "' on " + target + ".");
let deferred = promise.defer();
let count = 0;
for (let [add, remove] of [
["addEventListener", "removeEventListener"],
["addListener", "removeListener"],
["on", "off"]
]) {
if ((add in target) && (remove in target)) {
target[add](eventName, function onEvent(...aArgs) {
if (++count == numTimes) {
target[remove](eventName, onEvent, useCapture);
deferred.resolve.apply(deferred, aArgs);
}
}, useCapture);
break;
}
}
return deferred.promise;
}
/**
* Wait for eventName on target.
*
* @param {Object} target
* An observable object that either supports on/off or
* addEventListener/removeEventListener
* @param {String} eventName
* @param {Boolean} useCapture
* Optional, for addEventListener/removeEventListener
* @return A promise that resolves when the event has been handled
*/
function once(target, eventName, useCapture=false) {
return waitForNEvents(target, eventName, 1, useCapture);
}
/**
* This shouldn't be used in the tests, but is useful when writing new tests or
* debugging existing tests in order to introduce delays in the test steps
*
* @param {Number} ms
* The time to wait
* @return A promise that resolves when the time is passed
*/
function wait(ms) {
let def = promise.defer();
content.setTimeout(def.resolve, ms);
return def.promise;
}
/**
* Listen for a new tab to open and return a promise that resolves when one
* does and completes the load event.
@ -343,23 +56,6 @@ var waitForTab = Task.async(function*() {
return tab;
});
/**
* @see SimpleTest.waitForClipboard
*
* @param {Function} setup
* Function to execute before checking for the
* clipboard content
* @param {String|Boolean} expected
* An expected string or validator function
* @return a promise that resolves when the expected string has been found or
* the validator function has returned true, rejects otherwise.
*/
function waitForClipboard(setup, expected) {
let def = promise.defer();
SimpleTest.waitForClipboard(expected, setup, def.resolve, def.reject);
return def.promise;
}
/**
* Dispatch the copy event on the given element
*/
@ -369,18 +65,6 @@ function fireCopyEvent(element) {
element.dispatchEvent(evt);
}
/**
* Checks whether the inspector's sidebar corresponding to the given id already
* exists
*
* @param {InspectorPanel}
* @param {String}
* @return {Boolean}
*/
function hasSideBarTab(inspector, id) {
return !!inspector.sidebar.getWindowForTab(id);
}
/**
* Simulate the key input for the given input in the window.
*
@ -395,13 +79,6 @@ function synthesizeKeys(input, win) {
}
}
/* *********************************************
* COMPUTED-VIEW
* *********************************************
* Computed-view related utility functions.
* Allows to get properties, links, expand properties, ...
*/
/**
* Get references to the name and value span nodes corresponding to a given
* property name in the computed-view
@ -534,77 +211,3 @@ function getComputedViewLinkByIndex(view, index) {
let links = view.styleDocument.querySelectorAll(".rule-link .link");
return links[index];
}
/* *********************************************
* STYLE-EDITOR
* *********************************************
* Style-editor related utility functions.
*/
/**
* Wait for the toolbox to emit the styleeditor-selected event and when done
* wait for the stylesheet identified by href to be loaded in the stylesheet
* editor
*
* @param {Toolbox} toolbox
* @param {String} href
* Optional, if not provided, wait for the first editor to be ready
* @return a promise that resolves to the editor when the stylesheet editor is
* ready
*/
function waitForStyleEditor(toolbox, href) {
let def = promise.defer();
info("Waiting for the toolbox to switch to the styleeditor");
toolbox.once("styleeditor-selected").then(() => {
let panel = toolbox.getCurrentPanel();
ok(panel && panel.UI, "Styleeditor panel switched to front");
// A helper that resolves the promise once it receives an editor that
// matches the expected href. Returns false if the editor was not correct.
let gotEditor = (event, editor) => {
let currentHref = editor.styleSheet.href;
if (!href || (href && currentHref.endsWith(href))) {
info("Stylesheet editor selected");
panel.UI.off("editor-selected", gotEditor);
editor.getSourceEditor().then(sourceEditor => {
info("Stylesheet editor fully loaded");
def.resolve(sourceEditor);
});
return true;
}
info("The editor was incorrect. Waiting for editor-selected event.");
return false;
};
// The expected editor may already be selected. Check the if the currently
// selected editor is the expected one and if not wait for an
// editor-selected event.
if (!gotEditor("styleeditor-selected", panel.UI.selectedEditor)) {
// The expected editor is not selected (yet). Wait for it.
panel.UI.on("editor-selected", gotEditor);
}
});
return def.promise;
}
/**
* Reload the current page and wait for the inspector to be initialized after
* the navigation
*
* @param {InspectorPanel} inspector
* The instance of InspectorPanel currently loaded in the toolbox
* @return a promise that resolves after page reload and inspector
* initialization
*/
function reloadPage(inspector) {
let onNewRoot = inspector.once("new-root");
content.location.reload();
return onNewRoot.then(() => {
inspector.markup._waitForChildren();
});
}

Просмотреть файл

@ -5,23 +5,23 @@
requestLongerTimeout(2);
const TEST_URI = BASE_URI + "browser_fontinspector.html";
const TEST_URI = URL_ROOT + "browser_fontinspector.html";
const FONTS = [
{name: "Ostrich Sans Medium", remote: true, url: BASE_URI + "ostrich-regular.ttf",
{name: "Ostrich Sans Medium", remote: true, url: URL_ROOT + "ostrich-regular.ttf",
format: "truetype", cssName: "bar"},
{name: "Ostrich Sans Black", remote: true, url: BASE_URI + "ostrich-black.ttf",
{name: "Ostrich Sans Black", remote: true, url: URL_ROOT + "ostrich-black.ttf",
format: "", cssName: "bar"},
{name: "Ostrich Sans Black", remote: true, url: BASE_URI + "ostrich-black.ttf",
{name: "Ostrich Sans Black", remote: true, url: URL_ROOT + "ostrich-black.ttf",
format: "", cssName: "bar"},
{name: "Ostrich Sans Medium", remote: true, url: BASE_URI + "ostrich-regular.ttf",
{name: "Ostrich Sans Medium", remote: true, url: URL_ROOT + "ostrich-regular.ttf",
format: "", cssName: "barnormal"},
];
add_task(function*() {
let { inspector, fontInspector } = yield openFontInspectorForURL(TEST_URI);
ok(!!fontInspector, "Font inspector document is alive.");
let { inspector, view } = yield openFontInspectorForURL(TEST_URI);
ok(!!view, "Font inspector document is alive.");
let viewDoc = fontInspector.chromeDoc;
let viewDoc = view.chromeDoc;
yield testBodyFonts(inspector, viewDoc);
yield testDivFonts(inspector, viewDoc);

Просмотреть файл

@ -6,11 +6,11 @@
// Test that correct previews are shown if the text is edited after 'Show all'
// button is pressed.
const TEST_URI = BASE_URI + "browser_fontinspector.html";
const TEST_URI = URL_ROOT + "browser_fontinspector.html";
add_task(function*() {
let { inspector, fontInspector } = yield openFontInspectorForURL(TEST_URI);
let viewDoc = fontInspector.chromeDoc;
let { inspector, view } = yield openFontInspectorForURL(TEST_URI);
let viewDoc = view.chromeDoc;
info("Selecting a node that doesn't contain all document fonts.");
yield selectNode(".normal-text", inspector);
@ -36,7 +36,7 @@ add_task(function*() {
"The .normal-text didn't show all fonts.");
info("Editing the preview text.");
yield updatePreviewText(fontInspector, "The quick brown");
yield updatePreviewText(view, "The quick brown");
let numPreviews = viewDoc.querySelectorAll("#all-fonts .font-preview").length;
is(numPreviews, allFontsNumPreviews,

Просмотреть файл

@ -7,25 +7,25 @@
// exact preview images because they are drawn on a canvas causing them to vary
// between systems, platforms and software versions.
const TEST_URI = BASE_URI + "browser_fontinspector.html";
const TEST_URI = URL_ROOT + "browser_fontinspector.html";
add_task(function*() {
let { inspector, fontInspector } = yield openFontInspectorForURL(TEST_URI);
let viewDoc = fontInspector.chromeDoc;
let {view} = yield openFontInspectorForURL(TEST_URI);
let viewDoc = view.chromeDoc;
let previews = viewDoc.querySelectorAll("#all-fonts .font-preview");
let initialPreviews = [...previews].map(p => p.src);
info("Typing 'Abc' to check that the reference previews are correct.");
yield updatePreviewText(fontInspector, "Abc");
yield updatePreviewText(view, "Abc");
checkPreviewImages(viewDoc, initialPreviews, true);
info("Typing something else to the preview box.");
yield updatePreviewText(fontInspector, "The quick brown");
yield updatePreviewText(view, "The quick brown");
checkPreviewImages(viewDoc, initialPreviews, false);
info("Blanking the input to restore default previews.");
yield updatePreviewText(fontInspector, "");
yield updatePreviewText(view, "");
checkPreviewImages(viewDoc, initialPreviews, true);
});

Просмотреть файл

@ -9,7 +9,7 @@ requestLongerTimeout(2);
const { getTheme, setTheme } = require("devtools/client/shared/theme");
const TEST_URI = BASE_URI + "browser_fontinspector.html";
const TEST_URI = URL_ROOT + "browser_fontinspector.html";
const originalTheme = getTheme();
registerCleanupFunction(() => {
@ -18,8 +18,8 @@ registerCleanupFunction(() => {
});
add_task(function* () {
let { inspector, fontInspector } = yield openFontInspectorForURL(TEST_URI);
let { chromeDoc: doc } = fontInspector;
let { inspector, view } = yield openFontInspectorForURL(TEST_URI);
let { chromeDoc: doc } = view;
yield selectNode(".normal-text", inspector);

Просмотреть файл

@ -2,79 +2,21 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
// shared-head.js handles imports, constants, and utility functions
Services.scriptloader.loadSubScript("chrome://mochitests/content/browser/devtools/client/framework/test/shared-head.js", this);
const BASE_URI = "http://mochi.test:8888/browser/devtools/client/inspector/fonts/test/";
/**
* Open the toolbox, with the inspector tool visible.
* @param {Function} cb Optional callback, if you don't want to use the returned
* promise
* @return a promise that resolves when the inspector is ready
*/
var openInspector = Task.async(function*(cb) {
info("Opening the inspector");
let target = TargetFactory.forTab(gBrowser.selectedTab);
let inspector, toolbox;
// Checking if the toolbox and the inspector are already loaded
// The inspector-updated event should only be waited for if the inspector
// isn't loaded yet
toolbox = gDevTools.getToolbox(target);
if (toolbox) {
inspector = toolbox.getPanel("inspector");
if (inspector) {
info("Toolbox and inspector already open");
if (cb) {
return cb(inspector, toolbox);
} else {
return {
toolbox: toolbox,
inspector: inspector
};
}
}
}
info("Opening the toolbox");
toolbox = yield gDevTools.showToolbox(target, "inspector");
yield waitForToolboxFrameFocus(toolbox);
inspector = toolbox.getPanel("inspector");
info("Waiting for the inspector to update");
yield inspector.once("inspector-updated");
if (cb) {
return cb(inspector, toolbox);
} else {
return {
toolbox: toolbox,
inspector: inspector
};
}
});
// Import the inspector's head.js first (which itself imports shared-head.js).
Services.scriptloader.loadSubScript(
"chrome://mochitests/content/browser/devtools/client/inspector/test/head.js",
this);
/**
* Adds a new tab with the given URL, opens the inspector and selects the
* font-inspector tab.
*
* @return Object
* {
* toolbox,
* inspector,
* fontInspector
* }
* @return {Promise} resolves to a {toolbox, inspector, view} object
*/
var openFontInspectorForURL = Task.async(function* (url) {
info("Opening tab " + url);
var openFontInspectorForURL = Task.async(function*(url) {
yield addTab(url);
let { toolbox, inspector } = yield openInspector();
let {toolbox, inspector} = yield openInspectorSidebarTab("fontinspector");
/**
* Call selectNode to trigger font-inspector update so that we don't timeout
@ -88,74 +30,29 @@ var openFontInspectorForURL = Task.async(function* (url) {
* FontInspector.update that emits the 'fontinspector-updated' event.
*/
let onUpdated = inspector.once("fontinspector-updated");
yield selectNode("body", inspector);
inspector.sidebar.select("fontinspector");
info("Waiting for font-inspector to update.");
yield onUpdated;
info("Font Inspector ready.");
let { fontInspector } = inspector.sidebar.getWindowForTab("fontinspector");
return {
fontInspector,
toolbox,
inspector,
toolbox
view: inspector.sidebar.getWindowForTab("fontinspector").fontInspector
};
});
/**
* Select a node in the inspector given its selector.
*/
var selectNode = Task.async(function*(selector, inspector, reason="test") {
info("Selecting the node for '" + selector + "'");
let nodeFront = yield getNodeFront(selector, inspector);
let updated = inspector.once("inspector-updated");
inspector.selection.setNodeFront(nodeFront, reason);
yield updated;
});
/**
* Get the NodeFront for a given css selector, via the protocol
* @param {String|NodeFront} selector
* @param {InspectorPanel} inspector The instance of InspectorPanel currently
* loaded in the toolbox
* @return {Promise} Resolves to the NodeFront instance
*/
function getNodeFront(selector, {walker}) {
if (selector._form) {
return selector;
}
return walker.querySelector(walker.rootNode, selector);
}
/**
* Wait for the toolbox frame to receive focus after it loads
* @param {Toolbox} toolbox
* @return a promise that resolves when focus has been received
*/
function waitForToolboxFrameFocus(toolbox) {
info("Making sure that the toolbox's frame is focused");
let def = promise.defer();
let win = toolbox.frame.contentWindow;
waitForFocus(def.resolve, win);
return def.promise;
}
/**
* Clears the preview input field, types new text into it and waits for the
* preview images to be updated.
*
* @param {FontInspector} fontInspector - The FontInspector instance.
* @param {FontInspector} view - The FontInspector instance.
* @param {String} text - The text to preview.
*/
function* updatePreviewText(fontInspector, text) {
function* updatePreviewText(view, text) {
info(`Changing the preview text to '${text}'`);
let doc = fontInspector.chromeDoc;
let doc = view.chromeDoc;
let input = doc.getElementById("preview-text-input");
let update = fontInspector.inspector.once("fontinspector-updated");
let update = view.inspector.once("fontinspector-updated");
info("Focusing the input field.");
input.focus();

Просмотреть файл

@ -45,52 +45,29 @@ function selectAndHighlightNode(nodeOrSelector, inspector) {
return updated;
}
/**
* Checks whether the inspector's sidebar corresponding to the given id already
* exists
* @param {InspectorPanel}
* @param {String}
* @return {Boolean}
*/
function hasSideBarTab(inspector, id) {
return !!inspector.sidebar.getWindowForTab(id);
}
/**
* Open the toolbox, with the inspector tool visible, and the layout-view
* sidebar tab selected.
* @return a promise that resolves when the inspector is ready and the layout
* view is visible and ready
*/
var openLayoutView = Task.async(function*() {
let {toolbox, inspector} = yield openInspector();
function openLayoutView() {
return openInspectorSidebarTab("layoutview").then(objects => {
// The actual highligher show/hide methods are mocked in layoutview tests.
// The highlighter is tested in devtools/inspector/test.
function mockHighlighter({highlighter}) {
highlighter.showBoxModel = function(nodeFront, options) {
return promise.resolve();
};
highlighter.hideBoxModel = function() {
return promise.resolve();
};
}
mockHighlighter(objects.toolbox);
// The actual highligher show/hide methods are mocked in layoutview tests.
// The highlighter is tested in devtools/inspector/test.
function mockHighlighter({highlighter}) {
highlighter.showBoxModel = function(nodeFront, options) {
return promise.resolve();
};
highlighter.hideBoxModel = function() {
return promise.resolve();
};
}
mockHighlighter(toolbox);
if (!hasSideBarTab(inspector, "layoutview")) {
info("Waiting for the layoutview sidebar to be ready");
yield inspector.sidebar.once("layoutview-ready");
}
info("Selecting the layoutview sidebar");
inspector.sidebar.select("layoutview");
return {
toolbox: toolbox,
inspector: inspector,
view: inspector.sidebar.getWindowForTab("layoutview")["layoutview"]
};
});
return objects;
});
}
/**
* Wait for the layoutview-updated event.

Просмотреть файл

@ -5,10 +5,10 @@
"use strict";
// Test native anonymous content in the markupview.
const TEST_URL = TEST_URL_ROOT + "doc_markup_anonymous.html";
const TEST_URL = URL_ROOT + "doc_markup_anonymous.html";
add_task(function*() {
let {inspector} = yield addTab(TEST_URL).then(openInspector);
let {inspector} = yield openInspectorForURL(TEST_URL);
let pseudo = yield getNodeFront("#pseudo", inspector);

Просмотреть файл

@ -10,7 +10,7 @@ requestLongerTimeout(2);
const TEST_URL = "chrome://devtools/content/scratchpad/scratchpad.xul";
add_task(function*() {
let {inspector} = yield addTab(TEST_URL).then(openInspector);
let {inspector} = yield openInspectorForURL(TEST_URL);
let toolbarbutton = yield getNodeFront("toolbarbutton", inspector);
let children = yield inspector.walker.children(toolbarbutton);

Просмотреть файл

@ -7,12 +7,12 @@
// Test shadow DOM content in the markupview.
// Note that many features are not yet enabled, but basic listing
// of elements should be working.
const TEST_URL = TEST_URL_ROOT + "doc_markup_anonymous.html";
const TEST_URL = URL_ROOT + "doc_markup_anonymous.html";
add_task(function*() {
Services.prefs.setBoolPref("dom.webcomponents.enabled", true);
let {inspector} = yield addTab(TEST_URL).then(openInspector);
let {inspector} = yield openInspectorForURL(TEST_URL);
let shadow = yield getNodeFront("#shadow", inspector.markup);
let children = yield inspector.walker.children(shadow);

Просмотреть файл

@ -6,12 +6,12 @@
// Test native anonymous content in the markupview with devtools.inspector.showAllAnonymousContent
// set to true
const TEST_URL = TEST_URL_ROOT + "doc_markup_anonymous.html";
const TEST_URL = URL_ROOT + "doc_markup_anonymous.html";
add_task(function*() {
Services.prefs.setBoolPref("devtools.inspector.showAllAnonymousContent", true);
let {inspector} = yield addTab(TEST_URL).then(openInspector);
let {inspector} = yield openInspectorForURL(TEST_URL);
let native = yield getNodeFront("#native", inspector);

Просмотреть файл

@ -12,7 +12,7 @@
// The correctness and cycling of the suggestions is covered in the ruleview
// tests.
const TEST_URL = TEST_URL_ROOT + "doc_markup_edit.html";
const TEST_URL = URL_ROOT + "doc_markup_edit.html";
// test data format :
// [
// what key to press,
@ -65,7 +65,7 @@ const TEST_DATA = [
add_task(function*() {
info("Opening the inspector on the test URL");
let {inspector} = yield addTab(TEST_URL).then(openInspector);
let {inspector} = yield openInspectorForURL(TEST_URL);
yield inspector.markup.expandAll();

Просмотреть файл

@ -7,10 +7,10 @@
// Test that dragging a node near the top or bottom edge of the markup-view
// auto-scrolls the view.
const TEST_URL = TEST_URL_ROOT + "doc_markup_dragdrop_autoscroll.html";
const TEST_URL = URL_ROOT + "doc_markup_dragdrop_autoscroll.html";
add_task(function*() {
let {inspector} = yield addTab(TEST_URL).then(openInspector);
let {inspector} = yield openInspectorForURL(TEST_URL);
let markup = inspector.markup;
let viewHeight = markup.doc.documentElement.clientHeight;

Просмотреть файл

@ -8,14 +8,14 @@
// the minimum vertical distance defined in markup-view.js by
// DRAG_DROP_MIN_INITIAL_DISTANCE.
const TEST_URL = TEST_URL_ROOT + "doc_markup_dragdrop.html";
const TEST_URL = URL_ROOT + "doc_markup_dragdrop.html";
const TEST_NODE = "#test";
// Keep this in sync with DRAG_DROP_MIN_INITIAL_DISTANCE in markup-view.js
const MIN_DISTANCE = 10;
add_task(function*() {
let {inspector} = yield addTab(TEST_URL).then(openInspector);
let {inspector} = yield openInspectorForURL(TEST_URL);
info("Drag the test node by half of the minimum distance");
yield simulateNodeDrag(inspector, TEST_NODE, 0, MIN_DISTANCE / 2);

Просмотреть файл

@ -6,11 +6,11 @@
// Test that the root node isn't draggable (as well as head and body).
const TEST_URL = TEST_URL_ROOT + "doc_markup_dragdrop.html";
const TEST_URL = URL_ROOT + "doc_markup_dragdrop.html";
const TEST_DATA = ["html", "head", "body"];
add_task(function*() {
let {inspector} = yield addTab(TEST_URL).then(openInspector);
let {inspector} = yield openInspectorForURL(TEST_URL);
for (let selector of TEST_DATA) {
info("Try to drag/drop node " + selector);

Просмотреть файл

@ -6,10 +6,10 @@
// Test whether ESCAPE keypress cancels dragging of an element.
const TEST_URL = TEST_URL_ROOT + "doc_markup_dragdrop.html";
const TEST_URL = URL_ROOT + "doc_markup_dragdrop.html";
add_task(function*() {
let {inspector} = yield addTab(TEST_URL).then(openInspector);
let {inspector} = yield openInspectorForURL(TEST_URL);
let {markup} = inspector;
info("Get a test container");

Просмотреть файл

@ -6,12 +6,12 @@
// Check that pseudo-elements and anonymous nodes are not draggable.
const TEST_URL = TEST_URL_ROOT + "doc_markup_dragdrop.html";
const TEST_URL = URL_ROOT + "doc_markup_dragdrop.html";
add_task(function*() {
Services.prefs.setBoolPref("devtools.inspector.showAllAnonymousContent", true);
let {inspector} = yield addTab(TEST_URL).then(openInspector);
let {inspector} = yield openInspectorForURL(TEST_URL);
info("Expanding nodes below #test");
let parentFront = yield getNodeFront("#test", inspector);

Просмотреть файл

@ -8,10 +8,10 @@ requestLongerTimeout(2);
// Test different kinds of drag and drop node re-ordering.
const TEST_URL = TEST_URL_ROOT + "doc_markup_dragdrop.html";
const TEST_URL = URL_ROOT + "doc_markup_dragdrop.html";
add_task(function*() {
let {inspector} = yield addTab(TEST_URL).then(openInspector);
let {inspector} = yield openInspectorForURL(TEST_URL);
let ids;
info("Expand #test node");

Просмотреть файл

@ -5,7 +5,7 @@
const TEST_URL = "data:text/html;charset=utf8,<img src=\"about:logo\" /><div>";
add_task(function*() {
let {inspector} = yield addTab(TEST_URL).then(openInspector);
let {inspector} = yield openInspectorForURL(TEST_URL);
let {markup} = inspector;
info("Get the tooltip target element for the image's src attribute");

Просмотреть файл

@ -3,7 +3,7 @@
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
const TEST_URL = TEST_URL_ROOT + "doc_markup_events-overflow.html";
const TEST_URL = URL_ROOT + "doc_markup_events-overflow.html";
const TEST_DATA = [
{
desc: "editor overflows container",
@ -29,7 +29,7 @@ const TEST_DATA = [
];
add_task(function*() {
let { inspector } = yield addTab(TEST_URL).then(openInspector);
let { inspector } = yield openInspectorForURL(TEST_URL);
let markupContainer = yield getContainerForSelector("#events", inspector);
let evHolder = markupContainer.elt.querySelector(".markupview-events");

Просмотреть файл

@ -7,7 +7,7 @@
// Test that markup view event bubbles show the correct event info for DOM
// events.
const TEST_URL = TEST_URL_ROOT + "doc_markup_events.html";
const TEST_URL = URL_ROOT + "doc_markup_events.html";
loadHelperScript("helper_events_test_runner.js");

Просмотреть файл

@ -9,16 +9,16 @@
// The test registers one backend actor providing custom form data
// and checks that the value is properly sent to the client (NodeFront).
const TEST_PAGE_URL = TEST_URL_ROOT + "doc_markup_events_form.html";
const TEST_ACTOR_URL = CHROME_BASE + "actor_events_form.js";
const TEST_PAGE_URL = URL_ROOT + "doc_markup_events_form.html";
const TEST_ACTOR_URL = CHROME_URL_ROOT + "actor_events_form.js";
var {ActorRegistryFront} = require("devtools/server/actors/actor-registry");
var {EventsFormFront} = require(TEST_ACTOR_URL);
add_task(function*() {
info("Opening the Toolbox");
let {tab} = yield addTab(TEST_PAGE_URL);
let {toolbox} = yield openToolbox("webconsole");
let tab = yield addTab(TEST_PAGE_URL);
let toolbox = yield openToolboxForTab(tab, "webconsole");
info("Registering test actor");
let {registrar, front} = yield registerTestActor(toolbox);

Просмотреть файл

@ -8,7 +8,7 @@
// and jQuery Live events (jQuery version 1.0).
const TEST_LIB = "lib_jquery_1.0.js";
const TEST_URL = TEST_URL_ROOT + "doc_markup_events_jquery.html?" + TEST_LIB;
const TEST_URL = URL_ROOT + "doc_markup_events_jquery.html?" + TEST_LIB;
loadHelperScript("helper_events_test_runner.js");
@ -18,7 +18,7 @@ const TEST_DATA = [
expected: [
{
type: "load",
filename: TEST_URL_ROOT + TEST_LIB,
filename: URL_ROOT + TEST_LIB,
attributes: [
"jQuery"
],
@ -104,7 +104,7 @@ const TEST_DATA = [
},
{
type: "load",
filename: TEST_URL_ROOT + TEST_LIB,
filename: URL_ROOT + TEST_LIB,
attributes: [
"Bubbling",
"DOM0"
@ -159,7 +159,7 @@ const TEST_DATA = [
},
{
type: "click",
filename: TEST_URL_ROOT + TEST_LIB + ":894",
filename: URL_ROOT + TEST_LIB + ":894",
attributes: [
"Bubbling",
"DOM2"
@ -199,7 +199,7 @@ const TEST_DATA = [
},
{
type: "keydown",
filename: TEST_URL_ROOT + TEST_LIB + ":894",
filename: URL_ROOT + TEST_LIB + ":894",
attributes: [
"Bubbling",
"DOM2"

Просмотреть файл

@ -8,7 +8,7 @@
// and jQuery Live events (jQuery version 1.1).
const TEST_LIB = "lib_jquery_1.1.js";
const TEST_URL = TEST_URL_ROOT + "doc_markup_events_jquery.html?" + TEST_LIB;
const TEST_URL = URL_ROOT + "doc_markup_events_jquery.html?" + TEST_LIB;
loadHelperScript("helper_events_test_runner.js");
@ -18,7 +18,7 @@ const TEST_DATA = [
expected: [
{
type: "load",
filename: TEST_URL_ROOT + TEST_LIB,
filename: URL_ROOT + TEST_LIB,
attributes: [
"jQuery"
],
@ -108,7 +108,7 @@ const TEST_DATA = [
},
{
type: "load",
filename: TEST_URL_ROOT + TEST_LIB,
filename: URL_ROOT + TEST_LIB,
attributes: [
"Bubbling",
"DOM0"
@ -173,7 +173,7 @@ const TEST_DATA = [
},
{
type: "click",
filename: TEST_URL_ROOT + TEST_LIB + ":1224",
filename: URL_ROOT + TEST_LIB + ":1224",
attributes: [
"Bubbling",
"DOM2"
@ -223,7 +223,7 @@ const TEST_DATA = [
},
{
type: "keydown",
filename: TEST_URL_ROOT + TEST_LIB + ":1224",
filename: URL_ROOT + TEST_LIB + ":1224",
attributes: [
"Bubbling",
"DOM2"

Просмотреть файл

@ -8,7 +8,7 @@
// and jQuery Live events (jQuery version 1.11.1).
const TEST_LIB = "lib_jquery_1.11.1_min.js";
const TEST_URL = TEST_URL_ROOT + "doc_markup_events_jquery.html?" + TEST_LIB;
const TEST_URL = URL_ROOT + "doc_markup_events_jquery.html?" + TEST_LIB;
loadHelperScript("helper_events_test_runner.js");
@ -105,7 +105,7 @@ const TEST_DATA = [
},
{
type: "click",
filename: TEST_URL_ROOT + TEST_LIB + ":3",
filename: URL_ROOT + TEST_LIB + ":3",
attributes: [
"Bubbling",
"DOM2"
@ -126,7 +126,7 @@ const TEST_DATA = [
},
{
type: "keydown",
filename: TEST_URL_ROOT + TEST_LIB + ":3",
filename: URL_ROOT + TEST_LIB + ":3",
attributes: [
"Bubbling",
"DOM2"

Просмотреть файл

@ -8,7 +8,7 @@
// and jQuery Live events (jQuery version 1.2).
const TEST_LIB = "lib_jquery_1.2_min.js";
const TEST_URL = TEST_URL_ROOT + "doc_markup_events_jquery.html?" + TEST_LIB;
const TEST_URL = URL_ROOT + "doc_markup_events_jquery.html?" + TEST_LIB;
loadHelperScript("helper_events_test_runner.js");
@ -79,7 +79,7 @@ const TEST_DATA = [
},
{
type: "load",
filename: TEST_URL_ROOT + TEST_LIB,
filename: URL_ROOT + TEST_LIB,
attributes: [
"Bubbling",
"DOM0"
@ -144,7 +144,7 @@ const TEST_DATA = [
},
{
type: "click",
filename: TEST_URL_ROOT + TEST_LIB + ":24",
filename: URL_ROOT + TEST_LIB + ":24",
attributes: [
"Bubbling",
"DOM2"
@ -168,7 +168,7 @@ const TEST_DATA = [
},
{
type: "keydown",
filename: TEST_URL_ROOT + TEST_LIB + ":24",
filename: URL_ROOT + TEST_LIB + ":24",
attributes: [
"Bubbling",
"DOM2"

Просмотреть файл

@ -8,7 +8,7 @@
// and jQuery Live events (jQuery version 1.3).
const TEST_LIB = "lib_jquery_1.3_min.js";
const TEST_URL = TEST_URL_ROOT + "doc_markup_events_jquery.html?" + TEST_LIB;
const TEST_URL = URL_ROOT + "doc_markup_events_jquery.html?" + TEST_LIB;
loadHelperScript("helper_events_test_runner.js");
@ -18,7 +18,7 @@ const TEST_DATA = [
expected: [
{
type: "load",
filename: TEST_URL_ROOT + TEST_LIB + ":19",
filename: URL_ROOT + TEST_LIB + ":19",
attributes: [
"jQuery"
],
@ -98,7 +98,7 @@ const TEST_DATA = [
},
{
type: "load",
filename: TEST_URL_ROOT + TEST_LIB + ":19",
filename: URL_ROOT + TEST_LIB + ":19",
attributes: [
"Bubbling",
"DOM2"
@ -109,7 +109,7 @@ const TEST_DATA = [
},
{
type: "unload",
filename: TEST_URL_ROOT + TEST_LIB + ":19",
filename: URL_ROOT + TEST_LIB + ":19",
attributes: [
"jQuery"
],
@ -120,7 +120,7 @@ const TEST_DATA = [
},
{
type: "unload",
filename: TEST_URL_ROOT + TEST_LIB + ":19",
filename: URL_ROOT + TEST_LIB + ":19",
attributes: [
"Bubbling",
"DOM2"
@ -156,7 +156,7 @@ const TEST_DATA = [
},
{
type: "click",
filename: TEST_URL_ROOT + TEST_LIB + ":19",
filename: URL_ROOT + TEST_LIB + ":19",
attributes: [
"Bubbling",
"DOM2"
@ -177,7 +177,7 @@ const TEST_DATA = [
},
{
type: "keydown",
filename: TEST_URL_ROOT + TEST_LIB + ":19",
filename: URL_ROOT + TEST_LIB + ":19",
attributes: [
"Bubbling",
"DOM2"

Просмотреть файл

@ -8,7 +8,7 @@
// and jQuery Live events (jQuery version 1.4).
const TEST_LIB = "lib_jquery_1.4_min.js";
const TEST_URL = TEST_URL_ROOT + "doc_markup_events_jquery.html?" + TEST_LIB;
const TEST_URL = URL_ROOT + "doc_markup_events_jquery.html?" + TEST_LIB;
loadHelperScript("helper_events_test_runner.js");
@ -79,7 +79,7 @@ const TEST_DATA = [
},
{
type: "load",
filename: TEST_URL_ROOT + TEST_LIB + ":26",
filename: URL_ROOT + TEST_LIB + ":26",
attributes: [
"Bubbling",
"DOM2"
@ -123,7 +123,7 @@ const TEST_DATA = [
},
{
type: "click",
filename: TEST_URL_ROOT + TEST_LIB + ":48",
filename: URL_ROOT + TEST_LIB + ":48",
attributes: [
"Bubbling",
"DOM2"
@ -144,7 +144,7 @@ const TEST_DATA = [
},
{
type: "keydown",
filename: TEST_URL_ROOT + TEST_LIB + ":48",
filename: URL_ROOT + TEST_LIB + ":48",
attributes: [
"Bubbling",
"DOM2"
@ -171,7 +171,7 @@ const TEST_DATA = [
},
{
type: "dblclick",
filename: TEST_URL_ROOT + TEST_LIB + ":17",
filename: URL_ROOT + TEST_LIB + ":17",
attributes: [
"jQuery",
"Live"
@ -230,7 +230,7 @@ const TEST_DATA = [
},
{
type: "dragstart",
filename: TEST_URL_ROOT + TEST_LIB + ":17",
filename: URL_ROOT + TEST_LIB + ":17",
attributes: [
"jQuery",
"Live"

Просмотреть файл

@ -10,7 +10,7 @@ requestLongerTimeout(2);
// and jQuery Live events (jQuery version 1.6).
const TEST_LIB = "lib_jquery_1.6_min.js";
const TEST_URL = TEST_URL_ROOT + "doc_markup_events_jquery.html?" + TEST_LIB;
const TEST_URL = URL_ROOT + "doc_markup_events_jquery.html?" + TEST_LIB;
loadHelperScript("helper_events_test_runner.js");
@ -81,7 +81,7 @@ const TEST_DATA = [
},
{
type: "load",
filename: TEST_URL_ROOT + TEST_LIB + ":16",
filename: URL_ROOT + TEST_LIB + ":16",
attributes: [
"Bubbling",
"DOM2"
@ -122,7 +122,7 @@ const TEST_DATA = [
},
{
type: "click",
filename: TEST_URL_ROOT + TEST_LIB + ":16",
filename: URL_ROOT + TEST_LIB + ":16",
attributes: [
"Bubbling",
"DOM2"
@ -143,7 +143,7 @@ const TEST_DATA = [
},
{
type: "keydown",
filename: TEST_URL_ROOT + TEST_LIB + ":16",
filename: URL_ROOT + TEST_LIB + ":16",
attributes: [
"Bubbling",
"DOM2"
@ -170,7 +170,7 @@ const TEST_DATA = [
},
{
type: "dblclick",
filename: TEST_URL_ROOT + TEST_LIB + ":16",
filename: URL_ROOT + TEST_LIB + ":16",
attributes: [
"jQuery",
"Live"
@ -225,7 +225,7 @@ const TEST_DATA = [
},
{
type: "dragend",
filename: TEST_URL_ROOT + TEST_LIB + ":16",
filename: URL_ROOT + TEST_LIB + ":16",
attributes: [
"jQuery",
"Live"
@ -280,7 +280,7 @@ const TEST_DATA = [
},
{
type: "dragleave",
filename: TEST_URL_ROOT + TEST_LIB + ":16",
filename: URL_ROOT + TEST_LIB + ":16",
attributes: [
"jQuery",
"Live"
@ -335,7 +335,7 @@ const TEST_DATA = [
},
{
type: "dragstart",
filename: TEST_URL_ROOT + TEST_LIB + ":16",
filename: URL_ROOT + TEST_LIB + ":16",
attributes: [
"jQuery",
"Live"

Просмотреть файл

@ -10,7 +10,7 @@ requestLongerTimeout(2);
// and jQuery Live events (jQuery version 1.7).
const TEST_LIB = "lib_jquery_1.7_min.js";
const TEST_URL = TEST_URL_ROOT + "doc_markup_events_jquery.html?" + TEST_LIB;
const TEST_URL = URL_ROOT + "doc_markup_events_jquery.html?" + TEST_LIB;
loadHelperScript("helper_events_test_runner.js");
@ -81,7 +81,7 @@ const TEST_DATA = [
},
{
type: "load",
filename: TEST_URL_ROOT + TEST_LIB + ":2",
filename: URL_ROOT + TEST_LIB + ":2",
attributes: [
"Bubbling",
"DOM2"
@ -122,7 +122,7 @@ const TEST_DATA = [
},
{
type: "click",
filename: TEST_URL_ROOT + TEST_LIB + ":3",
filename: URL_ROOT + TEST_LIB + ":3",
attributes: [
"Bubbling",
"DOM2"
@ -143,7 +143,7 @@ const TEST_DATA = [
},
{
type: "keydown",
filename: TEST_URL_ROOT + TEST_LIB + ":3",
filename: URL_ROOT + TEST_LIB + ":3",
attributes: [
"Bubbling",
"DOM2"

Просмотреть файл

@ -10,7 +10,7 @@ requestLongerTimeout(2);
// and jQuery Live events (jQuery version 2.1.1).
const TEST_LIB = "lib_jquery_2.1.1_min.js";
const TEST_URL = TEST_URL_ROOT + "doc_markup_events_jquery.html?" + TEST_LIB;
const TEST_URL = URL_ROOT + "doc_markup_events_jquery.html?" + TEST_LIB;
loadHelperScript("helper_events_test_runner.js");
@ -106,7 +106,7 @@ const TEST_DATA = [
},
{
type: "click",
filename: TEST_URL_ROOT + TEST_LIB + ":3",
filename: URL_ROOT + TEST_LIB + ":3",
attributes: [
"Bubbling",
"DOM2"
@ -127,7 +127,7 @@ const TEST_DATA = [
},
{
type: "keydown",
filename: TEST_URL_ROOT + TEST_LIB + ":3",
filename: URL_ROOT + TEST_LIB + ":3",
attributes: [
"Bubbling",
"DOM2"

Просмотреть файл

@ -15,7 +15,7 @@ const TEST_DATA = [
newHTML: '<div id="one">First Div</div>',
validate: function*(pageNode, pageNodeFront, selectedNodeFront) {
is(pageNode.textContent, "First Div", "New div has expected text content");
ok(!getNode("#one em"), "No em remaining")
ok(!getNode("#one em", {expectNoMatch: true}), "No em remaining")
}
},
{
@ -71,7 +71,7 @@ const TEST_URL = "data:text/html," +
"</html>";
add_task(function*() {
let {inspector} = yield addTab(TEST_URL).then(openInspector);
let {inspector, testActor} = yield openInspectorForURL(TEST_URL);
inspector.markup._frame.focus();
yield runEditOuterHTMLTests(TEST_DATA, inspector);
yield runEditOuterHTMLTests(TEST_DATA, inspector, testActor);
});

Просмотреть файл

@ -74,7 +74,7 @@ const TEST_DATA = [
is(pageNodeFront, selectedNodeFront, "Original element is selected");
let p = getNode("#badMarkup5");
let nodiv = getNode("#badMarkup5 div");
let nodiv = getNode("#badMarkup5 div", {expectNoMatch: true});
let div = getNode("#badMarkup5 ~ div");
ok(!nodiv, "The invalid markup got created as a sibling");
@ -95,7 +95,7 @@ const TEST_URL = "data:text/html," +
"</html>";
add_task(function*() {
let {inspector} = yield addTab(TEST_URL).then(openInspector);
let {inspector, testActor} = yield openInspectorForURL(TEST_URL);
inspector.markup._frame.focus();
yield runEditOuterHTMLTests(TEST_DATA, inspector);
yield runEditOuterHTMLTests(TEST_DATA, inspector, testActor);
});

Просмотреть файл

@ -21,7 +21,7 @@ const NEW_HTML = '<div id="keyboard">Edited</div>';
requestLongerTimeout(2);
add_task(function*() {
let {inspector} = yield addTab(TEST_URL).then(openInspector);
let {inspector} = yield openInspectorForURL(TEST_URL);
inspector.markup._frame.focus();

Просмотреть файл

@ -11,7 +11,7 @@
const PAGE_CONTENT = [
'<img class="local" src="chrome://branding/content/about-logo.png" />',
'<img class="data" src="data:image/png;base64,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" />',
'<img class="remote" src="' + TEST_URL_ROOT + 'doc_markup_tooltip.png" />',
'<img class="remote" src="' + URL_ROOT + 'doc_markup_tooltip.png" />',
'<canvas class="canvas" width="600" height="600"></canvas>'
].join("\n");

Просмотреть файл

@ -8,15 +8,14 @@
// changes.
const INITIAL_SRC = "data:image/png;base64,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";
const UPDATED_SRC = TEST_URL_ROOT + "doc_markup_tooltip.png";
const UPDATED_SRC = URL_ROOT + "doc_markup_tooltip.png";
const INITIAL_SRC_SIZE = "64" + " \u00D7 " + "64";
const UPDATED_SRC_SIZE = "22" + " \u00D7 " + "23";
add_task(function*() {
yield addTab("data:text/html,<p>markup view tooltip test</p><img>");
let { inspector } = yield openInspector();
let { inspector } = yield openInspectorForURL(
"data:text/html,<p>markup view tooltip test</p><img>");
info("Retrieving NodeFront for the <img> element.");
let img = yield getNodeFront("img", inspector);

Просмотреть файл

@ -11,7 +11,7 @@ requestLongerTimeout(2);
const TEST_URL = "data:text/html;charset=utf8,<div id='test' a b c d e></div>";
add_task(function*() {
let {inspector} = yield addTab(TEST_URL).then(openInspector);
let {inspector} = yield openInspectorForURL(TEST_URL);
info("Focusing the tag editor of the test element");
let {editor} = yield getContainerForSelector("div", inspector);

Просмотреть файл

@ -10,7 +10,7 @@
const TEST_URL = "data:text/html;charset=utf8,<div></div>";
add_task(function*() {
let {inspector, toolbox} = yield addTab(TEST_URL).then(openInspector);
let {inspector, toolbox} = yield openInspectorForURL(TEST_URL);
info("Focusing the tag editor of the test element");
let {editor} = yield getContainerForSelector("div", inspector);

Просмотреть файл

@ -11,7 +11,7 @@
const TEST_URL = "data:text/html;charset=utf8,<div class='test-class'></div>Text node";
add_task(function*() {
let {inspector, toolbox} = yield addTab(TEST_URL).then(openInspector);
let {inspector, toolbox} = yield openInspectorForURL(TEST_URL);
let {walker} = inspector;
info("Select the test node to have the 2 test containers visible");

Просмотреть файл

@ -14,7 +14,7 @@ requestLongerTimeout(2);
const TEST_URL = "data:text/html;charset=utf8,<div>test element</div>";
add_task(function*() {
let {toolbox, inspector} = yield addTab(TEST_URL).then(openInspector);
let {inspector, testActor} = yield openInspectorForURL(TEST_URL);
info("Select the test node with the browser ctx menu");
yield selectWithBrowserMenu(inspector);
@ -26,7 +26,7 @@ add_task(function*() {
assertNodeSelected(inspector, "body");
info("Select the test node with the element picker");
yield selectWithElementPicker(inspector);
yield selectWithElementPicker(inspector, testActor);
assertNodeSelected(inspector, "div");
info("Press arrowUp to focus <body> " +
@ -71,16 +71,13 @@ function* selectWithBrowserMenu(inspector) {
yield inspector.once("inspector-updated");
}
function* selectWithElementPicker(inspector) {
function* selectWithElementPicker(inspector, testActor) {
yield inspector.toolbox.highlighterUtils.startPicker();
yield BrowserTestUtils.synthesizeMouseAtCenter("div", {
type: "mousemove",
}, gBrowser.selectedBrowser);
executeInContent("Test:SynthesizeKey", {
key: "VK_RETURN",
options: {}
}, {}, false);
yield testActor.synthesizeKey({key: "VK_RETURN", options: {}});
yield inspector.once("inspector-updated");
}

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше