mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-13 13:25:37 +00:00
Bug 1010387 - [appmgr v2] write tests and make good use of promises & tasks. r=janx r=jryans
--- browser/devtools/app-manager/app-validator.js | 2 +- browser/devtools/webide/content/newapp.js | 30 +++- browser/devtools/webide/content/webide.js | 180 +++++++++++++++-------- browser/devtools/webide/modules/app-manager.js | 27 +++- browser/devtools/webide/moz.build | 1 + browser/devtools/webide/test/app.zip | Bin 0 -> 480 bytes browser/devtools/webide/test/app/index.html | 6 + browser/devtools/webide/test/app/manifest.webapp | 5 + browser/devtools/webide/test/chrome.ini | 13 ++ browser/devtools/webide/test/head.js | 81 ++++++++++ browser/devtools/webide/test/hosted_app.manifest | 3 + browser/devtools/webide/test/templates.json | 14 ++ browser/devtools/webide/test/test_basic.html | 39 +++++ browser/devtools/webide/test/test_import.html | 65 ++++++++ browser/devtools/webide/test/test_newapp.html | 48 ++++++ browser/devtools/webide/test/test_runtime.html | 118 +++++++++++++++ browser/devtools/webide/themes/details.css | 1 - browser/devtools/webide/themes/newapp.css | 4 - 18 files changed, 558 insertions(+), 79 deletions(-) create mode 100644 browser/devtools/webide/test/app.zip create mode 100644 browser/devtools/webide/test/app/index.html create mode 100644 browser/devtools/webide/test/app/manifest.webapp create mode 100644 browser/devtools/webide/test/chrome.ini create mode 100644 browser/devtools/webide/test/head.js create mode 100644 browser/devtools/webide/test/hosted_app.manifest create mode 100644 browser/devtools/webide/test/templates.json create mode 100644 browser/devtools/webide/test/test_basic.html create mode 100644 browser/devtools/webide/test/test_import.html create mode 100644 browser/devtools/webide/test/test_newapp.html create mode 100644 browser/devtools/webide/test/test_runtime.html
This commit is contained in:
parent
d05119d3c9
commit
19f1f1f91e
@ -100,7 +100,7 @@ AppValidator.prototype._getManifest = function () {
|
||||
try {
|
||||
Services.io.newURI(manifestURL, null, null);
|
||||
} catch(e) {
|
||||
this.error(strings.formatStringFromName("validator.invalidHostedManifestURL", [manifestURL, e.message]));
|
||||
this.error(strings.formatStringFromName("validator.invalidHostedManifestURL", [manifestURL, e.message], 2));
|
||||
return promise.resolve(null);
|
||||
}
|
||||
} else {
|
||||
|
@ -63,6 +63,14 @@ function getJSON() {
|
||||
templatelistNode.appendChild(richlistitemNode);
|
||||
}
|
||||
templatelistNode.selectedIndex = 0;
|
||||
|
||||
/* Chrome mochitest support */
|
||||
let testOptions = window.arguments[0].testOptions;
|
||||
if (testOptions) {
|
||||
templatelistNode.selectedIndex = testOptions.index;
|
||||
document.querySelector("#project-name").value = testOptions.name;
|
||||
doOK();
|
||||
}
|
||||
};
|
||||
xhr.onerror = function() {
|
||||
failAndBail("Can't download app templates");
|
||||
@ -107,14 +115,22 @@ function doOK() {
|
||||
return false;
|
||||
}
|
||||
|
||||
let fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
|
||||
fp.init(window, "Select directory where to create app directory", Ci.nsIFilePicker.modeGetFolder);
|
||||
let res = fp.show();
|
||||
if (res == Ci.nsIFilePicker.returnCancel) {
|
||||
AppManager.console.error("No directory selected");
|
||||
return false;
|
||||
let folder;
|
||||
|
||||
/* Chrome mochitest support */
|
||||
let testOptions = window.arguments[0].testOptions;
|
||||
if (testOptions) {
|
||||
folder = testOptions.folder;
|
||||
} else {
|
||||
let fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
|
||||
fp.init(window, "Select directory where to create app directory", Ci.nsIFilePicker.modeGetFolder);
|
||||
let res = fp.show();
|
||||
if (res == Ci.nsIFilePicker.returnCancel) {
|
||||
AppManager.console.error("No directory selected");
|
||||
return false;
|
||||
}
|
||||
folder = fp.file;
|
||||
}
|
||||
let folder = fp.file;
|
||||
|
||||
// Create subfolder with fs-friendly name of project
|
||||
let subfolder = projectName.replace(/\W/g, '').toLowerCase();
|
||||
|
@ -7,6 +7,8 @@ const Cu = Components.utils;
|
||||
const Ci = Components.interfaces;
|
||||
|
||||
Cu.import("resource:///modules/devtools/gDevTools.jsm");
|
||||
Cu.import("resource://gre/modules/FileUtils.jsm");
|
||||
Cu.import("resource://gre/modules/Task.jsm");
|
||||
|
||||
const {devtools} = Cu.import("resource://gre/modules/devtools/Loader.jsm", {});
|
||||
const {require} = devtools;
|
||||
@ -14,6 +16,7 @@ const {Services} = Cu.import("resource://gre/modules/Services.jsm");
|
||||
const {AppProjects} = require("devtools/app-manager/app-projects");
|
||||
const {Connection} = require("devtools/client/connection-manager");
|
||||
const {AppManager} = require("devtools/app-manager");
|
||||
const {Promise: promise} = Cu.import("resource://gre/modules/Promise.jsm", {});
|
||||
const ProjectEditor = require("projecteditor/projecteditor");
|
||||
|
||||
const Strings = Services.strings.createBundle("chrome://webide/content/webide.properties");
|
||||
@ -166,6 +169,7 @@ let UI = {
|
||||
// Freeze the UI until the promise is resolved. A 30s timeout
|
||||
// will unfreeze the UI, just in case the promise never gets
|
||||
// resolved.
|
||||
this.hidePanels();
|
||||
let timeout = setTimeout(() => {
|
||||
this.unbusy();
|
||||
this.console.error("Operation timeout: " + operationDescription);
|
||||
@ -174,10 +178,12 @@ let UI = {
|
||||
promise.then(() => {
|
||||
clearTimeout(timeout);
|
||||
this.unbusy();
|
||||
}, () => {
|
||||
}, (e) => {
|
||||
clearTimeout(timeout);
|
||||
this.console.error("Error while processing: " + operationDescription + ": " + e);
|
||||
this.unbusy();
|
||||
});
|
||||
return promise;
|
||||
},
|
||||
|
||||
/********** RUNTIME **********/
|
||||
@ -190,7 +196,7 @@ let UI = {
|
||||
}
|
||||
|
||||
this.console.log("Found " + AppManager.runtimeList.usb.length + " USB devices.");
|
||||
this.console.log("Found " + AppManager.runtimeList.simulators.length + " simulators.");
|
||||
this.console.log("Found " + AppManager.runtimeList.simulator.length + " simulators.");
|
||||
for (let runtime of AppManager.runtimeList.usb) {
|
||||
let panelItemNode = document.createElement("toolbarbutton");
|
||||
panelItemNode.className = "panel-item runtime-panel-item-usbruntime";
|
||||
@ -206,7 +212,7 @@ let UI = {
|
||||
while (simulatorListNode.hasChildNodes()) {
|
||||
simulatorListNode.firstChild.remove();
|
||||
}
|
||||
for (let runtime of AppManager.runtimeList.simulators) {
|
||||
for (let runtime of AppManager.runtimeList.simulator) {
|
||||
let panelItemNode = document.createElement("toolbarbutton");
|
||||
panelItemNode.className = "panel-item runtime-panel-item-simulator";
|
||||
panelItemNode.setAttribute("label", runtime.getName());
|
||||
@ -227,6 +233,7 @@ let UI = {
|
||||
promise.then(
|
||||
() => {this.console.success("Connected to " + name)},
|
||||
() => {this.console.error("Can't connect to " + name)});
|
||||
return promise;
|
||||
},
|
||||
|
||||
updateRuntimeButton: function() {
|
||||
@ -515,56 +522,95 @@ let Cmds = {
|
||||
window.close();
|
||||
},
|
||||
|
||||
newApp: function() {
|
||||
UI.hidePanels();
|
||||
let ret = {location:null};
|
||||
window.openDialog("chrome://webide/content/newapp.xul", "newapp", "chrome,modal", ret);
|
||||
if (!ret.location)
|
||||
return;
|
||||
let project = AppProjects.get(ret.location);
|
||||
UI.busyUntil(AppManager.validateProject(project).then(() => {
|
||||
UI.console.success("New project created at " + ret.location);
|
||||
/**
|
||||
* testOptions: { chrome mochitest support
|
||||
* folder: nsIFile, where to store the app
|
||||
* index: Number, index of the app in the template list
|
||||
* name: String name of the app
|
||||
* }
|
||||
*/
|
||||
newApp: function(testOptions) {
|
||||
return UI.busyUntil(Task.spawn(function* () {
|
||||
|
||||
// Open newapp.xul, which will feed ret.location
|
||||
let ret = {location: null, testOptions: testOptions};
|
||||
window.openDialog("chrome://webide/content/newapp.xul", "newapp", "chrome,modal", ret);
|
||||
if (!ret.location)
|
||||
return;
|
||||
|
||||
// Retrieve added project
|
||||
let project = AppProjects.get(ret.location);
|
||||
|
||||
// Validate project
|
||||
yield AppManager.validateProject(project);
|
||||
|
||||
// Select project
|
||||
AppManager.selectedProject = project;
|
||||
}, (e) => UI.console.error("Error while create new app: " + e)), "creating new app");;
|
||||
|
||||
}), "creating new app");
|
||||
},
|
||||
|
||||
importPackagedApp: function() {
|
||||
UI.hidePanels();
|
||||
let fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
|
||||
fp.init(window, Strings.GetStringFromName("importPackagedApp_title"), Ci.nsIFilePicker.modeGetFolder);
|
||||
let res = fp.show();
|
||||
if (res == Ci.nsIFilePicker.returnCancel)
|
||||
return;
|
||||
UI.busyUntil(AppProjects.addPackaged(fp.file)
|
||||
.then(project => AppManager.validateProject(project))
|
||||
.then(project => AppManager.selectedProject = project)
|
||||
.then(( ) => { UI.console.log("New project successfuly added") },
|
||||
(e) => { UI.console.error("Error while importing project: " + e) }),
|
||||
"importing packaged app");
|
||||
importPackagedApp: function(location) {
|
||||
return UI.busyUntil(Task.spawn(function* () {
|
||||
|
||||
let directory;
|
||||
|
||||
if (!location) {
|
||||
let fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
|
||||
fp.init(window, Strings.GetStringFromName("importPackagedApp_title"), Ci.nsIFilePicker.modeGetFolder);
|
||||
let res = fp.show();
|
||||
if (res == Ci.nsIFilePicker.returnCancel) {
|
||||
return promise.resolve();
|
||||
}
|
||||
directory = fp.file;
|
||||
} else {
|
||||
directory = new FileUtils.File(location);
|
||||
}
|
||||
|
||||
// Add project
|
||||
let project = yield AppProjects.addPackaged(directory);
|
||||
|
||||
// Validate project
|
||||
yield AppManager.validateProject(project);
|
||||
|
||||
// Select project
|
||||
AppManager.selectedProject = project;
|
||||
}), "importing packaged app");
|
||||
},
|
||||
|
||||
|
||||
importHostedApp: function() {
|
||||
UI.hidePanels();
|
||||
let promptService = Cc["@mozilla.org/embedcomp/prompt-service;1"].getService(Ci.nsIPromptService);
|
||||
let ret = {value:null};
|
||||
promptService.prompt(window,
|
||||
Strings.GetStringFromName("importHostedApp_title"),
|
||||
Strings.GetStringFromName("importHostedApp_header"),
|
||||
ret, null, {});
|
||||
let url = ret.value;
|
||||
if (!url)
|
||||
return;
|
||||
UI.busyUntil(AppProjects.addHosted(url)
|
||||
.then(project => AppManager.validateProject(project))
|
||||
.then(project => AppManager.selectedProject = project)
|
||||
.then(( ) => { UI.console.log("New project successfuly added") },
|
||||
(e) => { UI.console.error("Error while importing project: " + e) }),
|
||||
"importing hosted app");
|
||||
importHostedApp: function(location) {
|
||||
return UI.busyUntil(Task.spawn(function* () {
|
||||
let ret = {value: null};
|
||||
|
||||
let url;
|
||||
if (!location) {
|
||||
Services.prompt.prompt(window,
|
||||
Strings.GetStringFromName("importHostedApp_title"),
|
||||
Strings.GetStringFromName("importHostedApp_header"),
|
||||
ret, null, {});
|
||||
location = ret.value;
|
||||
}
|
||||
|
||||
if (!location) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Add project
|
||||
let project = yield AppProjects.addHosted(location)
|
||||
|
||||
// Validate project
|
||||
yield AppManager.validateProject(project);
|
||||
|
||||
// Select project
|
||||
AppManager.selectedProject = project;
|
||||
}), "importing hosted app");
|
||||
},
|
||||
|
||||
|
||||
showProjectPanel: function() {
|
||||
let deferred = promise.defer();
|
||||
|
||||
let panelNode = document.querySelector("#project-panel");
|
||||
let panelVboxNode = document.querySelector("#project-panel > vbox");
|
||||
let anchorNode = document.querySelector("#project-panel-button > .panel-button-anchor");
|
||||
@ -603,10 +649,15 @@ let Cmds = {
|
||||
// Open the popup only when the projects are added.
|
||||
// Not doing it in the next tick can cause mis-calculations
|
||||
// of the size of the panel.
|
||||
function onPopupShown() {
|
||||
panelNode.removeEventListener("popupshown", onPopupShown);
|
||||
deferred.resolve();
|
||||
}
|
||||
panelNode.addEventListener("popupshown", onPopupShown);
|
||||
panelNode.openPopup(anchorNode);
|
||||
panelVboxNode.scrollTop = 0;
|
||||
}, 0);
|
||||
}, UI.console.error);
|
||||
}, deferred.reject);
|
||||
|
||||
|
||||
let runtimeappsHeaderNode = document.querySelector("#panel-header-runtimeapps");
|
||||
@ -640,31 +691,40 @@ let Cmds = {
|
||||
};
|
||||
}, true);
|
||||
}
|
||||
|
||||
return deferred.promise;
|
||||
},
|
||||
|
||||
showRuntimePanel: function() {
|
||||
let panel = document.querySelector("#runtime-panel");
|
||||
let anchor = document.querySelector("#runtime-panel-button > .panel-button-anchor");
|
||||
|
||||
let deferred = promise.defer();
|
||||
function onPopupShown() {
|
||||
panel.removeEventListener("popupshown", onPopupShown);
|
||||
deferred.resolve();
|
||||
}
|
||||
panel.addEventListener("popupshown", onPopupShown);
|
||||
|
||||
panel.openPopup(anchor);
|
||||
return deferred.promise;
|
||||
},
|
||||
|
||||
disconnectRuntime: function() {
|
||||
UI.busyUntil(AppManager.disconnectRuntime());
|
||||
return UI.busyUntil(AppManager.disconnectRuntime(), "disconnecting from runtime");
|
||||
},
|
||||
|
||||
takeScreenshot: function() {
|
||||
UI.hidePanels();
|
||||
UI.busyUntil(AppManager.deviceFront.screenshotToDataURL().then(longstr => {
|
||||
return UI.busyUntil(AppManager.deviceFront.screenshotToDataURL().then(longstr => {
|
||||
return longstr.string().then(dataURL => {
|
||||
longstr.release().then(null, UI.console.error);
|
||||
UI.openInBrowser(dataURL);
|
||||
});
|
||||
}));
|
||||
}), "taking screenshot");
|
||||
},
|
||||
|
||||
showPermissionsTable: function() {
|
||||
UI.hidePanels();
|
||||
UI.busyUntil(AppManager.deviceFront.getRawPermissionsTable().then(json => {
|
||||
return UI.busyUntil(AppManager.deviceFront.getRawPermissionsTable().then(json => {
|
||||
let styleContent = "";
|
||||
styleContent += "body {background:white; font-family: monospace}";
|
||||
styleContent += "table {border-collapse: collapse}";
|
||||
@ -713,8 +773,7 @@ let Cmds = {
|
||||
},
|
||||
|
||||
showRuntimeDetails: function() {
|
||||
UI.hidePanels();
|
||||
UI.busyUntil(AppManager.deviceFront.getDescription().then(json => {
|
||||
return UI.busyUntil(AppManager.deviceFront.getDescription().then(json => {
|
||||
let styleContent = "";
|
||||
styleContent += "body {background:white; font-family: monospace}";
|
||||
styleContent += "table {border-collapse: collapse}";
|
||||
@ -746,31 +805,34 @@ let Cmds = {
|
||||
switch(AppManager.selectedProject.type) {
|
||||
case "packaged":
|
||||
case "hosted":
|
||||
UI.busyUntil(AppManager.installAndRunProject(), "installing and running app");
|
||||
return UI.busyUntil(AppManager.installAndRunProject(), "installing and running app");
|
||||
break;
|
||||
case "runtimeApp":
|
||||
UI.busyUntil(AppManager.runRuntimeApp(), "running app");
|
||||
return UI.busyUntil(AppManager.runRuntimeApp(), "running app");
|
||||
break;
|
||||
}
|
||||
return promise.reject();
|
||||
},
|
||||
|
||||
stop: function() {
|
||||
UI.busyUntil(AppManager.stopRunningApp(), "stopping app");
|
||||
return UI.busyUntil(AppManager.stopRunningApp(), "stopping app");
|
||||
},
|
||||
|
||||
toggleToolbox: function() {
|
||||
if (UI.toolboxIframe) {
|
||||
UI.closeToolbox();
|
||||
return promise.resolve();
|
||||
} else {
|
||||
UI.toolboxPromise = AppManager.getTarget().then((target) => {
|
||||
return UI.showToolbox(target);
|
||||
}, UI.console.error);
|
||||
UI.busyUntil(UI.toolboxPromise, "opening toolbox");
|
||||
return UI.toolboxPromise;
|
||||
}
|
||||
},
|
||||
|
||||
removeProject: function() {
|
||||
AppManager.removeSelectedProject();
|
||||
return AppManager.removeSelectedProject();
|
||||
},
|
||||
|
||||
toggleEditors: function() {
|
||||
|
@ -34,7 +34,7 @@ exports.AppManager = AppManager = {
|
||||
this.connection.on(Connection.Events.STATUS_CHANGED, this.onConnectionChanged);
|
||||
this.webAppsStore = new WebappsStore(this.connection);
|
||||
|
||||
this.runtimeList = {usb:[], simulators:[]};
|
||||
this.runtimeList = {usb: [], simulator: []};
|
||||
this.trackUSBRuntimes();
|
||||
this.trackSimulatorRuntimes();
|
||||
},
|
||||
@ -49,6 +49,7 @@ exports.AppManager = AppManager = {
|
||||
this.runtimeList = null;
|
||||
this.connection.off(Connection.Events.STATUS_CHANGED, this.onConnectionChanged);
|
||||
this.webAppsStore.destroy();
|
||||
this.webAppsStore = null;
|
||||
this._listTabsResponse = null;
|
||||
this.connection.disconnect();
|
||||
this.connection = null;
|
||||
@ -91,6 +92,9 @@ exports.AppManager = AppManager = {
|
||||
_runningApps: new Set(),
|
||||
_getRunningApps: function() {
|
||||
let client = this.connection.client;
|
||||
if (!this._listTabsResponse.webappsActor) {
|
||||
return;
|
||||
}
|
||||
let request = {
|
||||
to: this._listTabsResponse.webappsActor,
|
||||
type: "listRunningApps"
|
||||
@ -214,7 +218,7 @@ exports.AppManager = AppManager = {
|
||||
removeSelectedProject: function() {
|
||||
let location = this.selectedProject.location;
|
||||
AppManager.selectedProject = null;
|
||||
AppProjects.remove(location);
|
||||
return AppProjects.remove(location);
|
||||
},
|
||||
|
||||
_selectedRuntime: null,
|
||||
@ -288,13 +292,16 @@ exports.AppManager = AppManager = {
|
||||
installAndRunProject: function() {
|
||||
let project = this.selectedProject;
|
||||
|
||||
if (!project ||
|
||||
!this._listTabsResponse ||
|
||||
(project.type != "packaged" && project.type != "hosted")) {
|
||||
if (!project || (project.type != "packaged" && project.type != "hosted")) {
|
||||
AppManager.console.error("Can't install project. Unknown type of project.");
|
||||
return promise.reject("Can't install");
|
||||
}
|
||||
|
||||
if (!this._listTabsResponse) {
|
||||
AppManager.console.error("Can't install project. Not fully connected.");
|
||||
return promise.reject("Can't install");
|
||||
}
|
||||
|
||||
return this.validateProject(project).then(() => {
|
||||
|
||||
if (project.errorsCount > 0) {
|
||||
@ -471,9 +478,9 @@ exports.AppManager = AppManager = {
|
||||
Simulator.off("unregister", this._updateSimulatorRuntimes);
|
||||
},
|
||||
_updateSimulatorRuntimes: function() {
|
||||
this.runtimeList.simulators = [];
|
||||
this.runtimeList.simulator = [];
|
||||
for (let version of Simulator.availableVersions()) {
|
||||
this.runtimeList.simulators.push(new SimulatorRuntime(version));
|
||||
this.runtimeList.simulator.push(new SimulatorRuntime(version));
|
||||
}
|
||||
this.update("runtimelist");
|
||||
},
|
||||
@ -517,6 +524,9 @@ USBRuntime.prototype = {
|
||||
connection.connect();
|
||||
});
|
||||
},
|
||||
getID: function() {
|
||||
return this.id;
|
||||
},
|
||||
getName: function() {
|
||||
return this.id;
|
||||
},
|
||||
@ -540,6 +550,9 @@ SimulatorRuntime.prototype = {
|
||||
connection.connect();
|
||||
});
|
||||
},
|
||||
getID: function() {
|
||||
return this.version;
|
||||
},
|
||||
getName: function() {
|
||||
return this.version;
|
||||
},
|
||||
|
@ -9,3 +9,4 @@ PARALLEL_DIRS += [
|
||||
'themes',
|
||||
]
|
||||
|
||||
MOCHITEST_CHROME_MANIFESTS += ['test/chrome.ini']
|
||||
|
BIN
browser/devtools/webide/test/app.zip
Normal file
BIN
browser/devtools/webide/test/app.zip
Normal file
Binary file not shown.
6
browser/devtools/webide/test/app/index.html
Normal file
6
browser/devtools/webide/test/app/index.html
Normal file
@ -0,0 +1,6 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head><title></title></head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
5
browser/devtools/webide/test/app/manifest.webapp
Normal file
5
browser/devtools/webide/test/app/manifest.webapp
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"name": "A name (in app directory)",
|
||||
"description": "desc",
|
||||
"launch_path": "/index.html"
|
||||
}
|
13
browser/devtools/webide/test/chrome.ini
Normal file
13
browser/devtools/webide/test/chrome.ini
Normal file
@ -0,0 +1,13 @@
|
||||
[DEFAULT]
|
||||
support-files =
|
||||
app/index.html
|
||||
app/manifest.webapp
|
||||
app.zip
|
||||
head.js
|
||||
hosted_app.manifest
|
||||
templates.json
|
||||
|
||||
[test_basic.html]
|
||||
[test_newapp.html]
|
||||
[test_import.html]
|
||||
[test_runtime.html]
|
81
browser/devtools/webide/test/head.js
Normal file
81
browser/devtools/webide/test/head.js
Normal file
@ -0,0 +1,81 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
const {utils: Cu, classes: Cc, interfaces: Ci} = Components;
|
||||
|
||||
Cu.import('resource://gre/modules/Services.jsm');
|
||||
Cu.import("resource://gre/modules/FileUtils.jsm");
|
||||
Cu.import("resource://gre/modules/Task.jsm");
|
||||
|
||||
const {Promise: promise} = Cu.import("resource://gre/modules/devtools/deprecated-sync-thenables.js", {});
|
||||
const {devtools} = Cu.import("resource://gre/modules/devtools/Loader.jsm", {});
|
||||
const {require} = devtools;
|
||||
const {AppProjects} = require("devtools/app-manager/app-projects");
|
||||
|
||||
const TEST_BASE = "chrome://mochitests/content/chrome/browser/devtools/webide/test/";
|
||||
|
||||
Services.prefs.setBoolPref("devtools.webide.enabled", true);
|
||||
|
||||
SimpleTest.registerCleanupFunction(() => {
|
||||
Services.prefs.clearUserPref("devtools.webide.enabled");
|
||||
});
|
||||
|
||||
function openWebIDE() {
|
||||
info("opening WebIDE");
|
||||
|
||||
let deferred = promise.defer();
|
||||
|
||||
let ww = Cc["@mozilla.org/embedcomp/window-watcher;1"].getService(Ci.nsIWindowWatcher);
|
||||
let win = ww.openWindow(null, "chrome://webide/content/", "webide", "chrome,centerscreen,resizable", null);
|
||||
|
||||
win.addEventListener("load", function onLoad() {
|
||||
win.removeEventListener("load", onLoad);
|
||||
info("WebIDE open");
|
||||
SimpleTest.executeSoon(() => {
|
||||
deferred.resolve(win);
|
||||
});
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function closeWebIDE(win) {
|
||||
info("Closing WebIDE");
|
||||
|
||||
let deferred = promise.defer();
|
||||
|
||||
win.addEventListener("unload", function onUnload() {
|
||||
win.removeEventListener("unload", onUnload);
|
||||
info("WebIDE closed");
|
||||
SimpleTest.executeSoon(() => {
|
||||
deferred.resolve();
|
||||
});
|
||||
});
|
||||
|
||||
win.close();
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function removeAllProjects() {
|
||||
let deferred = promise.defer();
|
||||
AppProjects.load().then(() => {
|
||||
let projects = AppProjects.store.object.projects;
|
||||
for (let i = 0; i < projects.length; i++) {
|
||||
AppProjects.remove(projects[i].location);
|
||||
}
|
||||
deferred.resolve();
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
function nextTick() {
|
||||
let deferred = promise.defer();
|
||||
SimpleTest.executeSoon(() => {
|
||||
deferred.resolve();
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
}
|
3
browser/devtools/webide/test/hosted_app.manifest
Normal file
3
browser/devtools/webide/test/hosted_app.manifest
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"name": "hosted manifest name property"
|
||||
}
|
14
browser/devtools/webide/test/templates.json
Normal file
14
browser/devtools/webide/test/templates.json
Normal file
@ -0,0 +1,14 @@
|
||||
[
|
||||
{
|
||||
"file": "chrome://mochitests/content/chrome/browser/devtools/webide/test/app.zip?1",
|
||||
"icon": "ximgx1",
|
||||
"name": "app name 1",
|
||||
"description": "app description 1"
|
||||
},
|
||||
{
|
||||
"file": "chrome://mochitests/content/chrome/browser/devtools/webide/test/app.zip?2",
|
||||
"icon": "ximgx2",
|
||||
"name": "app name 2",
|
||||
"description": "app description 2"
|
||||
}
|
||||
]
|
39
browser/devtools/webide/test/test_basic.html
Normal file
39
browser/devtools/webide/test/test_basic.html
Normal file
@ -0,0 +1,39 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf8">
|
||||
<title></title>
|
||||
|
||||
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript" src="chrome://mochikit/content/chrome-harness.js"></script>
|
||||
<script type="application/javascript;version=1.8" src="head.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<script type="application/javascript;version=1.8">
|
||||
window.onload = function() {
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
openWebIDE().then((win) => {
|
||||
ok(win, "Found a window");
|
||||
ok(win.AppManager, "App Manager accessible");
|
||||
let appmgr = win.AppManager;
|
||||
ok(appmgr.connection, "App Manager connection ready");
|
||||
ok(appmgr.runtimeList, "Runtime list ready");
|
||||
ok(appmgr.webAppsStore, "WebApps store ready");
|
||||
closeWebIDE(win).then(() => {
|
||||
ok(!appmgr.connection, "App Manager connection destroyed");
|
||||
ok(!appmgr.runtimeList, "Runtime list destroyed");
|
||||
ok(!appmgr.webAppsStore, "WebApps store destroyed");
|
||||
SimpleTest.finish();
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
65
browser/devtools/webide/test/test_import.html
Normal file
65
browser/devtools/webide/test/test_import.html
Normal file
@ -0,0 +1,65 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf8">
|
||||
<title></title>
|
||||
|
||||
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript" src="chrome://mochikit/content/chrome-harness.js"></script>
|
||||
<script type="application/javascript;version=1.8" src="head.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<script type="application/javascript;version=1.8">
|
||||
window.onload = function() {
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
Task.spawn(function* () {
|
||||
let win = yield openWebIDE();
|
||||
let packagedAppLocation = getTestFilePath("app");
|
||||
|
||||
yield win.Cmds.importPackagedApp(packagedAppLocation);
|
||||
|
||||
let project = win.AppManager.selectedProject;
|
||||
is(project.location, packagedAppLocation, "Location is valid");
|
||||
is(project.name, "A name (in app directory)", "name field has been updated");
|
||||
is(project.manifest.launch_path, "/index.html", "manifest found. launch_path valid.");
|
||||
is(project.manifest.description, "desc", "manifest found. description valid");
|
||||
|
||||
yield nextTick();
|
||||
|
||||
let hostedAppManifest = TEST_BASE + "hosted_app.manifest";
|
||||
yield win.Cmds.importHostedApp(hostedAppManifest);
|
||||
|
||||
project = win.AppManager.selectedProject;
|
||||
is(project.location, hostedAppManifest, "Location is valid");
|
||||
is(project.name, "hosted manifest name property", "name field has been updated");
|
||||
|
||||
info("opening panel");
|
||||
yield win.Cmds.showProjectPanel();
|
||||
info("panel open");
|
||||
|
||||
let panelNode = win.document.querySelector("#project-panel");
|
||||
let items = panelNode.querySelectorAll(".panel-item");
|
||||
// 3 controls, + 2 projects
|
||||
is(items.length, 5, "5 projects in panel");
|
||||
is(items[3].getAttribute("label"), "A name (in app directory)", "Panel label is correct");
|
||||
is(items[4].getAttribute("label"), "hosted manifest name property", "Panel label is correct");
|
||||
|
||||
yield closeWebIDE(win);
|
||||
|
||||
yield removeAllProjects();
|
||||
|
||||
SimpleTest.finish();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
48
browser/devtools/webide/test/test_newapp.html
Normal file
48
browser/devtools/webide/test/test_newapp.html
Normal file
@ -0,0 +1,48 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf8">
|
||||
<title></title>
|
||||
|
||||
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript" src="chrome://mochikit/content/chrome-harness.js"></script>
|
||||
<script type="application/javascript;version=1.8" src="head.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<script type="application/javascript;version=1.8">
|
||||
window.onload = function() {
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
Services.prefs.setCharPref("devtools.webide.templatesURL", TEST_BASE + "templates.json");
|
||||
|
||||
Task.spawn(function* () {
|
||||
let win = yield openWebIDE();
|
||||
let tmpDir = FileUtils.getDir("TmpD", []);
|
||||
yield win.Cmds.newApp({
|
||||
index: 0,
|
||||
name: "webideTmpApp",
|
||||
folder: tmpDir
|
||||
});
|
||||
|
||||
let project = win.AppManager.selectedProject;
|
||||
let tmpDir = FileUtils.getDir("TmpD", ["webidetmpapp"]);
|
||||
ok(tmpDir.isDirectory(), "Directory created");
|
||||
is(project.location, tmpDir.path, "Location is valid (and lowercase)");
|
||||
is(project.name, "webideTmpApp", "name field has been updated");
|
||||
|
||||
// Clean up
|
||||
tmpDir.remove(true);
|
||||
Services.prefs.clearUserPref("devtools.webide.templatesURL");
|
||||
yield closeWebIDE(win);
|
||||
yield removeAllProjects();
|
||||
SimpleTest.finish();
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
118
browser/devtools/webide/test/test_runtime.html
Normal file
118
browser/devtools/webide/test/test_runtime.html
Normal file
@ -0,0 +1,118 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf8">
|
||||
<title></title>
|
||||
|
||||
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript" src="chrome://mochikit/content/chrome-harness.js"></script>
|
||||
<script type="application/javascript;version=1.8" src="head.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<script type="application/javascript;version=1.8">
|
||||
window.onload = function() {
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
Task.spawn(function* () {
|
||||
|
||||
function isPlayActive() {
|
||||
return !win.document.querySelector("#cmd_play").hasAttribute("disabled");
|
||||
}
|
||||
|
||||
function isStopActive() {
|
||||
return !win.document.querySelector("#cmd_stop").hasAttribute("disabled");
|
||||
}
|
||||
|
||||
Cu.import("resource://gre/modules/devtools/dbg-server.jsm");
|
||||
DebuggerServer.init(function () { return true; });
|
||||
DebuggerServer.addBrowserActors();
|
||||
|
||||
let win = yield openWebIDE();
|
||||
|
||||
win.AppManager.runtimeList.usb.push({
|
||||
connect: function(connection) {
|
||||
ok(connection, win.AppManager.connection, "connection is valid");
|
||||
connection.host = null; // force connectPipe
|
||||
connection.connect();
|
||||
return promise.resolve();
|
||||
},
|
||||
|
||||
getName: function() {
|
||||
return "fakeRuntime";
|
||||
}
|
||||
});
|
||||
|
||||
win.AppManager.update("runtimelist");
|
||||
|
||||
let hostedAppManifest = TEST_BASE + "hosted_app.manifest";
|
||||
yield win.Cmds.importHostedApp(hostedAppManifest);
|
||||
|
||||
yield win.Cmds.showRuntimePanel();
|
||||
|
||||
let panelNode = win.document.querySelector("#runtime-panel");
|
||||
let items = panelNode.querySelectorAll(".runtime-panel-item-usbruntime");
|
||||
is(items.length, 1, "Found one runtime button");
|
||||
|
||||
let deferred = promise.defer();
|
||||
win.AppManager.connection.once(
|
||||
win.Connection.Events.CONNECTED,
|
||||
() => deferred.resolve());
|
||||
|
||||
items[0].click();
|
||||
|
||||
yield deferred.promise;
|
||||
|
||||
yield nextTick();
|
||||
|
||||
ok(!isPlayActive(), "play button is disabled 2");
|
||||
ok(!isStopActive(), "stop button is disabled 2");
|
||||
|
||||
win.AppManager.selectedProject.errorsCount = 0;
|
||||
win.UI.updateCommands();
|
||||
|
||||
yield nextTick();
|
||||
|
||||
ok(isPlayActive(), "play button is enabled 3");
|
||||
ok(!isStopActive(), "stop button is disabled 3");
|
||||
let oldProject = win.AppManager.selectedProject;
|
||||
win.AppManager.selectedProject = null;
|
||||
|
||||
yield nextTick();
|
||||
|
||||
ok(!isPlayActive(), "play button is disabled 4");
|
||||
ok(!isStopActive(), "stop button is disabled 4");
|
||||
win.AppManager._selectedProject = oldProject;
|
||||
win.UI.updateCommands();
|
||||
|
||||
yield nextTick();
|
||||
|
||||
ok(isPlayActive(), "play button is enabled 5");
|
||||
ok(!isStopActive(), "stop button is disabled 5");
|
||||
|
||||
|
||||
yield win.Cmds.disconnectRuntime();
|
||||
|
||||
|
||||
ok(win.AppManager.selectedProject, "A project is still selected");
|
||||
ok(!isPlayActive(), "play button is disabled 6");
|
||||
ok(!isStopActive(), "stop button is disabled 6");
|
||||
|
||||
|
||||
yield closeWebIDE(win);
|
||||
|
||||
DebuggerServer.destroy();
|
||||
|
||||
SimpleTest.finish();
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -61,7 +61,6 @@ header > div {
|
||||
#icon {
|
||||
height: 48px;
|
||||
width: 48px;
|
||||
text-align:top;
|
||||
float: left;
|
||||
margin: 0 20px;
|
||||
}
|
||||
|
@ -43,10 +43,6 @@ richlistitem {
|
||||
-moz-box-align: start;
|
||||
}
|
||||
|
||||
richlistitem:nth-child(odd) {
|
||||
background-color:
|
||||
}
|
||||
|
||||
richlistitem > image {
|
||||
height: 24px;
|
||||
width: 24px;
|
||||
|
Loading…
Reference in New Issue
Block a user