diff options
Diffstat (limited to 'toolkit/devtools/webide/test')
57 files changed, 2291 insertions, 0 deletions
diff --git a/toolkit/devtools/webide/test/addons/adbhelper-linux.xpi b/toolkit/devtools/webide/test/addons/adbhelper-linux.xpi Binary files differnew file mode 100644 index 000000000..b56cc03e3 --- /dev/null +++ b/toolkit/devtools/webide/test/addons/adbhelper-linux.xpi diff --git a/toolkit/devtools/webide/test/addons/adbhelper-linux64.xpi b/toolkit/devtools/webide/test/addons/adbhelper-linux64.xpi Binary files differnew file mode 100644 index 000000000..b56cc03e3 --- /dev/null +++ b/toolkit/devtools/webide/test/addons/adbhelper-linux64.xpi diff --git a/toolkit/devtools/webide/test/addons/adbhelper-mac64.xpi b/toolkit/devtools/webide/test/addons/adbhelper-mac64.xpi Binary files differnew file mode 100644 index 000000000..b56cc03e3 --- /dev/null +++ b/toolkit/devtools/webide/test/addons/adbhelper-mac64.xpi diff --git a/toolkit/devtools/webide/test/addons/adbhelper-win32.xpi b/toolkit/devtools/webide/test/addons/adbhelper-win32.xpi Binary files differnew file mode 100644 index 000000000..b56cc03e3 --- /dev/null +++ b/toolkit/devtools/webide/test/addons/adbhelper-win32.xpi diff --git a/toolkit/devtools/webide/test/addons/fxdt-adapters-linux32.xpi b/toolkit/devtools/webide/test/addons/fxdt-adapters-linux32.xpi Binary files differnew file mode 100644 index 000000000..5a512ae3d --- /dev/null +++ b/toolkit/devtools/webide/test/addons/fxdt-adapters-linux32.xpi diff --git a/toolkit/devtools/webide/test/addons/fxdt-adapters-linux64.xpi b/toolkit/devtools/webide/test/addons/fxdt-adapters-linux64.xpi Binary files differnew file mode 100644 index 000000000..5a512ae3d --- /dev/null +++ b/toolkit/devtools/webide/test/addons/fxdt-adapters-linux64.xpi diff --git a/toolkit/devtools/webide/test/addons/fxdt-adapters-mac64.xpi b/toolkit/devtools/webide/test/addons/fxdt-adapters-mac64.xpi Binary files differnew file mode 100644 index 000000000..5a512ae3d --- /dev/null +++ b/toolkit/devtools/webide/test/addons/fxdt-adapters-mac64.xpi diff --git a/toolkit/devtools/webide/test/addons/fxdt-adapters-win32.xpi b/toolkit/devtools/webide/test/addons/fxdt-adapters-win32.xpi Binary files differnew file mode 100644 index 000000000..5a512ae3d --- /dev/null +++ b/toolkit/devtools/webide/test/addons/fxdt-adapters-win32.xpi diff --git a/toolkit/devtools/webide/test/addons/fxos_1_0_simulator-linux.xpi b/toolkit/devtools/webide/test/addons/fxos_1_0_simulator-linux.xpi Binary files differnew file mode 100644 index 000000000..81e1abc6e --- /dev/null +++ b/toolkit/devtools/webide/test/addons/fxos_1_0_simulator-linux.xpi diff --git a/toolkit/devtools/webide/test/addons/fxos_1_0_simulator-linux64.xpi b/toolkit/devtools/webide/test/addons/fxos_1_0_simulator-linux64.xpi Binary files differnew file mode 100644 index 000000000..81e1abc6e --- /dev/null +++ b/toolkit/devtools/webide/test/addons/fxos_1_0_simulator-linux64.xpi diff --git a/toolkit/devtools/webide/test/addons/fxos_1_0_simulator-mac64.xpi b/toolkit/devtools/webide/test/addons/fxos_1_0_simulator-mac64.xpi Binary files differnew file mode 100644 index 000000000..81e1abc6e --- /dev/null +++ b/toolkit/devtools/webide/test/addons/fxos_1_0_simulator-mac64.xpi diff --git a/toolkit/devtools/webide/test/addons/fxos_1_0_simulator-win32.xpi b/toolkit/devtools/webide/test/addons/fxos_1_0_simulator-win32.xpi Binary files differnew file mode 100644 index 000000000..81e1abc6e --- /dev/null +++ b/toolkit/devtools/webide/test/addons/fxos_1_0_simulator-win32.xpi diff --git a/toolkit/devtools/webide/test/addons/fxos_2_0_simulator-linux.xpi b/toolkit/devtools/webide/test/addons/fxos_2_0_simulator-linux.xpi Binary files differnew file mode 100644 index 000000000..1ce3f959e --- /dev/null +++ b/toolkit/devtools/webide/test/addons/fxos_2_0_simulator-linux.xpi diff --git a/toolkit/devtools/webide/test/addons/fxos_2_0_simulator-linux64.xpi b/toolkit/devtools/webide/test/addons/fxos_2_0_simulator-linux64.xpi Binary files differnew file mode 100644 index 000000000..1ce3f959e --- /dev/null +++ b/toolkit/devtools/webide/test/addons/fxos_2_0_simulator-linux64.xpi diff --git a/toolkit/devtools/webide/test/addons/fxos_2_0_simulator-mac64.xpi b/toolkit/devtools/webide/test/addons/fxos_2_0_simulator-mac64.xpi Binary files differnew file mode 100644 index 000000000..1ce3f959e --- /dev/null +++ b/toolkit/devtools/webide/test/addons/fxos_2_0_simulator-mac64.xpi diff --git a/toolkit/devtools/webide/test/addons/fxos_2_0_simulator-win32.xpi b/toolkit/devtools/webide/test/addons/fxos_2_0_simulator-win32.xpi Binary files differnew file mode 100644 index 000000000..1ce3f959e --- /dev/null +++ b/toolkit/devtools/webide/test/addons/fxos_2_0_simulator-win32.xpi diff --git a/toolkit/devtools/webide/test/addons/fxos_3_0_simulator-linux.xpi b/toolkit/devtools/webide/test/addons/fxos_3_0_simulator-linux.xpi Binary files differnew file mode 100644 index 000000000..ec9645da4 --- /dev/null +++ b/toolkit/devtools/webide/test/addons/fxos_3_0_simulator-linux.xpi diff --git a/toolkit/devtools/webide/test/addons/fxos_3_0_simulator-linux64.xpi b/toolkit/devtools/webide/test/addons/fxos_3_0_simulator-linux64.xpi Binary files differnew file mode 100644 index 000000000..ec9645da4 --- /dev/null +++ b/toolkit/devtools/webide/test/addons/fxos_3_0_simulator-linux64.xpi diff --git a/toolkit/devtools/webide/test/addons/fxos_3_0_simulator-mac64.xpi b/toolkit/devtools/webide/test/addons/fxos_3_0_simulator-mac64.xpi Binary files differnew file mode 100644 index 000000000..ec9645da4 --- /dev/null +++ b/toolkit/devtools/webide/test/addons/fxos_3_0_simulator-mac64.xpi diff --git a/toolkit/devtools/webide/test/addons/fxos_3_0_simulator-win32.xpi b/toolkit/devtools/webide/test/addons/fxos_3_0_simulator-win32.xpi Binary files differnew file mode 100644 index 000000000..ec9645da4 --- /dev/null +++ b/toolkit/devtools/webide/test/addons/fxos_3_0_simulator-win32.xpi diff --git a/toolkit/devtools/webide/test/addons/simulators.json b/toolkit/devtools/webide/test/addons/simulators.json new file mode 100644 index 000000000..dace8c8a9 --- /dev/null +++ b/toolkit/devtools/webide/test/addons/simulators.json @@ -0,0 +1,4 @@ +{ + "stable": ["1.0", "2.0"], + "unstable": ["3.0"] +} diff --git a/toolkit/devtools/webide/test/app.zip b/toolkit/devtools/webide/test/app.zip Binary files differnew file mode 100644 index 000000000..8a706a3c9 --- /dev/null +++ b/toolkit/devtools/webide/test/app.zip diff --git a/toolkit/devtools/webide/test/app/index.html b/toolkit/devtools/webide/test/app/index.html new file mode 100644 index 000000000..3ef4a25e2 --- /dev/null +++ b/toolkit/devtools/webide/test/app/index.html @@ -0,0 +1,6 @@ +<!doctype html> +<html> +<head><title></title></head> +<body> +</body> +</html> diff --git a/toolkit/devtools/webide/test/app/manifest.webapp b/toolkit/devtools/webide/test/app/manifest.webapp new file mode 100644 index 000000000..4a198b1ca --- /dev/null +++ b/toolkit/devtools/webide/test/app/manifest.webapp @@ -0,0 +1,5 @@ +{ + "name": "A name (in app directory)", + "description": "desc", + "launch_path": "/index.html" +} diff --git a/toolkit/devtools/webide/test/browser.ini b/toolkit/devtools/webide/test/browser.ini new file mode 100644 index 000000000..2fadb3340 --- /dev/null +++ b/toolkit/devtools/webide/test/browser.ini @@ -0,0 +1,11 @@ +[DEFAULT] +subsuite = devtools +support-files = + addons/simulators.json + doc_tabs.html + head.js + templates.json + +[browser_tabs.js] +skip-if = e10s || (os == 'mac' && debug) # Bug 1072167 - browser_tabs.js test fails under e10s +[browser_widget.js] diff --git a/toolkit/devtools/webide/test/browser_tabs.js b/toolkit/devtools/webide/test/browser_tabs.js new file mode 100644 index 000000000..81ff64c2c --- /dev/null +++ b/toolkit/devtools/webide/test/browser_tabs.js @@ -0,0 +1,59 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ +"use strict"; + +const TEST_URI = "http://example.com/browser/browser/devtools/webide/test/doc_tabs.html"; + +function test() { + waitForExplicitFinish(); + SimpleTest.requestCompleteLog(); + + Task.spawn(function() { + const { DebuggerServer } = + Cu.import("resource://gre/modules/devtools/dbg-server.jsm", {}); + + // Since we test the connections set below, destroy the server in case it + // was left open. + DebuggerServer.destroy(); + DebuggerServer.init(); + DebuggerServer.addBrowserActors(); + + let tab = yield addTab(TEST_URI); + + let win = yield openWebIDE(); + + yield connectToLocal(win); + + is(Object.keys(DebuggerServer._connections).length, 1, "Locally connected"); + + yield selectTabProject(win); + + let project = win.AppManager.selectedProject; + is(project.location, TEST_URI, "Location is correct"); + is(project.name, "example.com: Test Tab", "Name is correct"); + + yield closeWebIDE(win); + DebuggerServer.destroy(); + yield removeTab(tab); + }).then(finish, handleError); +} + +function connectToLocal(win) { + let deferred = promise.defer(); + win.AppManager.connection.once( + win.Connection.Events.CONNECTED, + () => deferred.resolve()); + win.document.querySelectorAll(".runtime-panel-item-other")[1].click(); + return deferred.promise; +} + +function selectTabProject(win) { + return Task.spawn(function() { + yield win.AppManager.listTabs(); + win.Cmds.showProjectPanel(); + yield nextTick(); + let tabsNode = win.document.querySelector("#project-panel-tabs"); + let tabNode = tabsNode.querySelectorAll(".panel-item")[1]; + tabNode.click(); + }); +} diff --git a/toolkit/devtools/webide/test/browser_widget.js b/toolkit/devtools/webide/test/browser_widget.js new file mode 100644 index 000000000..574ec413b --- /dev/null +++ b/toolkit/devtools/webide/test/browser_widget.js @@ -0,0 +1,15 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ +"use strict"; + +function test() { + waitForExplicitFinish(); + Task.spawn(function() { + let win = yield openWebIDE(); + ok(document.querySelector("#webide-button"), "Found WebIDE button"); + Services.prefs.setBoolPref("devtools.webide.widget.enabled", false); + ok(!document.querySelector("#webide-button"), "WebIDE button uninstalled"); + yield closeWebIDE(win); + Services.prefs.clearUserPref("devtools.webide.widget.enabled"); + }).then(finish, handleError); +} diff --git a/toolkit/devtools/webide/test/build_app1/package.json b/toolkit/devtools/webide/test/build_app1/package.json new file mode 100644 index 000000000..c6ae833e1 --- /dev/null +++ b/toolkit/devtools/webide/test/build_app1/package.json @@ -0,0 +1,5 @@ +{ + "webide": { + "prepackage": "echo \"{\\\"name\\\":\\\"hello\\\"}\" > manifest.webapp" + } +} diff --git a/toolkit/devtools/webide/test/build_app2/manifest.webapp b/toolkit/devtools/webide/test/build_app2/manifest.webapp new file mode 100644 index 000000000..0967ef424 --- /dev/null +++ b/toolkit/devtools/webide/test/build_app2/manifest.webapp @@ -0,0 +1 @@ +{} diff --git a/toolkit/devtools/webide/test/build_app2/package.json b/toolkit/devtools/webide/test/build_app2/package.json new file mode 100644 index 000000000..5b7101620 --- /dev/null +++ b/toolkit/devtools/webide/test/build_app2/package.json @@ -0,0 +1,10 @@ +{ + "webide": { + "prepackage": { + "command": "echo \"{\\\"name\\\":\\\"$NAME\\\"}\" > manifest.webapp", + "cwd": "./stage", + "env": ["NAME=world"] + }, + "packageDir": "./stage" + } +} diff --git a/toolkit/devtools/webide/test/build_app2/stage/empty-directory b/toolkit/devtools/webide/test/build_app2/stage/empty-directory new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/toolkit/devtools/webide/test/build_app2/stage/empty-directory diff --git a/toolkit/devtools/webide/test/build_app_windows1/package.json b/toolkit/devtools/webide/test/build_app_windows1/package.json new file mode 100644 index 000000000..036d2d767 --- /dev/null +++ b/toolkit/devtools/webide/test/build_app_windows1/package.json @@ -0,0 +1,5 @@ +{ + "webide": { + "prepackage": "echo {\"name\":\"hello\"} > manifest.webapp" + } +} diff --git a/toolkit/devtools/webide/test/build_app_windows2/manifest.webapp b/toolkit/devtools/webide/test/build_app_windows2/manifest.webapp new file mode 100644 index 000000000..0967ef424 --- /dev/null +++ b/toolkit/devtools/webide/test/build_app_windows2/manifest.webapp @@ -0,0 +1 @@ +{} diff --git a/toolkit/devtools/webide/test/build_app_windows2/package.json b/toolkit/devtools/webide/test/build_app_windows2/package.json new file mode 100644 index 000000000..83caf82ab --- /dev/null +++ b/toolkit/devtools/webide/test/build_app_windows2/package.json @@ -0,0 +1,10 @@ +{ + "webide": { + "prepackage": { + "command": "echo {\"name\":\"%NAME%\"} > manifest.webapp", + "cwd": "./stage", + "env": ["NAME=world"] + }, + "packageDir": "./stage" + } +} diff --git a/toolkit/devtools/webide/test/build_app_windows2/stage/empty-directory b/toolkit/devtools/webide/test/build_app_windows2/stage/empty-directory new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/toolkit/devtools/webide/test/build_app_windows2/stage/empty-directory diff --git a/toolkit/devtools/webide/test/chrome.ini b/toolkit/devtools/webide/test/chrome.ini new file mode 100644 index 000000000..893fbba0c --- /dev/null +++ b/toolkit/devtools/webide/test/chrome.ini @@ -0,0 +1,55 @@ +[DEFAULT] +support-files = + app/index.html + app/manifest.webapp + app.zip + addons/simulators.json + addons/fxos_1_0_simulator-linux.xpi + addons/fxos_1_0_simulator-linux64.xpi + addons/fxos_1_0_simulator-win32.xpi + addons/fxos_1_0_simulator-mac64.xpi + addons/fxos_2_0_simulator-linux.xpi + addons/fxos_2_0_simulator-linux64.xpi + addons/fxos_2_0_simulator-win32.xpi + addons/fxos_2_0_simulator-mac64.xpi + addons/fxos_3_0_simulator-linux.xpi + addons/fxos_3_0_simulator-linux64.xpi + addons/fxos_3_0_simulator-win32.xpi + addons/fxos_3_0_simulator-mac64.xpi + addons/adbhelper-linux.xpi + addons/adbhelper-linux64.xpi + addons/adbhelper-win32.xpi + addons/adbhelper-mac64.xpi + addons/fxdt-adapters-linux32.xpi + addons/fxdt-adapters-linux64.xpi + addons/fxdt-adapters-win32.xpi + addons/fxdt-adapters-mac64.xpi + build_app1/package.json + build_app2/manifest.webapp + build_app2/package.json + build_app2/stage/empty-directory + build_app_windows1/package.json + build_app_windows2/manifest.webapp + build_app_windows2/package.json + build_app_windows2/stage/empty-directory + device_front_shared.js + head.js + hosted_app.manifest + templates.json + +[test_basic.html] +[test_newapp.html] +[test_import.html] +[test_duplicate_import.html] +[test_runtime.html] +[test_manifestUpdate.html] +[test_addons.html] +[test_device_runtime.html] +[test_device_permissions.html] +[test_autoconnect_runtime.html] +[test_telemetry.html] +[test_device_preferences.html] +[test_device_settings.html] +[test_fullscreenToolbox.html] +[test_zoom.html] +[test_build.html] diff --git a/toolkit/devtools/webide/test/device_front_shared.js b/toolkit/devtools/webide/test/device_front_shared.js new file mode 100644 index 000000000..c4f7f1906 --- /dev/null +++ b/toolkit/devtools/webide/test/device_front_shared.js @@ -0,0 +1,219 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +let customName; +let customValue; +let customValueType; +let customBtn; +let newField; +let change; +let doc; +let iframe; +let resetBtn; +let found = false; + +function setDocument(frame) { + iframe = frame; + doc = iframe.contentWindow.document; +} + +function fieldChange(fields, id) { + // Trigger existing field change + for (let field of fields) { + if (field.id == id) { + let button = doc.getElementById("btn-" + id); + found = true; + ok(button.classList.contains("hide"), "Default field detected"); + field.value = "custom"; + field.click(); + ok(!button.classList.contains("hide"), "Custom field detected"); + break; + } + } + ok(found, "Found " + id + " line"); +} + +function addNewField() { + found = false; + customName = doc.querySelector("#custom-value-name"); + customValue = doc.querySelector("#custom-value-text"); + customValueType = doc.querySelector("#custom-value-type"); + customBtn = doc.querySelector("#custom-value"); + change = doc.createEvent("HTMLEvents"); + change.initEvent("change", false, true); + + // Add a new custom string + customValueType.value = "string"; + customValueType.dispatchEvent(change); + customName.value = "new-string-field!"; + customValue.value = "test"; + customBtn.click(); + let newField = doc.querySelector("#new-string-field"); + if (newField) { + found = true; + is(newField.type, "text", "Custom type is a string"); + is(newField.value, "test", "Custom string new value is correct"); + } + ok(found, "Found new string field line"); + is(customName.value, "", "Custom string name reset"); + is(customValue.value, "", "Custom string value reset"); +} + +function addNewFieldWithEnter() { + // Add a new custom value with the <enter> key + found = false; + customName.value = "new-string-field-two"; + customValue.value = "test"; + let newAddField = doc.querySelector("#add-custom-field"); + let enter = doc.createEvent("KeyboardEvent"); + enter.initKeyEvent( + "keyup", true, true, null, false, false, false, false, 13, 0); + newAddField.dispatchEvent(enter); + newField = doc.querySelector("#new-string-field-two"); + if (newField) { + found = true; + is(newField.type, "text", "Custom type is a string"); + is(newField.value, "test", "Custom string new value is correct"); + } + ok(found, "Found new string field line"); + is(customName.value, "", "Custom string name reset"); + is(customValue.value, "", "Custom string value reset"); +} + +function editExistingField() { + // Edit existing custom string preference + newField.value = "test2"; + newField.click(); + is(newField.value, "test2", "Custom string existing value is correct"); +} + +function addNewFieldInteger() { + // Add a new custom integer preference with a valid integer + customValueType.value = "number"; + customValueType.dispatchEvent(change); + customName.value = "new-integer-field"; + customValue.value = 1; + found = false; + + customBtn.click(); + newField = doc.querySelector("#new-integer-field"); + if (newField) { + found = true; + is(newField.type, "number", "Custom type is a number"); + is(newField.value, 1, "Custom integer value is correct"); + } + ok(found, "Found new integer field line"); + is(customName.value, "", "Custom integer name reset"); + is(customValue.value, 0, "Custom integer value reset"); +} + +let editFieldInteger = Task.async(function*() { + // Edit existing custom integer preference + newField.value = 3; + newField.click(); + is(newField.value, 3, "Custom integer existing value is correct"); + + // Reset a custom field + let resetBtn = doc.querySelector("#btn-new-integer-field"); + resetBtn.click(); + + try { + yield iframe.contentWindow.configView._defaultField; + } catch(err) { + let fieldRow = doc.querySelector("#row-new-integer-field"); + if (!fieldRow) { + found = false; + } + ok(!found, "Custom field removed"); + } +}); + +let resetExistingField = Task.async(function*(id) { + let existing = doc.getElementById(id); + existing.click(); + is(existing.checked, true, "Existing boolean value is correct"); + resetBtn = doc.getElementById("btn-" + id); + resetBtn.click(); + + yield iframe.contentWindow.configView._defaultField; + + ok(resetBtn.classList.contains("hide"), true, "Reset button hidden"); + is(existing.checked, true, "Existing field reset"); +}); + +let resetNewField = Task.async(function*(id) { + let custom = doc.getElementById(id); + custom.click(); + is(custom.value, "test", "New string value is correct"); + resetBtn = doc.getElementById("btn-" + id); + resetBtn.click(); + + yield iframe.contentWindow.configView._defaultField; + + ok(resetBtn.classList.contains("hide"), true, "Reset button hidden"); +}); + +function addNewFieldBoolean() { + customValueType.value = "boolean"; + customValueType.dispatchEvent(change); + customName.value = "new-boolean-field"; + customValue.checked = true; + found = false; + customBtn.click(); + newField = doc.querySelector("#new-boolean-field"); + if (newField) { + found = true; + is(newField.type, "checkbox", "Custom type is a checkbox"); + is(newField.checked, true, "Custom boolean value is correctly true"); + } + ok(found, "Found new boolean field line"); + + // Mouse event trigger + var mouseClick = new MouseEvent("click", { + canBubble: true, + cancelable: true, + view: doc.parent, + }); + + found = false; + customValueType.value = "boolean"; + customValueType.dispatchEvent(change); + customName.value = "new-boolean-field2"; + customValue.dispatchEvent(mouseClick); + customBtn.dispatchEvent(mouseClick); + newField = doc.querySelector("#new-boolean-field2"); + if (newField) { + found = true; + is(newField.checked, true, "Custom boolean value is correctly false"); + } + ok(found, "Found new second boolean field line"); + + is(customName.value, "", "Custom boolean name reset"); + is(customValue.checked, false, "Custom boolean value reset"); + + newField.click(); + is(newField.checked, false, "Custom boolean existing value is correct"); +} + +function searchFields(deck, keyword) { + // Search for a non-existent field + let searchField = doc.querySelector("#search-bar"); + searchField.value = "![o_O]!"; + searchField.click(); + + let fieldsTotal = doc.querySelectorAll("tr.edit-row").length; + let hiddenFields = doc.querySelectorAll("tr.hide"); + is(hiddenFields.length, fieldsTotal, "Search keyword not found"); + + // Search for existing fields + searchField.value = keyword; + searchField.click(); + hiddenFields = doc.querySelectorAll("tr.hide"); + isnot(hiddenFields.length, fieldsTotal, "Search keyword found"); + + doc.querySelector("#close").click(); + + ok(!deck.selectedPanel, "No panel selected"); +} diff --git a/toolkit/devtools/webide/test/doc_tabs.html b/toolkit/devtools/webide/test/doc_tabs.html new file mode 100644 index 000000000..4901289fc --- /dev/null +++ b/toolkit/devtools/webide/test/doc_tabs.html @@ -0,0 +1,15 @@ +<!-- Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ --> +<!doctype html> + +<html> + <head> + <meta charset="utf-8"/> + <title>Test Tab</title> + </head> + + <body> + Test Tab + </body> + +</html> diff --git a/toolkit/devtools/webide/test/head.js b/toolkit/devtools/webide/test/head.js new file mode 100644 index 000000000..7953a7667 --- /dev/null +++ b/toolkit/devtools/webide/test/head.js @@ -0,0 +1,209 @@ +/* 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 {devtools} = Cu.import("resource://gre/modules/devtools/Loader.jsm", {}); +const {require} = devtools; +const promise = require("promise"); +const {AppProjects} = require("devtools/app-manager/app-projects"); + +let TEST_BASE; +if (window.location === "chrome://browser/content/browser.xul") { + TEST_BASE = "chrome://mochitests/content/browser/browser/devtools/webide/test/"; +} else { + TEST_BASE = "chrome://mochitests/content/chrome/browser/devtools/webide/test/"; +} + +Services.prefs.setBoolPref("devtools.webide.enabled", true); +Services.prefs.setBoolPref("devtools.webide.enableLocalRuntime", true); + +Services.prefs.setCharPref("devtools.webide.addonsURL", TEST_BASE + "addons/simulators.json"); +Services.prefs.setCharPref("devtools.webide.simulatorAddonsURL", TEST_BASE + "addons/fxos_#SLASHED_VERSION#_simulator-#OS#.xpi"); +Services.prefs.setCharPref("devtools.webide.adbAddonURL", TEST_BASE + "addons/adbhelper-#OS#.xpi"); +Services.prefs.setCharPref("devtools.webide.adaptersAddonURL", TEST_BASE + "addons/fxdt-adapters-#OS#.xpi"); +Services.prefs.setCharPref("devtools.webide.templatesURL", TEST_BASE + "templates.json"); + + +SimpleTest.registerCleanupFunction(() => { + Services.prefs.clearUserPref("devtools.webide.enabled"); + Services.prefs.clearUserPref("devtools.webide.enableLocalRuntime"); + Services.prefs.clearUserPref("devtools.webide.autoinstallADBHelper"); + Services.prefs.clearUserPref("devtools.webide.autoinstallFxdtAdapters"); +}); + +function openWebIDE(autoInstallAddons) { + info("opening WebIDE"); + + Services.prefs.setBoolPref("devtools.webide.autoinstallADBHelper", !!autoInstallAddons); + Services.prefs.setBoolPref("devtools.webide.autoinstallFxdtAdapters", !!autoInstallAddons); + + 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.requestCompleteLog(); + SimpleTest.executeSoon(() => { + deferred.resolve(win); + }); + }); + + return deferred.promise; +} + +function closeWebIDE(win) { + info("Closing WebIDE"); + + let deferred = promise.defer(); + + Services.prefs.clearUserPref("devtools.webide.widget.enabled"); + + win.addEventListener("unload", function onUnload() { + win.removeEventListener("unload", onUnload); + info("WebIDE closed"); + SimpleTest.executeSoon(() => { + deferred.resolve(); + }); + }); + + win.close(); + + return deferred.promise; +} + +function removeAllProjects() { + return Task.spawn(function* () { + yield AppProjects.load(); + // use a new array so we're not iterating over the same + // underlying array that's being modified by AppProjects + let projects = AppProjects.store.object.projects.map(p => p.location); + for (let i = 0; i < projects.length; i++) { + yield AppProjects.remove(projects[i]); + } + }); +} + +function nextTick() { + let deferred = promise.defer(); + SimpleTest.executeSoon(() => { + deferred.resolve(); + }); + + return deferred.promise; +} + +function waitForUpdate(win, update) { + let deferred = promise.defer(); + win.AppManager.on("app-manager-update", function onUpdate(e, what) { + if (what !== update) { + return; + } + win.AppManager.off("app-manager-update", onUpdate); + deferred.resolve(win.UI._updatePromise); + }); + return deferred.promise; +} + +function waitForTime(time) { + let deferred = promise.defer(); + setTimeout(() => { + deferred.resolve(); + }, time); + return deferred.promise; +} + +function documentIsLoaded(doc) { + let deferred = promise.defer(); + if (doc.readyState == "complete") { + deferred.resolve(); + } else { + doc.addEventListener("readystatechange", function onChange() { + if (doc.readyState == "complete") { + doc.removeEventListener("readystatechange", onChange); + deferred.resolve(); + } + }); + } + return deferred.promise; +} + +function lazyIframeIsLoaded(iframe) { + let deferred = promise.defer(); + iframe.addEventListener("load", function onLoad() { + iframe.removeEventListener("load", onLoad, true); + deferred.resolve(); + }, true); + return deferred.promise; +} + +function addTab(aUrl, aWindow) { + info("Adding tab: " + aUrl); + + let deferred = promise.defer(); + let targetWindow = aWindow || window; + let targetBrowser = targetWindow.gBrowser; + + targetWindow.focus(); + let tab = targetBrowser.selectedTab = targetBrowser.addTab(aUrl); + let linkedBrowser = tab.linkedBrowser; + + linkedBrowser.addEventListener("load", function onLoad() { + linkedBrowser.removeEventListener("load", onLoad, true); + info("Tab added and finished loading: " + aUrl); + deferred.resolve(tab); + }, true); + + return deferred.promise; +} + +function removeTab(aTab, aWindow) { + info("Removing tab."); + + let deferred = promise.defer(); + let targetWindow = aWindow || window; + let targetBrowser = targetWindow.gBrowser; + let tabContainer = targetBrowser.tabContainer; + + tabContainer.addEventListener("TabClose", function onClose(aEvent) { + tabContainer.removeEventListener("TabClose", onClose, false); + info("Tab removed and finished closing."); + deferred.resolve(); + }, false); + + targetBrowser.removeTab(aTab); + return deferred.promise; +} + +function connectToLocalRuntime(aWindow) { + info("Loading local runtime."); + + let panelNode = aWindow.document.querySelector("#runtime-panel"); + let items = panelNode.querySelectorAll(".runtime-panel-item-other"); + is(items.length, 2, "Found 2 custom runtime buttons"); + + let deferred = promise.defer(); + aWindow.AppManager.on("app-manager-update", function onUpdate(e,w) { + if (w == "list-tabs-response") { + aWindow.AppManager.off("app-manager-update", onUpdate); + deferred.resolve(); + } + }); + + items[1].click(); + return deferred.promise; +} + +function handleError(aError) { + ok(false, "Got an error: " + aError.message + "\n" + aError.stack); + finish(); +} diff --git a/toolkit/devtools/webide/test/hosted_app.manifest b/toolkit/devtools/webide/test/hosted_app.manifest new file mode 100644 index 000000000..ab5069978 --- /dev/null +++ b/toolkit/devtools/webide/test/hosted_app.manifest @@ -0,0 +1,3 @@ +{ + "name": "hosted manifest name property" +} diff --git a/toolkit/devtools/webide/test/templates.json b/toolkit/devtools/webide/test/templates.json new file mode 100644 index 000000000..8ee4a0dce --- /dev/null +++ b/toolkit/devtools/webide/test/templates.json @@ -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" + } +] diff --git a/toolkit/devtools/webide/test/test_addons.html b/toolkit/devtools/webide/test/test_addons.html new file mode 100644 index 000000000..44ae43daa --- /dev/null +++ b/toolkit/devtools/webide/test/test_addons.html @@ -0,0 +1,172 @@ +<!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(); + + const {GetAvailableAddons} = require("devtools/webide/addons"); + const {Devices} = Cu.import("resource://gre/modules/devtools/Devices.jsm"); + const {Simulator} = Cu.import("resource://gre/modules/devtools/Simulator.jsm"); + + let adbAddonsInstalled = promise.defer(); + Devices.on("addon-status-updated", function onUpdate1() { + Devices.off("addon-status-updated", onUpdate1); + adbAddonsInstalled.resolve(); + }); + + function getVersion(name) { + return name.match(/(\d+\.\d+)/)[0]; + } + + function onSimulatorInstalled(name) { + let deferred = promise.defer(); + Simulator.on("register", function onUpdate() { + if (Simulator.getByName(name)) { + Simulator.off("register", onUpdate); + nextTick().then(deferred.resolve); + } + }); + return deferred.promise; + } + + function installSimulatorFromUI(doc, name) { + let li = doc.querySelector('[addon="simulator-' + getVersion(name) + '"]'); + li.querySelector(".install-button").click(); + return onSimulatorInstalled(name); + } + + function uninstallSimulatorFromUI(doc, name) { + let deferred = promise.defer(); + Simulator.on("unregister", function onUpdate() { + nextTick().then(() => { + let li = doc.querySelector('[status="uninstalled"][addon="simulator-' + getVersion(name) + '"]'); + if (li) { + Simulator.off("unregister", onUpdate); + deferred.resolve(); + } else { + deferred.reject("Can't find item"); + } + }) + }); + let li = doc.querySelector('[status="installed"][addon="simulator-' + getVersion(name) + '"]'); + li.querySelector(".uninstall-button").click(); + return deferred.promise; + } + + function uninstallADBFromUI(doc) { + let deferred = promise.defer(); + Devices.on("addon-status-updated", function onUpdate() { + nextTick().then(() => { + let li = doc.querySelector('[status="uninstalled"][addon="adb"]'); + if (li) { + Devices.off("addon-status-updated", onUpdate); + deferred.resolve(); + } else { + deferred.reject("Can't find item"); + } + }) + }); + let li = doc.querySelector('[status="installed"][addon="adb"]'); + li.querySelector(".uninstall-button").click(); + return deferred.promise; + } + + Task.spawn(function* () { + + ok(!Devices.helperAddonInstalled, "Helper not installed"); + + let win = yield openWebIDE(true); + + yield adbAddonsInstalled.promise; + + ok(Devices.helperAddonInstalled, "Helper has been auto-installed"); + + yield nextTick(); + + let addons = yield GetAvailableAddons(); + + is(addons.simulators.length, 3, "3 simulator addons to install"); + + let sim10 = addons.simulators.filter(a => a.version == "1.0")[0]; + sim10.install(); + + yield onSimulatorInstalled("Firefox OS 1.0"); + + win.Cmds.showAddons(); + + let frame = win.document.querySelector("#deck-panel-addons"); + let addonDoc = frame.contentWindow.document; + let lis; + + lis = addonDoc.querySelectorAll("li"); + is(lis.length, 5, "5 addons listed"); + + lis = addonDoc.querySelectorAll('li[status="installed"]'); + is(lis.length, 3, "3 addons installed"); + + lis = addonDoc.querySelectorAll('li[status="uninstalled"]'); + is(lis.length, 2, "2 addons uninstalled"); + + info("Uninstalling Simulator 2.0"); + + yield installSimulatorFromUI(addonDoc, "Firefox OS 2.0"); + + info("Uninstalling Simulator 3.0"); + + yield installSimulatorFromUI(addonDoc, "Firefox OS 3.0"); + + yield nextTick(); + + let panelNode = win.document.querySelector("#runtime-panel"); + let items; + + items = panelNode.querySelectorAll(".runtime-panel-item-usb"); + is(items.length, 1, "Found one runtime button"); + + items = panelNode.querySelectorAll(".runtime-panel-item-simulator"); + is(items.length, 3, "Found 3 simulators button"); + + yield uninstallSimulatorFromUI(addonDoc, "Firefox OS 1.0"); + yield uninstallSimulatorFromUI(addonDoc, "Firefox OS 2.0"); + yield uninstallSimulatorFromUI(addonDoc, "Firefox OS 3.0"); + + items = panelNode.querySelectorAll(".runtime-panel-item-simulator"); + is(items.length, 0, "No simulator listed"); + + let w = addonDoc.querySelector(".warning"); + let display = addonDoc.defaultView.getComputedStyle(w).display + is(display, "none", "Warning about missing ADB hidden"); + + yield uninstallADBFromUI(addonDoc, "adb"); + + items = panelNode.querySelectorAll(".runtime-panel-item-usb"); + is(items.length, 0, "No usb runtime listed"); + + display = addonDoc.defaultView.getComputedStyle(w).display + is(display, "block", "Warning about missing ADB present"); + + yield closeWebIDE(win); + + SimpleTest.finish(); + + }); + } + + + </script> + </body> +</html> diff --git a/toolkit/devtools/webide/test/test_autoconnect_runtime.html b/toolkit/devtools/webide/test/test_autoconnect_runtime.html new file mode 100644 index 000000000..ef12fc88d --- /dev/null +++ b/toolkit/devtools/webide/test/test_autoconnect_runtime.html @@ -0,0 +1,91 @@ +<!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* () { + + Cu.import("resource://gre/modules/devtools/dbg-server.jsm"); + DebuggerServer.init(); + DebuggerServer.addBrowserActors(); + + let win = yield openWebIDE(); + + let fakeRuntime = { + type: "USB", + connect: function(connection) { + is(connection, win.AppManager.connection, "connection is valid"); + connection.host = null; // force connectPipe + connection.connect(); + return promise.resolve(); + }, + + get id() { + return "fakeRuntime"; + }, + + get name() { + return "fakeRuntime"; + } + }; + win.AppManager.runtimeList.usb.push(fakeRuntime); + win.AppManager.update("runtimelist"); + + let panelNode = win.document.querySelector("#runtime-panel"); + let items = panelNode.querySelectorAll(".runtime-panel-item-usb"); + 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(); + + ok(win.document.querySelector("window").className, "busy", "UI is busy"); + yield win.UI._busyPromise; + is(Object.keys(DebuggerServer._connections).length, 1, "Connected"); + + yield nextTick(); + + yield closeWebIDE(win); + + is(Object.keys(DebuggerServer._connections).length, 0, "Disconnected"); + + win = yield openWebIDE(); + + win.AppManager.runtimeList.usb.push(fakeRuntime); + win.AppManager.update("runtimelist"); + + yield waitForUpdate(win, "runtime-apps-found"); + + is(Object.keys(DebuggerServer._connections).length, 1, "Automatically reconnected"); + + yield win.Cmds.disconnectRuntime(); + + yield closeWebIDE(win); + + DebuggerServer.destroy(); + + SimpleTest.finish(); + }); + } + + + </script> + </body> +</html> diff --git a/toolkit/devtools/webide/test/test_basic.html b/toolkit/devtools/webide/test/test_basic.html new file mode 100644 index 000000000..0cc7b1e46 --- /dev/null +++ b/toolkit/devtools/webide/test/test_basic.html @@ -0,0 +1,51 @@ +<!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(); + + 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"); + + // test error reporting + let nbox = win.document.querySelector("#notificationbox"); + let notification = nbox.getNotificationWithValue("webide:errornotification"); + ok(!notification, "No notification yet"); + let deferred = promise.defer(); + nextTick().then(() => { + deferred.reject("BOOM!"); + }); + try { + yield win.UI.busyUntil(deferred.promise, "xx"); + } catch(e) {/* This *will* fail */} + notification = nbox.getNotificationWithValue("webide:errornotification"); + ok(notification, "Error has been reported"); + + yield closeWebIDE(win); + + SimpleTest.finish(); + }); + } + </script> + </body> +</html> diff --git a/toolkit/devtools/webide/test/test_build.html b/toolkit/devtools/webide/test/test_build.html new file mode 100644 index 000000000..a43a2c3f3 --- /dev/null +++ b/toolkit/devtools/webide/test/test_build.html @@ -0,0 +1,119 @@ +<!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(); + + let {TextDecoder, OS} = Cu.import("resource://gre/modules/osfile.jsm", {}); + let {ProjectBuilding} = require("devtools/webide/build"); + + Task.spawn(function* () { + let win = yield openWebIDE(); + let AppManager = win.AppManager; + + function isProjectMarkedAsValid() { + let details = win.UI.projecteditor.window.frames[0]; + return !details.document.body.classList.contains("error"); + } + + // # Test first package.json like this: `{webide: {prepackage: "command line string"}}` + let platform = Services.appShell.hiddenDOMWindow.navigator.platform; + let testSuffix = ""; + if (platform.indexOf("Win") != -1) { + testSuffix = "_windows"; + } + + let packagedAppLocation = getTestFilePath("build_app" + testSuffix + "1"); + + yield win.Cmds.importPackagedApp(packagedAppLocation); + + let project = win.AppManager.selectedProject; + + let deferred = promise.defer(); + win.UI.projecteditor.once("onEditorCreated", deferred.resolve); + yield deferred.promise; + + ok(!project.manifest, "manifest includes name"); + is(project.name, "--", "Display name uses manifest name"); + + let loggedMessages = []; + let logger = function (msg) { + loggedMessages.push(msg); + } + + let packageDir = yield ProjectBuilding.build({ + project, + logger + }); + ok(!packageDir, "no custom packagedir"); + is(loggedMessages[0], "start", "log messages are correct"); + ok(loggedMessages[1].indexOf("Running pre-package hook") != -1, "log messages are correct"); + is(loggedMessages[2], "Terminated with error code: 0", "log messages are correct"); + is(loggedMessages[3], "succeed", "log messages are correct"); + + // Trigger validation + yield AppManager.validateProject(AppManager.selectedProject); + yield nextTick(); + + ok("name" in project.manifest, "manifest includes name"); + is(project.name, "hello", "Display name uses manifest name"); + is(project.manifest.name, project.name, "Display name uses manifest name"); + + yield OS.File.remove(OS.Path.join(packagedAppLocation, "manifest.webapp")); + + // # Now test a full featured package.json + packagedAppLocation = getTestFilePath("build_app" + testSuffix + "2"); + + yield win.Cmds.importPackagedApp(packagedAppLocation); + + project = win.AppManager.selectedProject; + + loggedMessages = []; + packageDir = yield ProjectBuilding.build({ + project, + logger + }); + is(OS.Path.normalize(packageDir), + OS.Path.join(packagedAppLocation, "stage"), "custom packagedir"); + is(loggedMessages[0], "start", "log messages are correct"); + ok(loggedMessages[1].indexOf("Running pre-package hook") != -1, "log messages are correct"); + is(loggedMessages[2], "Terminated with error code: 0", "log messages are correct"); + is(loggedMessages[3], "succeed", "log messages are correct"); + + // Switch to the package dir in order to verify the generated webapp.manifest + yield win.Cmds.importPackagedApp(packageDir); + + project = win.AppManager.selectedProject; + + ok("name" in project.manifest, "manifest includes name"); + is(project.name, "world", "Display name uses manifest name"); + is(project.manifest.name, project.name, "Display name uses manifest name"); + + yield closeWebIDE(win); + + yield removeAllProjects(); + + SimpleTest.finish(); + }); + } + + + </script> + </body> +</html> + + diff --git a/toolkit/devtools/webide/test/test_device_permissions.html b/toolkit/devtools/webide/test/test_device_permissions.html new file mode 100644 index 000000000..654f9092e --- /dev/null +++ b/toolkit/devtools/webide/test/test_device_permissions.html @@ -0,0 +1,83 @@ +<!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* () { + Cu.import("resource://gre/modules/devtools/dbg-server.jsm"); + + if (!DebuggerServer.initialized) { + DebuggerServer.init(); + DebuggerServer.addBrowserActors(); + } + + let win = yield openWebIDE(); + + let permIframe = win.document.querySelector("#deck-panel-permissionstable"); + + yield connectToLocalRuntime(win); + + let perm = win.document.querySelector("#cmd_showPermissionsTable"); + + ok(!perm.hasAttribute("disabled"), "perm cmd enabled"); + + let deck = win.document.querySelector("#deck"); + + win.Cmds.showPermissionsTable(); + is(deck.selectedPanel, permIframe, "permission iframe selected"); + + yield nextTick(); + + yield lazyIframeIsLoaded(permIframe); + + yield nextTick(); + + yield permIframe.contentWindow.getRawPermissionsTablePromise; + + doc = permIframe.contentWindow.document; + trs = doc.querySelectorAll(".line"); + found = false; + for (let tr of trs) { + let [name,v1,v2,v3] = tr.querySelectorAll("td"); + if (name.textContent == "geolocation") { + found = true; + is(v1.className, "permprompt", "geolocation perm is valid"); + is(v2.className, "permprompt", "geolocation perm is valid"); + is(v3.className, "permprompt", "geolocation perm is valid"); + break; + } + } + ok(found, "Found geolocation line"); + + doc.querySelector("#close").click(); + + ok(!deck.selectedPanel, "No panel selected"); + + DebuggerServer.destroy(); + + yield closeWebIDE(win); + + SimpleTest.finish(); + }).then(null, e => { + ok(false, "Exception: " + e); + SimpleTest.finish(); + }); + } + </script> + </body> +</html> diff --git a/toolkit/devtools/webide/test/test_device_preferences.html b/toolkit/devtools/webide/test/test_device_preferences.html new file mode 100644 index 000000000..7acc2a258 --- /dev/null +++ b/toolkit/devtools/webide/test/test_device_preferences.html @@ -0,0 +1,90 @@ +<!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> + <script type="application/javascript;version=1.8" src="device_front_shared.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* () { + Cu.import("resource://gre/modules/devtools/dbg-server.jsm"); + + if (!DebuggerServer.initialized) { + DebuggerServer.init(); + DebuggerServer.addBrowserActors(); + } + + let win = yield openWebIDE(); + + let prefIframe = win.document.querySelector("#deck-panel-devicepreferences"); + + win.AppManager.update("runtimelist"); + + yield connectToLocalRuntime(win); + + let prefs = win.document.querySelector("#cmd_showDevicePrefs"); + + ok(!prefs.hasAttribute("disabled"), "device prefs cmd enabled"); + + let deck = win.document.querySelector("#deck"); + + win.Cmds.showDevicePrefs(); + is(deck.selectedPanel, prefIframe, "device preferences iframe selected"); + + yield nextTick(); + + yield lazyIframeIsLoaded(prefIframe); + + yield nextTick(); + + yield prefIframe.contentWindow.getAllPrefs; + + setDocument(prefIframe); + + let fields = doc.querySelectorAll(".editable"); + + addNewField(); + + let preference = "accessibility.accesskeycausesactivation"; + + fieldChange(fields, preference); + + addNewFieldWithEnter(); + + editExistingField(); + + addNewFieldInteger(); + + yield editFieldInteger(); + + yield resetExistingField("accessibility.accesskeycausesactivation"); + + addNewFieldBoolean(); + + searchFields(deck, "debugger"); + + DebuggerServer.destroy(); + + yield closeWebIDE(win); + + SimpleTest.finish(); + }).then(null, e => { + ok(false, "Exception: " + e); + SimpleTest.finish(); + }); + } + </script> + </body> +</html> diff --git a/toolkit/devtools/webide/test/test_device_runtime.html b/toolkit/devtools/webide/test/test_device_runtime.html new file mode 100644 index 000000000..bea754fbb --- /dev/null +++ b/toolkit/devtools/webide/test/test_device_runtime.html @@ -0,0 +1,85 @@ +<!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* () { + Cu.import("resource://gre/modules/devtools/dbg-server.jsm"); + + if (!DebuggerServer.initialized) { + DebuggerServer.init(); + DebuggerServer.addBrowserActors(); + } + + let win = yield openWebIDE(); + + let detailsIframe = win.document.querySelector("#deck-panel-runtimedetails"); + + yield connectToLocalRuntime(win); + + let details = win.document.querySelector("#cmd_showRuntimeDetails"); + + ok(!details.hasAttribute("disabled"), "info cmd enabled"); + + let deck = win.document.querySelector("#deck"); + + win.Cmds.showRuntimeDetails(); + is(deck.selectedPanel, detailsIframe, "info iframe selected"); + + yield nextTick(); + + yield lazyIframeIsLoaded(detailsIframe); + + yield nextTick(); + + yield detailsIframe.contentWindow.getDescriptionPromise; + + // device info and permissions content is checked in other tests + // We just test one value to make sure we get something + + let doc = detailsIframe.contentWindow.document; + let trs = doc.querySelectorAll("tr"); + let found = false; + + for (let tr of trs) { + let [name,val] = tr.querySelectorAll("td"); + if (name.textContent == "appid") { + found = true; + is(val.textContent, Services.appinfo.ID, "appid has the right value"); + break; + } + } + ok(found, "Found appid line"); + + doc.querySelector("#close").click(); + + ok(!deck.selectedPanel, "No panel selected"); + + DebuggerServer.destroy(); + + yield closeWebIDE(win); + + SimpleTest.finish(); + }).then(null, e => { + ok(false, "Exception: " + e); + SimpleTest.finish(); + }); + } + </script> + </body> +</html> diff --git a/toolkit/devtools/webide/test/test_device_settings.html b/toolkit/devtools/webide/test/test_device_settings.html new file mode 100644 index 000000000..e075db4fd --- /dev/null +++ b/toolkit/devtools/webide/test/test_device_settings.html @@ -0,0 +1,90 @@ +<!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> + <script type="application/javascript;version=1.8" src="device_front_shared.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*() { + Cu.import("resource://gre/modules/devtools/dbg-server.jsm"); + + if (SpecialPowers.isMainProcess()) { + Cu.import("resource://gre/modules/SettingsRequestManager.jsm"); + } + + if (!DebuggerServer.initialized) { + DebuggerServer.init(); + DebuggerServer.addBrowserActors(); + } + + let win = yield openWebIDE(); + + let settingIframe = win.document.querySelector("#deck-panel-devicesettings"); + + win.AppManager.update("runtimelist"); + + yield connectToLocalRuntime(win); + + let settings = win.document.querySelector("#cmd_showSettings"); + + ok(!settings.hasAttribute("disabled"), "device settings cmd enabled"); + + let deck = win.document.querySelector("#deck"); + + win.Cmds.showSettings(); + is(deck.selectedPanel, settingIframe, "device settings iframe selected"); + + yield nextTick(); + + yield lazyIframeIsLoaded(settingIframe); + + yield nextTick(); + + yield settingIframe.contentWindow.getAllSettings; + + setDocument(settingIframe); + + let fields = doc.querySelectorAll(".editable"); + + addNewField(); + + addNewFieldWithEnter(); + + editExistingField(); + + addNewFieldInteger(); + + yield editFieldInteger(); + + yield resetNewField("new-string-field"); + + addNewFieldBoolean(); + + searchFields(deck, "new-boolean-field2"); + + DebuggerServer.destroy(); + + yield closeWebIDE(win); + + SimpleTest.finish(); + }).then(null, e => { + ok(false, "Exception: " + e); + SimpleTest.finish(); + }); + } + </script> + </body> +</html> diff --git a/toolkit/devtools/webide/test/test_duplicate_import.html b/toolkit/devtools/webide/test/test_duplicate_import.html new file mode 100644 index 000000000..df8166f22 --- /dev/null +++ b/toolkit/devtools/webide/test/test_duplicate_import.html @@ -0,0 +1,74 @@ +<!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"); + let hostedAppManifest = TEST_BASE + "hosted_app.manifest"; + + yield win.AppProjects.load(); + is(win.AppProjects.store.object.projects.length, 0, "IDB is empty"); + + info("to call importPackagedApp(" + packagedAppLocation + ")"); + yield win.Cmds.importPackagedApp(packagedAppLocation); + yield nextTick(); + + info("to call importHostedApp(" + hostedAppManifest + ")"); + yield win.Cmds.importHostedApp(hostedAppManifest); + yield nextTick(); + + info("to call importPackagedApp(" + packagedAppLocation + ") again"); + yield win.Cmds.importPackagedApp(packagedAppLocation); + + let project = win.AppManager.selectedProject; + is(project.location, packagedAppLocation, "Correctly reselected existing packaged app."); + yield nextTick(); + + info("to call importHostedApp(" + hostedAppManifest + ") again"); + yield win.Cmds.importHostedApp(hostedAppManifest); + project = win.AppManager.selectedProject; + is(project.location, hostedAppManifest, "Correctly reselected existing hosted app."); + yield nextTick(); + + 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(); + }).then(null, e => { + ok(false, "Exception: " + e); + SimpleTest.finish(); + }); + } + </script> + </body> +</html> + diff --git a/toolkit/devtools/webide/test/test_fullscreenToolbox.html b/toolkit/devtools/webide/test/test_fullscreenToolbox.html new file mode 100644 index 000000000..5045f8515 --- /dev/null +++ b/toolkit/devtools/webide/test/test_fullscreenToolbox.html @@ -0,0 +1,74 @@ +<!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"> + + function connectToLocal(win) { + let deferred = promise.defer(); + win.AppManager.connection.once( + win.Connection.Events.CONNECTED, + () => deferred.resolve()); + win.document.querySelectorAll(".runtime-panel-item-other")[1].click(); + return deferred.promise; + } + + window.onload = function() { + SimpleTest.waitForExplicitFinish(); + + Task.spawn(function* () { + Cu.import("resource://gre/modules/devtools/dbg-server.jsm"); + win = yield openWebIDE(); + win.AppManager.update("runtimelist"); + + yield connectToLocal(win); + + yield waitForUpdate(win, "runtime-apps-found"); + + // Select main process + yield win.Cmds.showProjectPanel(); + SimpleTest.executeSoon(() => { + win.document.querySelectorAll("#project-panel-runtimeapps .panel-item")[0].click(); + }); + + yield waitForUpdate(win, "project"); + + ok(win.UI.toolboxPromise, "Toolbox promise exists"); + yield win.UI.toolboxPromise; + + ok(win.UI.toolboxIframe, "Toolbox iframe exists"); + + let nbox = win.document.querySelector("#notificationbox"); + ok(nbox.hasAttribute("toolboxfullscreen"), "Toolbox is fullsreen"); + + win.Cmds.showRuntimeDetails(); + + ok(!nbox.hasAttribute("toolboxfullscreen"), "Toolbox is not fullscreen"); + + yield win.Cmds.disconnectRuntime(); + + yield closeWebIDE(win); + + const { DebuggerServer } = Cu.import("resource://gre/modules/devtools/dbg-server.jsm", {}); + DebuggerServer.destroy(); + + SimpleTest.finish(); + }); + } + + + </script> + </body> +</html> diff --git a/toolkit/devtools/webide/test/test_import.html b/toolkit/devtools/webide/test/test_import.html new file mode 100644 index 000000000..6dc5fcddb --- /dev/null +++ b/toolkit/devtools/webide/test/test_import.html @@ -0,0 +1,81 @@ +<!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.AppProjects.load(); + is(win.AppProjects.store.object.projects.length, 0, "IDB is empty"); + + info("to call importPackagedApp(" + packagedAppLocation + ")"); + ok(!win.UI._busyPromise, "UI is not busy"); + + 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"); + + yield nextTick(); + + hostedAppManifest = TEST_BASE + "/app"; + yield win.Cmds.importHostedApp(hostedAppManifest); + + project = win.AppManager.selectedProject; + ok(project.location.endsWith('manifest.webapp'), "The manifest was found and the project was 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, 6, "6 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(); + }).then(null, e => { + ok(false, "Exception: " + e); + SimpleTest.finish(); + }); + } + + + </script> + </body> +</html> diff --git a/toolkit/devtools/webide/test/test_manifestUpdate.html b/toolkit/devtools/webide/test/test_manifestUpdate.html new file mode 100644 index 000000000..23375e3f8 --- /dev/null +++ b/toolkit/devtools/webide/test/test_manifestUpdate.html @@ -0,0 +1,101 @@ +<!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(); + + let {TextDecoder, OS} = Cu.import("resource://gre/modules/osfile.jsm", {}); + + Task.spawn(function* () { + let win = yield openWebIDE(); + let AppManager = win.AppManager; + + function isProjectMarkedAsValid() { + let details = win.UI.projecteditor.window.frames[0]; + return !details.document.body.classList.contains("error"); + } + + let packagedAppLocation = getTestFilePath("app"); + + yield win.Cmds.importPackagedApp(packagedAppLocation); + + let project = win.AppManager.selectedProject; + + let deferred = promise.defer(); + win.UI.projecteditor.once("onEditorCreated", deferred.resolve); + yield deferred.promise; + + ok("name" in project.manifest, "manifest includes name"); + is(project.name, project.manifest.name, "Display name uses manifest name"); + ok(isProjectMarkedAsValid(), "project is marked as valid"); + + // Change the name + let originalName = project.manifest.name; + + project.manifest.name = "xxx"; + + // Write to disk + yield AppManager.writeManifest(project); + + // Read file + let manifestPath = OS.Path.join(packagedAppLocation, "manifest.webapp"); + let Decoder = new TextDecoder(); + let data = yield OS.File.read(manifestPath); + data = new TextDecoder().decode(data); + let json = JSON.parse(data); + is(json.name, "xxx", "manifest written on disc"); + + // Make the manifest invalid on disk + delete json.name; + let Encoder = new TextEncoder(); + data = Encoder.encode(JSON.stringify(json)); + yield OS.File.writeAtomic(manifestPath, data , {tmpPath: manifestPath + ".tmp"}); + + // Trigger validation + yield AppManager.validateProject(AppManager.selectedProject); + yield nextTick(); + + ok(!("name" in project.manifest), "manifest has been updated"); + is(project.name, "--", "Placeholder is used for display name"); + ok(!isProjectMarkedAsValid(), "project is marked as invalid"); + + // Make the manifest valid on disk + project.manifest.name = originalName; + yield AppManager.writeManifest(project); + + // Trigger validation + yield AppManager.validateProject(AppManager.selectedProject); + yield nextTick(); + + ok("name" in project.manifest, "manifest includes name"); + is(project.name, originalName, "Display name uses original manifest name"); + ok(isProjectMarkedAsValid(), "project is marked as valid"); + + yield closeWebIDE(win); + + yield removeAllProjects(); + + SimpleTest.finish(); + }); + } + + + </script> + </body> +</html> + + diff --git a/toolkit/devtools/webide/test/test_newapp.html b/toolkit/devtools/webide/test/test_newapp.html new file mode 100644 index 000000000..29c6db8b6 --- /dev/null +++ b/toolkit/devtools/webide/test/test_newapp.html @@ -0,0 +1,45 @@ +<!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 tmpDir = FileUtils.getDir("TmpD", []); + yield win.Cmds.newApp({ + index: 0, + name: "webideTmpApp", + folder: tmpDir + }); + + let project = win.AppManager.selectedProject; + 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); + yield closeWebIDE(win); + yield removeAllProjects(); + SimpleTest.finish(); + }); + } + </script> + </body> +</html> diff --git a/toolkit/devtools/webide/test/test_runtime.html b/toolkit/devtools/webide/test/test_runtime.html new file mode 100644 index 000000000..895bab4af --- /dev/null +++ b/toolkit/devtools/webide/test/test_runtime.html @@ -0,0 +1,147 @@ +<!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(); + + let win; + + SimpleTest.registerCleanupFunction(() => { + Task.spawn(function*() { + if (win) { + yield closeWebIDE(win); + } + DebuggerServer.destroy(); + yield removeAllProjects(); + }); + }); + + 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"); + + if (!DebuggerServer.initialized) { + DebuggerServer.init(); + DebuggerServer.addBrowserActors(); + } + + win = yield openWebIDE(); + + win.AppManager.runtimeList.usb.push({ + connect: function(connection) { + is(connection, win.AppManager.connection, "connection is valid"); + connection.host = null; // force connectPipe + connection.connect(); + return promise.resolve(); + }, + + get name() { + return "fakeRuntime"; + } + }); + + win.AppManager.update("runtimelist"); + + let packagedAppLocation = getTestFilePath("app"); + + yield win.Cmds.importPackagedApp(packagedAppLocation); + + let panelNode = win.document.querySelector("#runtime-panel"); + let items = panelNode.querySelectorAll(".runtime-panel-item-usb"); + 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(); + + ok(win.document.querySelector("window").className, "busy", "UI is busy"); + yield win.UI._busyPromise; + + is(Object.keys(DebuggerServer._connections).length, 1, "Connected"); + + yield waitForUpdate(win, "runtime-apps-found"); + + ok(isPlayActive(), "play button is enabled 1"); + ok(!isStopActive(), "stop button is disabled 1"); + let oldProject = win.AppManager.selectedProject; + win.AppManager.selectedProject = null; + + yield nextTick(); + + ok(!isPlayActive(), "play button is disabled 2"); + ok(!isStopActive(), "stop button is disabled 2"); + win.AppManager._selectedProject = oldProject; + win.UI.updateCommands(); + + yield nextTick(); + + ok(isPlayActive(), "play button is enabled 3"); + ok(!isStopActive(), "stop button is disabled 3"); + + + yield win.Cmds.disconnectRuntime(); + + is(Object.keys(DebuggerServer._connections).length, 0, "Disconnected"); + + ok(win.AppManager.selectedProject, "A project is still selected"); + ok(!isPlayActive(), "play button is disabled 4"); + ok(!isStopActive(), "stop button is disabled 4"); + + win.document.querySelectorAll(".runtime-panel-item-other")[1].click(); + + yield waitForUpdate(win, "runtime-apps-found"); + + is(Object.keys(DebuggerServer._connections).length, 1, "Locally connected"); + + ok(win.AppManager.isMainProcessDebuggable(), "Main process available"); + + // Select main process + yield win.Cmds.showProjectPanel(); + SimpleTest.executeSoon(() => { + win.document.querySelectorAll("#project-panel-runtimeapps .panel-item")[0].click(); + }); + + yield waitForUpdate(win, "project"); + + // Toolbox opens automatically for main process / runtime apps + ok(win.UI.toolboxPromise, "Toolbox promise exists"); + yield win.UI.toolboxPromise; + + ok(win.UI.toolboxIframe, "Toolbox iframe exists"); + + yield win.Cmds.disconnectRuntime(); + + SimpleTest.finish(); + + }); + } + + + </script> + </body> +</html> diff --git a/toolkit/devtools/webide/test/test_telemetry.html b/toolkit/devtools/webide/test/test_telemetry.html new file mode 100644 index 000000000..163fd67a3 --- /dev/null +++ b/toolkit/devtools/webide/test/test_telemetry.html @@ -0,0 +1,264 @@ +<!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"> + const Telemetry = require("devtools/shared/telemetry"); + const { _DeprecatedUSBRuntime, _WiFiRuntime, _SimulatorRuntime, + _gRemoteRuntime, _gLocalRuntime, RuntimeTypes } + = require("devtools/webide/runtimes"); + + // Because we need to gather stats for the period of time that a tool has + // been opened we make use of setTimeout() to create tool active times. + const TOOL_DELAY = 200; + + function patchTelemetry() { + Telemetry.prototype.telemetryInfo = {}; + Telemetry.prototype._oldlog = Telemetry.prototype.log; + Telemetry.prototype.log = function(histogramId, value) { + if (histogramId) { + if (!this.telemetryInfo[histogramId]) { + this.telemetryInfo[histogramId] = []; + } + this.telemetryInfo[histogramId].push(value); + } + } + } + + function resetTelemetry() { + Telemetry.prototype.log = Telemetry.prototype._oldlog; + delete Telemetry.prototype._oldlog; + delete Telemetry.prototype.telemetryInfo; + } + + function cycleWebIDE() { + return Task.spawn(function*() { + let win = yield openWebIDE(); + // Wait a bit, so we're open for a non-zero time + yield waitForTime(TOOL_DELAY); + yield closeWebIDE(win); + }); + } + + function addFakeRuntimes(win) { + // We use the real runtimes here (and switch out some functionality) + // so we can ensure that logging happens as it would in real use. + + let usb = new _DeprecatedUSBRuntime("fakeUSB"); + // Use local pipe instead + usb.connect = function(connection) { + ok(connection, win.AppManager.connection, "connection is valid"); + connection.host = null; // force connectPipe + connection.connect(); + return promise.resolve(); + }; + win.AppManager.runtimeList.usb.push(usb); + + let wifi = new _WiFiRuntime("fakeWiFi"); + // Use local pipe instead + wifi.connect = function(connection) { + ok(connection, win.AppManager.connection, "connection is valid"); + connection.host = null; // force connectPipe + connection.connect(); + return promise.resolve(); + }; + win.AppManager.runtimeList.wifi.push(wifi); + + let sim = new _SimulatorRuntime("fakeSimulator"); + // Use local pipe instead + sim.connect = function(connection) { + ok(connection, win.AppManager.connection, "connection is valid"); + connection.host = null; // force connectPipe + connection.connect(); + return promise.resolve(); + }; + Object.defineProperty(sim, "name", { + get() { + return this.version; + } + }); + win.AppManager.runtimeList.simulator.push(sim); + + let remote = _gRemoteRuntime; + // Use local pipe instead + remote.connect = function(connection) { + ok(connection, win.AppManager.connection, "connection is valid"); + connection.host = null; // force connectPipe + connection.connect(); + return promise.resolve(); + }; + let local = _gLocalRuntime; + + let other = Object.create(_gLocalRuntime); + other.type = RuntimeTypes.OTHER; + + win.AppManager.runtimeList.other = [remote, local, other]; + + win.AppManager.update("runtimelist"); + } + + function addTestApp(win) { + return Task.spawn(function*() { + let packagedAppLocation = getTestFilePath("app"); + yield win.Cmds.importPackagedApp(packagedAppLocation); + }); + } + + function startConnection(win, type, index) { + let panelNode = win.document.querySelector("#runtime-panel"); + let items = panelNode.querySelectorAll(".runtime-panel-item-" + type); + if (index === undefined) { + is(items.length, 1, "Found one runtime button"); + } + + let deferred = promise.defer(); + win.AppManager.connection.once( + win.Connection.Events.CONNECTED, + () => deferred.resolve()); + + items[index || 0].click(); + + return deferred.promise; + } + + function waitUntilConnected(win) { + return Task.spawn(function*() { + ok(win.document.querySelector("window").className, "busy", "UI is busy"); + yield win.UI._busyPromise; + is(Object.keys(DebuggerServer._connections).length, 1, "Connected"); + }); + } + + function connectToRuntime(win, type, index) { + return Task.spawn(function*() { + startConnection(win, type, index); + yield waitUntilConnected(win); + }); + } + + function checkResults() { + let result = Telemetry.prototype.telemetryInfo; + for (let [histId, value] of Iterator(result)) { + if (histId.endsWith("OPENED_PER_USER_FLAG")) { + ok(value.length === 1 && !!value[0], + "Per user value " + histId + " has a single value of true"); + } else if (histId.endsWith("OPENED_BOOLEAN")) { + ok(value.length > 1, histId + " has more than one entry"); + + let okay = value.every(function(element) { + return !!element; + }); + + ok(okay, "All " + histId + " entries are true"); + } else if (histId.endsWith("TIME_ACTIVE_SECONDS")) { + ok(value.length > 1, histId + " has more than one entry"); + + let okay = value.every(function(element) { + return element > 0; + }); + + ok(okay, "All " + histId + " entries have time > 0"); + } else if (histId === "DEVTOOLS_WEBIDE_CONNECTION_RESULT") { + ok(value.length === 6, histId + " has 6 connection results"); + + let okay = value.every(function(element) { + return !!element; + }); + + ok(okay, "All " + histId + " connections succeeded"); + } else if (histId.endsWith("CONNECTION_RESULT")) { + ok(value.length === 1 && !!value[0], + histId + " has 1 successful connection"); + } else if (histId === "DEVTOOLS_WEBIDE_CONNECTION_TIME_SECONDS") { + ok(value.length === 6, histId + " has 6 connection results"); + + let okay = value.every(function(element) { + return element > 0; + }); + + ok(okay, "All " + histId + " connections have time > 0"); + } else if (histId.endsWith("USED")) { + ok(value.length === 6, histId + " has 6 connection actions"); + + let okay = value.every(function(element) { + return !element; + }); + + ok(okay, "All " + histId + " actions were skipped"); + } else { + ok(false, "Unexpected " + histId + " was logged"); + } + } + } + + window.onload = function() { + SimpleTest.waitForExplicitFinish(); + + let win; + + SimpleTest.registerCleanupFunction(() => { + Task.spawn(function*() { + if (win) { + yield closeWebIDE(win); + } + DebuggerServer.destroy(); + yield removeAllProjects(); + resetTelemetry(); + }); + }); + + Task.spawn(function*() { + Cu.import("resource://gre/modules/devtools/dbg-server.jsm"); + + if (!DebuggerServer.initialized) { + DebuggerServer.init(); + DebuggerServer.addBrowserActors(); + } + + patchTelemetry(); + + // Cycle once, so we can test for multiple opens + yield cycleWebIDE(); + + win = yield openWebIDE(); + // Wait a bit, so we're open for a non-zero time + yield waitForTime(TOOL_DELAY); + addFakeRuntimes(win); + yield addTestApp(win); + + // Each one should log a connection result and non-zero connection + // time + yield connectToRuntime(win, "usb"); + yield waitForTime(TOOL_DELAY); + yield connectToRuntime(win, "wifi"); + yield waitForTime(TOOL_DELAY); + yield connectToRuntime(win, "simulator"); + yield waitForTime(TOOL_DELAY); + yield connectToRuntime(win, "other", 0 /* remote */); + yield waitForTime(TOOL_DELAY); + yield connectToRuntime(win, "other", 1 /* local */); + yield waitForTime(TOOL_DELAY); + yield connectToRuntime(win, "other", 2 /* other */); + yield waitForTime(TOOL_DELAY); + yield closeWebIDE(win); + + checkResults(); + + SimpleTest.finish(); + }); + } + </script> + </body> +</html> diff --git a/toolkit/devtools/webide/test/test_zoom.html b/toolkit/devtools/webide/test/test_zoom.html new file mode 100644 index 000000000..4ad3885d2 --- /dev/null +++ b/toolkit/devtools/webide/test/test_zoom.html @@ -0,0 +1,77 @@ +<!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 viewer = win.QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsIWebNavigation) + .QueryInterface(Ci.nsIDocShell) + .contentViewer; + + win.Cmds.zoomOut(); + win.Cmds.zoomOut(); + win.Cmds.zoomOut(); + win.Cmds.zoomOut(); + win.Cmds.zoomOut(); + win.Cmds.zoomOut(); + win.Cmds.zoomOut(); + + let roundZoom = Math.round(10 * viewer.fullZoom) / 10; + is(roundZoom, 0.6, "Reach min zoom"); + + win.Cmds.zoomIn(); + win.Cmds.zoomIn(); + win.Cmds.zoomIn(); + win.Cmds.zoomIn(); + win.Cmds.zoomIn(); + win.Cmds.zoomIn(); + win.Cmds.zoomIn(); + win.Cmds.zoomIn(); + win.Cmds.zoomIn(); + win.Cmds.zoomIn(); + win.Cmds.zoomIn(); + win.Cmds.zoomIn(); + + roundZoom = Math.round(10 * viewer.fullZoom) / 10; + is(roundZoom, 1.4, "Reach max zoom"); + + yield closeWebIDE(win); + + win = yield openWebIDE(); + viewer = win.QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsIWebNavigation) + .QueryInterface(Ci.nsIDocShell) + .contentViewer; + + roundZoom = Math.round(10 * viewer.fullZoom) / 10; + is(roundZoom, 1.4, "Zoom restored"); + + win.Cmds.resetZoom(); + + is(viewer.fullZoom, 1, "Zoom reset"); + + yield closeWebIDE(win); + + SimpleTest.finish(); + }); + } + </script> + </body> +</html> |