diff options
Diffstat (limited to 'data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/test')
23 files changed, 2060 insertions, 0 deletions
diff --git a/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/test/black.png b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/test/black.png Binary files differnew file mode 100644 index 0000000..ee11b09 --- /dev/null +++ b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/test/black.png diff --git a/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/test/index.html b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/test/index.html new file mode 100644 index 0000000..7e49348 --- /dev/null +++ b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/test/index.html @@ -0,0 +1,4 @@ +<html> + <title></title> + <body></body> +</html> diff --git a/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/test/test-addon-folder.js b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/test/test-addon-folder.js new file mode 100644 index 0000000..4b98c42 --- /dev/null +++ b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/test/test-addon-folder.js @@ -0,0 +1,90 @@ +'use strict'; + +const JETPACK_DIR_BASENAME = "jetpack"; + +const FOLDER = require('pathfinder/addon/folder'); + +const { Loader } = require('sdk/test/loader'); +const { Cc, Ci } = require('chrome'); +const file = require('sdk/io/file'); +const jpSelf = require('sdk/self'); + +let storeFile = Cc['@mozilla.org/file/directory_service;1'] + .getService(Ci.nsIProperties) + .get('ProfD', Ci.nsIFile); +storeFile.append(JETPACK_DIR_BASENAME); +storeFile.append(jpSelf.id); +storeFile.append('addon-folder'); + +const ADDON_FOLDER_PATH = storeFile.path; + +exports.testFolderCreated = function(assert) { + let loader = Loader(module); + assert.ok(file.exists(ADDON_FOLDER_PATH), ADDON_FOLDER_PATH + ' was created'); + FOLDER.destroy(); + assert.ok(!file.exists(ADDON_FOLDER_PATH), ADDON_FOLDER_PATH + ' was destroyed'); + loader.require('pathfinder/addon/folder'); + assert.ok(file.exists(ADDON_FOLDER_PATH), ADDON_FOLDER_PATH + ' was created'); + loader.unload(); + assert.ok(file.exists(ADDON_FOLDER_PATH), ADDON_FOLDER_PATH + 'exists after unload'); +} + +exports.testFileLifecycle = function(assert, done) { + let filename = 'test.json'; + let fileStream = FOLDER.write(filename); + try { + fileStream.writeAsync('{}', function(err) { + assert.equal(FOLDER.exists(filename), true, 'the file was created'); + + if (err) + assert.fail(err); + else + assert.equal(FOLDER.read(filename), '{}', 'the file was written correctly'); + + let entries = FOLDER.list(); + assert.ok(entries.length > 0, 'there is more than one entry'); + for each (let entry in entries) { + assert.equal(entry, filename, filename + ' is the only entry listed'); + } + + let testFile = Cc['@mozilla.org/file/directory_service;1'] + .getService(Ci.nsIProperties) + .get('ProfD', Ci.nsIFile); + testFile.append(JETPACK_DIR_BASENAME); + testFile.append(jpSelf.id); + testFile.append('addon-folder'); + testFile.append(filename); + + assert.ok(testFile.exists(), 'the test file does exist.') + + FOLDER.remove(filename); + + assert.equal(FOLDER.exists(filename), false, 'the file was removed'); + + done(); + }); + } + catch(e) { + assert.fail(e); + fileStream.close(); + done(); + } +} + +exports.testBackPath = function(assert, done) { + let filename = '../../test.json'; + let fileStream = { close: function(){} }; + try { + fileStream = FOLDER.write(filename); + assert.fail(filename + ' should not be useable'); + } + catch(e) { + assert.pass(e); + } + + fileStream.close(); + done(); +} + + +require('sdk/test').run(exports); diff --git a/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/test/test-addon-warning.js b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/test/test-addon-warning.js new file mode 100644 index 0000000..777c279 --- /dev/null +++ b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/test/test-addon-warning.js @@ -0,0 +1,3 @@ +'use strict'; + +const warning = require('pathfinder/ui/warning'); diff --git a/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/test/test-connection-request.js b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/test/test-connection-request.js new file mode 100644 index 0000000..fcd278d --- /dev/null +++ b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/test/test-connection-request.js @@ -0,0 +1,57 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +'use strict'; + +const { Ci } = require('chrome'); +const tabs = require('sdk/tabs'); +const { data } = require('sdk/self'); +const { Loader } = require('sdk/test/loader'); +const httpd = require('sdk/test/httpd'); + +const { RequestRule } = require('pathfinder/connections'); + +exports.testNewHeader = function(assert, done) { + let rule = RequestRule({ + headers: { + 'X-TEST-HEADER': 'TEST' + } + }); + + let serverPort = 8058; + let url = 'http://localhost:' + serverPort + '/test.txt'; + let server = httpd.startServerAsync(serverPort); + const contents = "testNewHeader"; + let requestCount = 0; + + server.registerPathHandler("/test.txt", function handle(request, response) { + requestCount++; + + if (requestCount == 1) { + try { + assert.equal(request.getHeader('X-TEST-HEADER'), 'TEST', 'the new test header value is correct'); + } + catch (e) { + assert.fail(e); + } + rule.destroy(); + } + response.write(contents); + }); + + tabs.open({ + url: url, + onReady: function(tab) { + if (requestCount == 1) { + tab.reload(); + } + else { + server.stop(function() { + done(); + }); + } + } + }) +} + +require('sdk/test').run(exports); diff --git a/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/test/test-content-permissions.js b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/test/test-content-permissions.js new file mode 100644 index 0000000..c9a6da2 --- /dev/null +++ b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/test/test-content-permissions.js @@ -0,0 +1,35 @@ +'use strict'; + +const { permissions } = require('pathfinder/content/permissions'); + +exports.testAddRemovePermission = function(assert) { + permissions.add({ + url: 'http://erikvold.com/', + permission: 'deny', + type: 'images' + }); + + let found = false; + for each (let permission in permissions.permissions) { + if (permission.host == 'erikvold.com') { + found = true; + assert.equal(permission.permission, 'deny'); + assert.equal(permission.type, 'images'); + } + } + assert.ok(found, 'erikvold.com permission was found'); + + permissions.remove({ + url: 'http://erikvold.com/', + type: 'images' + }); + + for each (let permission in permissions.permissions) { + if (permission.host == 'erikvold.com') { + assert.fail('there should not be a permission for erikvold.com'); + } + } + assert.pass('permission was removed!'); +}; + +require('sdk/test').run(exports); diff --git a/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/test/test-content-policy.js b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/test/test-content-policy.js new file mode 100644 index 0000000..5a811df --- /dev/null +++ b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/test/test-content-policy.js @@ -0,0 +1,155 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +'use strict'; + +const { Loader } = require('sdk/test/loader'); +const tabs = require('sdk/tabs'); +const timers = require('sdk/timers'); + +const cp = require('pathfinder/content/policy'); + +exports.testConstants = function(assert) { + assert.ok(cp.REJECT != undefined, 'REJECT constant exists'); + assert.ok(cp.ACCEPT != undefined, 'ACCEPT constant exists'); + assert.ok(cp.ContentPolicy != undefined, 'ContentPolicy constant exists'); +}; + +exports.testContentPolicyDestroy = function(assert, done) { + const loader = Loader(module); + const httpd = loader.require('sdk/test/httpd'); + const { ContentPolicy } = loader.require('pathfinder/content/policy') + const { startServerAsync } = httpd; + const { setTimeout } = timers; + + let tabsCount = tabs.length; + let tab1; + + let serverPort = 8056; + let server = httpd.startServerAsync(serverPort); + const contents = '<!DOCTYPE html><html><head></head><body>testContentPolicyDestroy</body></html>'; + // test.html + let testPageRequests = 0; + server.registerPathHandler('/test.html', function handle(request, response) { + testPageRequests++; + response.write(contents); + }); + + let url = 'http://localhost:' + serverPort + '/test.html'; + let policy = ContentPolicy({ + shouldLoad: function({ location }) { + if (location != url) + return true; + + setTimeout(function() { + policy.destroy(); + + tabs.open({ + url: url, + inBackground: true, + onReady: function (tab2) { + assert.equal(tab2.url, url, url); + tab2.close(function() tab1.close()); + } + }); + assert.pass('tab2 opening..'); + }, 0); + return false; + } + }); + assert.pass('Content policy is setup'); + + setTimeout(function() { + tabs.open({ + url: url, + inBackground: true, + onOpen: function (tab) { + tab1 = tab; + assert.equal(tab1.url, 'about:blank', 'tab1 opened - about:blank'); + }, + onReady: function() { + assert.fail('tab1 loaded..'); + }, + onClose: function() { + assert.equal(testPageRequests, 1, 'test page was only requested once'); + //assert.equal(tabsCount, tabs.length, 'all test tabs are closed'); + loader.unload(); + done(); + } + }); + + assert.pass('tab1 opening..'); + }, 500); +}; + +exports.testContentPolicyUnload = function(assert, done) { + const loader = Loader(module); + const { ContentPolicy } = loader.require('pathfinder/content/policy'); + const { setTimeout } = loader.require('sdk/timers'); + + let tabsCount = tabs.length; + let tab1; + let otherTabs = []; + let calls = 0; + let expectedCalls = 1; + let url = 'data:text/html;charset=utf-8,testContentPolicyUnload'; + let policy = ContentPolicy({ + contract: '@erikvold.com/content-policy.TEST;unload', + shouldLoad: function({ location }) { + if (location != url) + return true; + + calls++; + setTimeout(function() { + loader.unload(); + + assert.pass('tab2 opening..'); + tabs.open({ + url: url, + inBackground: true, + onOpen: function(tab) { + otherTabs.push(tab); + }, + onReady: function (tab2) { + assert.equal(tab2.url, url, url); + expectedCalls = otherTabs.length; + + // close tabs + (function ender() { + if (otherTabs.length <= 0) + return tab1.close(); + otherTabs.pop().close(); + ender(otherTabs); + })() + } + }); + assert.pass('tab2 open called.'); + }, 0); + + return false; + } + }); + assert.pass('Content policy is setup'); + + setTimeout(function() { + assert.pass('tab1 opening..'); + tabs.open({ + url: url, + inBackground: true, + onOpen: function (tab) { + tab1 = tab; + assert.equal(tab1.url, 'about:blank', 'tab1 opened - about:blank'); + }, + onReady: function() { + assert.fail('tab1 loaded..'); + }, + onClose: function() { + assert.equal(calls, expectedCalls, 'content policy only rejected expected number of times'); + //assert.equal(tabsCount, tabs.length, 'all test tabs are closed'); + done(); + } + }); + }, 500); +}; + +require('test').run(exports); diff --git a/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/test/test-download.js b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/test/test-download.js new file mode 100644 index 0000000..30b4b69 --- /dev/null +++ b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/test/test-download.js @@ -0,0 +1,58 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +'use strict'; + +const { Ci, Cc, Cu } = require('chrome'); +const { pathFor } = require("sdk/system"); +const { Loader } = require("sdk/test/loader"); +const { Request } = require('sdk/request'); +const options = require("@test/options"); + +const { Download } = require('pathfinder/download'); + +const { Services } = require('pathfinder/chrome/services'); + +exports.testDownload = function(assert, done) { + const loader = Loader(module); + const httpd = loader.require('sdk/test/httpd'); + + let serverPort = 8057; + let server = httpd.startServerAsync(serverPort); + const contents = "testDownload"; + + server.registerPathHandler("/test.txt", function handle(request, response) { + response.write(contents); + }); + + let file = Services.dirsvc.get("ProfD", Ci.nsIFile); + file.append("test.txt"); + + assert.ok(!file.exists(), 'Download does not exist yet'); + + let download = Download({ + url: "http://localhost:" + serverPort + "/test.txt", + destination: file.path, + onComplete: function() { + assert.ok(file.exists(), 'Download was successful'); + + Request({ + url: Services.io.newFileURI(file).spec, + overrideMimeType: "text/plain; charset=latin1", + onComplete: function ({ text }) { + assert.equal(text, contents, 'the file content is correct'); + file.remove(false); + assert.ok(!file.exists(), 'File was removed'); + + server.stop(function() { + loader.unload(); + done(); + }); + } + }).get(); + } + }); + assert.ok(!!download, 'Download started'); +} + +require('sdk/test').run(exports); diff --git a/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/test/test-find-suggestion.js b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/test/test-find-suggestion.js new file mode 100644 index 0000000..18e3de3 --- /dev/null +++ b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/test/test-find-suggestion.js @@ -0,0 +1,3 @@ +'use strict'; + +require('pathfinder/ui/findbar/suggestion'); diff --git a/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/test/test-listen.js b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/test/test-listen.js new file mode 100644 index 0000000..0967b4f --- /dev/null +++ b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/test/test-listen.js @@ -0,0 +1,152 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +'use strict'; + +const { Loader } = require('sdk/test/loader'); +const { getMostRecentBrowserWindow } = require('sdk/window/utils'); +const { open, close, promise: windowPromise } = require('sdk/window/helpers'); +const NS_XUL = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"; + +const { listen: gListen } = require('pathfinder/xul/listen'); + +// from https://developer.mozilla.org/en-US/docs/Web/API/document.createEvent +function simulateClick(ele) { + let window = ele.ownerDocument.defaultView; + let { document } = window; + var evt = document.createEvent("MouseEvents"); + evt.initMouseEvent("click", true, true, window, + 0, 0, 0, 0, 0, false, false, false, false, 0, null); + ele.dispatchEvent(evt); +} + +function makeEle(window) { + window = window || getMostRecentBrowserWindow(); + let ele = window.document.createElementNS(NS_XUL, 'toolbar'); + return { + window: window, + document: window.document, + ele: ele + } +} + +exports.testSuccessiveListenersCaptureTrue = function(assert, done) { + const loader = Loader(module); + const { listen } = loader.require('pathfinder/xul/listen'); + let { window, document, ele } = makeEle(); + let aHappened = false; + + listen(window, ele, 'click', function() { + aHappened = true; + }, true); + listen(window, ele, 'click', function() { + assert.ok(aHappened, 'the first listener attached was the first called.') + loader.unload(); + done(); + }, true); + + simulateClick(ele); +} + +exports.testSuccessiveListeners = function(assert, done) { + const loader = Loader(module); + const { listen } = loader.require('pathfinder/xul/listen'); + let { window, document, ele } = makeEle(); + let aHappened = false; + + listen(window, ele, 'click', function() { + aHappened = true; + }, false); + listen(window, ele, 'click', function() { + assert.ok(aHappened, 'the first listener attached was the first called.') + loader.unload(); + done(); + }, false); + + simulateClick(ele); +} + +exports.testSuccessiveListenersAcrossLoaders = function(assert, done) { + const loader = Loader(module); + const { listen } = loader.require('pathfinder/xul/listen'); + let { window, document, ele } = makeEle(); + let aHappened = false; + + listen(window, ele, 'click', function() { + aHappened = true; + }, false); + let remover = gListen(window, ele, 'click', function() { + assert.ok(aHappened, 'the first listener attached was the first called.'); + remover(); + loader.unload(); + done(); + }, false); + + simulateClick(ele); +} + +exports.testRemover = function(assert, done) { + const loader = Loader(module); + const { listen } = loader.require('pathfinder/xul/listen'); + let { window, document, ele } = makeEle(); + let aHappened = false; + + let remover1 = listen(window, ele, 'click', function() { + aHappened = true; + }, false); + let remover = gListen(window, ele, 'click', function() { + assert.ok(!aHappened, 'the first listener attached was removed'); + remover(); + loader.unload(); + done(); + }, false); + + remover1(); + simulateClick(ele); +} + +exports.testWindowUnloadEvent = function(assert, done) { + let eHappened = false; + let { window, ele: ele1 } = makeEle(); + let remover2, remover1 = gListen(window, ele1, 'click', function() { + assert.ok(!eHappened, 'listeners are removed when parent window unloads'); + remover1(); + remover2(); + done(); + }); + + open().then(function(window) { + let { document, ele: ele2 } = makeEle(window); + + remover2 = gListen(window, ele2, 'click', function() { + eHappened = true; + }); + + windowPromise(window, 'unload').then(function() { + simulateClick(ele2); + simulateClick(ele1); + }); + close(window); + }); +} + +exports.testListenWorksOnUnload = function(assert, done) { + const loader = Loader(module); + const { listen } = loader.require('pathfinder/xul/listen'); + let { window, document, ele } = makeEle(); + + listen(window, ele, 'click', function() { + assert.fail('should not be here'); + }, false); + + let remover = gListen(window, ele, 'click', function() { + remover(); + assert.pass('ending listen unload test'); + done(); + }, false); + + loader.unload(); + simulateClick(ele); +} + +require('sdk/test').run(exports); diff --git a/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/test/test-menuitems.js b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/test/test-menuitems.js new file mode 100644 index 0000000..db55a36 --- /dev/null +++ b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/test/test-menuitems.js @@ -0,0 +1,169 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +'use strict' + +const windowUtils = require('sdk/deprecated/window-utils'); +const menuitems = require('pathfinder/ui/menuitems'); + +let window = windowUtils.activeBrowserWindow; +let document = window.document; +function $(id) document.getElementById(id); + +function createMI(options, test) { + test.equal(!$(options.id), true); + var mi = new menuitems.Menuitem(options); + return mi; +} + +exports.testMIDoesNotExist = function(assert) { + var options = { + id: "test-mi-dne", + label: "test" + }; + createMI(options, assert); + assert.equal(!!$(options.id), false, 'menuitem does not exists'); +}; + +exports.testMIDoesExist = function(assert) { + var options = { + id: "test-mi-exists", + label: "test", + menuid: 'menu_FilePopup' + }; + let mi = createMI(options, assert); + let menuitem = $(options.id); + assert.equal(!!menuitem, true, 'menuitem exists'); + assert.equal(menuitem.id, options.id, 'menuitem id is ok'); + assert.equal(menuitem.getAttribute('label'), options.label, 'menuitem label is ok'); + assert.equal(menuitem.parentNode.id, options.menuid, 'in the file menu'); + assert.equal(menuitem.getAttribute('disabled'), 'false', 'menuitem not disabled'); + assert.equal(menuitem.getAttribute('accesskey'), '', 'menuitem accesskey is ok'); + assert.equal(menuitem.getAttribute('class'), '', 'menuitem class is ok'); + assert.equal(menuitem.nextSibling, undefined, 'menuitem is last'); + assert.equal(menuitem.hasAttribute("checked"), false, 'menuitem not checked'); + mi.destroy(); + assert.ok(!$(options.id), 'menuitem is gone'); + assert.equal(menuitem.parentNode, null, 'menuitem has no parent'); +}; + +exports.testMIOnClick = function(assert, done) { + let options = { + id: "test-mi-onclick", + label: "test", + menuid: 'menu_FilePopup', + onCommand: function() { + mi.destroy(); + assert.pass('onCommand worked!'); + done(); + } + }; + + let e = document.createEvent("UIEvents"); + e.initUIEvent("command", true, true, window, 1); + + var mi = createMI(options, assert); + let menuitem = $(options.id); + assert.equal(!!menuitem, true, 'menuitem exists'); + menuitem.dispatchEvent(e); +}; + +exports.testMIDisabled = function(assert, done) { + let commandIsOK = false; + let count = 0; + let options = { + id: "test-mi-disabled", + label: "test", + disabled: true, + menuid: 'menu_FilePopup', + onCommand: function() { + count++; + if (!commandIsOK) { + assert.fail('onCommand was called, that is not ok'); + return; + } + + mi.destroy(); + assert.equal(count, 1, 'onCommand was called the correct number of times!'); + done(); + } + }; + + let e = document.createEvent("UIEvents"); + e.initUIEvent("command", true, true, window, 1); + + var mi = createMI(options, assert); + let menuitem = $(options.id); + assert.equal(!!menuitem, true, 'menuitem exists'); + assert.equal(menuitem.getAttribute('disabled'), 'true', 'menuitem not disabled'); + menuitem.dispatchEvent(e); + mi.disabled = false; + assert.equal(menuitem.getAttribute('disabled'), 'false', 'menuitem not disabled'); + commandIsOK = true; + menuitem.dispatchEvent(e); +}; + +exports.testMIChecked = function(assert) { + let options = { + id: "test-mi-checked", + label: "test", + disabled: true, + menuid: 'menu_FilePopup', + checked: true + }; + + let mi = createMI(options, assert); + let menuitem = $(options.id); + assert.equal(!!menuitem, true, 'menuitem exists'); + assert.equal(menuitem.getAttribute("checked"), "true", 'menuitem checked'); + mi.checked = false; + assert.equal(menuitem.getAttribute("checked"), "false", 'menuitem checked'); + mi.destroy(); +}; + +exports.testMIClass = function(assert) { + let options = { + id: "test-mi-class", + label: "pizazz", + className: "pizazz", + menuid: 'menu_FilePopup', + }; + + var mi = createMI(options, assert); + let menuitem = $(options.id); + assert.equal(!!menuitem, true, 'menuitem exists'); + assert.equal(menuitem.getAttribute('class'), 'pizazz', 'menuitem not disabled'); + mi.destroy(); +}; + +exports.testInsertBeforeExists = function(assert) { + let options = { + id: 'test-mi-insertbefore', + label: 'insertbefore', + insertbefore:'menu_FileQuitItem', + menuid: 'menu_FilePopup', + }; + + var mi = createMI(options, assert); + let menuitem = $(options.id); + assert.equal(!!menuitem, true, 'menuitem exists'); + assert.equal(menuitem.nextSibling, $('menu_FileQuitItem'), 'menuitem not disabled'); + mi.destroy(); +}; + +exports.testInsertBeforeDoesNotExist = function(assert) { + let options = { + id: 'test-mi-insertbefore', + label: 'insertbefore', + insertbefore:'menu_ZZZDNE', + menuid: 'menu_FilePopup', + }; + + var mi = createMI(options, assert); + let menuitem = $(options.id); + assert.equal(!!menuitem, true, 'menuitem exists'); + assert.equal(menuitem.nextSibling, null, 'menuitem not disabled'); + mi.destroy(); +}; + +require('sdk/test').run(exports); diff --git a/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/test/test-panic.js b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/test/test-panic.js new file mode 100644 index 0000000..49d3a76 --- /dev/null +++ b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/test/test-panic.js @@ -0,0 +1,103 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +'use strict'; + +const panic = require('pathfinder/panic'); +const prefs = require('sdk/preferences/service'); +const { Loader } = require('sdk/test/loader'); + +const PREF_END_NAME = 'security.addon.panic_end'; + +// TEST: the inPanic variable and panic events +exports.testPanicInPanic = function(assert, done) { + assert.equal(panic.inPanic, false, "not in a panic"); + panic.once('start', function() { + assert.pass('"start" event was fired'); + assert.equal(panic.inPanic, true, "in a panic"); + + panic.once('end', function() { + assert.pass('"end" event was fired'); + assert.equal(panic.inPanic, false, "not in a panic"); + + done(); + }); + }); + + panic.panic(); +}; + +// TEST: on and off methods +exports.testPanicOnOff = function(assert, done) { + let count = 0; + + panic.on('start', function panicOn() { + panic.off('start', panicOn); + count++; + + panic.once('start', function() { + if (count > 1) { + assert.fail('panic.on was called too many times'); + } + else { + assert.pass('panic.on was only called once'); + } + + panic.once('end', function() { + done(); + }); + }); + + panic.once('end', function() { + panic.panic(50); + }); + }); + + panic.panic(); +}; + +// TEST: panic emits in multiple instances +exports.testPanicFiresInMultipleInstances = function(assert, done) { + let count = 0; + + let loader = Loader(module); + let panic2 = loader.require('panic'); + + let testCounter = function() { + if (++count < 2) return; + assert.pass('panic was fired on multiple instances'); + + panic.once('end', function() { + loader.unload(); + done(); + }); + }; + panic.once('start', testCounter); + panic2.once('start', testCounter); + + panic.panic(); +}; + +exports.testEndTimestamp = function(assert, done) { + let ms = 0; + let min = Date.now() + ms; + let endTimestamp; + + panic.once('end', function() { + let now = Date.now(); + let max = (now + ms); + + assert.ok(min <= endTimestamp, endTimestamp + ' is gte ' + min); + assert.ok(min <= now, now + ' event is gte to ' + min); + assert.ok(max >= endTimestamp, 'timestamp is lte to max'); + assert.ok(max >= now, 'end event is lte to max'); + + done(); + }); + + panic.panic(ms); + + endTimestamp = prefs.get(PREF_END_NAME); +}; + +require('sdk/test').run(exports); diff --git a/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/test/test-redirect.js b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/test/test-redirect.js new file mode 100644 index 0000000..071b09d --- /dev/null +++ b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/test/test-redirect.js @@ -0,0 +1,49 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +'use strict'; + +const tabs = require('sdk/tabs'); +const { data } = require('sdk/self'); +const { Loader } = require("sdk/test/loader"); + +const { Redirect } = require('pathfinder/redirect'); + +function getData(url) { + return 'data:text/javascript;charset=utf-8,' + encodeURIComponent(url); +} + +exports.testRedirect = function(assert, done) { + const loader = Loader(module); + const httpd = loader.require('sdk/test/httpd'); + const { startServerAsync } = httpd; + + let serverPort = 8058; + let server = httpd.startServerAsync(serverPort); + const contents = "testRedirect"; + + server.registerPathHandler("/test.txt", function handle(request, response) { + response.write(contents); + }); + + let details = { + from: 'http://localhost:' + serverPort + '/test.txt', + to: getData('exptected') + }; + let redirect = Redirect(JSON.parse(JSON.stringify(details))); + + tabs.open({ + url: details.from, + onReady: function(tab) { + assert.equal(tab.url, details.to, 'The final destination is correct!'); + redirect.destroy(); + + server.stop(function() { + loader.unload(); + tab.close(done); + }); + } + }); +} + +require('sdk/test').run(exports); diff --git a/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/test/test-scheme-about.js b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/test/test-scheme-about.js new file mode 100644 index 0000000..5d7873f --- /dev/null +++ b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/test/test-scheme-about.js @@ -0,0 +1,43 @@ +'use strict'; + +const { Loader } = require('sdk/test/loader'); +const tabs = require('sdk/tabs') + +function openTabGetContent(url, callback) { + tabs.open({ + url: 'about:test', + inBackground: true, + onReady: function(tab) { + let worker = tab.attach({ + contentScript: 'self.port.emit("body", document.body.innerHTML)' + }) + worker.port.on('body', function(msg) { + tab.close(function() { + callback(msg); + }); + }); + } + }) +} + +exports.testAddAboutWhat = function(assert, done) { + const loader = Loader(module); + const { add } = loader.require('pathfinder/scheme/about'); + + add({ + what: 'test', + url: 'data:text/html;charset=utf-8,<body>test</body>' + }); + + openTabGetContent('about:test', function(msg) { + assert.equal(msg, 'test', 'about:test content is "test"'); + loader.unload(); + openTabGetContent('about:test', function(msg) { + assert.notEqual(msg, 'test', 'about:test content is "test"'); + done(); + }); + }); + +} + +require('test').run(exports); diff --git a/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/test/test-scheme-resource.js b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/test/test-scheme-resource.js new file mode 100644 index 0000000..da6fd3b --- /dev/null +++ b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/test/test-scheme-resource.js @@ -0,0 +1,3 @@ +'use strict'; + +require('pathfinder/scheme/resource'); diff --git a/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/test/test-storage.js b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/test/test-storage.js new file mode 100644 index 0000000..14187cd --- /dev/null +++ b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/test/test-storage.js @@ -0,0 +1,134 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +'use strict'; + +const { Loader } = require('sdk/test/loader'); +const { before, after } = require('sdk/test/utils'); + +const { get, set } = require('pathfinder/storage'); + +exports.testGetNothing = function(assert, done) { + get().then(function({ data }) { + assert.equal(data, '', 'the data is blank!'); + done(); + }); +}; + +exports.testSetThenGet = function(assert, done) { + const randomData = Math.random() + ''; + + // SET TO A RANDOM VALUE + set({ data: randomData }).then(function({ data }) { + assert.pass('setting was successful'); + assert.equal(data, randomData, 'the data returned from set is correct [' + randomData + ']'); + }, function(e) { + assert.fail('setting was unsuccessful'); + assert.fail(e); + }).then(function() get()).then(function({ data }) { + assert.pass('getting was successful'); + assert.equal(data, randomData, 'the data returned from get is correct [' + randomData + ']'); + }, function(e) { + assert.fail('getting was unsuccessful'); + assert.fail(e); + }) + // SET AGAIN + .then(function() set({ data: 'test' })).then(function({ data }) { + assert.pass('setting was successful'); + assert.equal(data, 'test', 'the data returned from set is correct [test]'); + }, function(e) { + assert.fail('setting was unsuccessful'); + assert.fail(e); + }).then(function() get()).then(function({ data }) { + assert.pass('getting was successful'); + assert.equal(data, 'test', 'the data returned from get is correct [test]'); + }, function(e) { + assert.fail('getting was unsuccessful'); + assert.fail(e); + }). + // SET TO BLANK + then(function() set({ data: '' })).then(function({ data }) { + assert.pass('setting was successful'); + assert.equal(data, '', 'the data returned from set is correct'); + }, function(e) { + assert.fail('setting was unsuccessful'); + assert.fail(e); + }).then(function() get()).then(function({ data }) { + assert.pass('getting was successful'); + assert.equal(data, '', 'the data returned from get is correct'); + }, function(e) { + assert.fail('getting was unsuccessful'); + assert.fail(e); + }). + // SET TO BLANK AGAIN + then(function() set({ data: '' })).then(function({ data }) { + assert.pass('setting was successful'); + assert.equal(data, '', 'the data returned from set is correct'); + }, function(e) { + assert.fail('setting was unsuccessful'); + assert.fail(e); + }).then(function() get()).then(function({ data }) { + assert.pass('getting was successful'); + assert.equal(data, '', 'the data returned from get is correct'); + }, function(e) { + assert.fail('getting was unsuccessful'); + assert.fail(e); + }).then(done, assert.fail); +}; + +exports.testSettingJSON = function(assert, done) { + const json = JSON.stringify({ + num: 1, + str: 'string', + bool: true, + obj: { x: 'x' }, + ary: [ 1, 2, 3 ] + }); + + set({ data: json }).then(function({ data }) { + assert.pass('setting was successful'); + assert.equal(data, json, 'the data returned from set is correct json'); + }, function(e) { + assert.fail('setting was unsuccessful'); + assert.fail(e); + }).then(function() get()).then(function({ data }) { + assert.pass('getting was successful'); + assert.equal(data, json, 'the data returned from get is correct json'); + }, function(e) { + assert.fail('getting was unsuccessful'); + assert.fail(e); + }). + // SET TO BLANK AGAIN + then(function() set({ data: '' })).then(function({ data }) { + assert.pass('setting was successful'); + assert.equal(data, '', 'the data returned from set is correct'); + }, function(e) { + assert.fail('setting was unsuccessful'); + assert.fail(e); + }).then(function() get()).then(function({ data }) { + assert.pass('getting was successful'); + assert.equal(data, '', 'the data returned from get is correct'); + }, function(e) { + assert.fail('getting was unsuccessful'); + assert.fail(e); + }).then(done, assert.fail); +}; + +before(exports, function(name, assert, done) { + let loader = Loader(module); + loader.require('pathfinder/storage'); + let file = loader.sandbox('pathfinder/storage').getStorageFile(); + assert.pass(file.exists(), false, 'the storage file DNE'); + loader.unload(); + done(); +}); +after(exports, function(name, assert, done) { + let loader = Loader(module); + loader.require('pathfinder/storage'); + let file = loader.sandbox('pathfinder/storage').getStorageFile(); + assert.pass(file.exists(), false, 'the storage file DNE'); + loader.unload(); + done(); +}); + +require('sdk/test').run(exports); diff --git a/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/test/test-toolbarbutton.js b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/test/test-toolbarbutton.js new file mode 100644 index 0000000..1cfb269 --- /dev/null +++ b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/test/test-toolbarbutton.js @@ -0,0 +1,165 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +'use strict'; + +const windows = require("sdk/windows").browserWindows; +const toolbarbutton = require("pathfinder/ui/toolbarbutton"); +//const { Loader } = require('sdk/test/loader'); +const winUtils = require('sdk/window/utils'); + +const NS_XUL = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"; + +const TEST_ICON_URL = module.uri.replace(/[^\.\\\/]*\.js$/, "test.png"); +const TEST_ICON_BLACK_URL = module.uri.replace(/[^\.\\\/]*\.js$/, "black.png"); + +function $(id) winUtils.getMostRecentBrowserWindow().document.getElementById(id); + +function createToolbarButton(options, test) { + test.assertEqual(!$(options.id), true); + + var tbb = toolbarbutton.ToolbarButton(options); + test.assertEqual(!$(options.id), true); + + tbb.moveTo(options); + if (options.toolbarID) + test.assertEqual(!$(options.id), false); + + return tbb; +} + +function buttonExists(button, options, test) { + test.assertEqual(!button, false, 'test button'); + test.assertEqual(button.parentNode, $(options.toolbarID), 'test parent'); + test.assertEqual(button.id, options.id, 'test id'); + if (options.label) + test.assertEqual(button.label, options.label, 'test label'); + if (options.image) + test.assertEqual(button.image, options.image); + else + test.assertEqual(button.image, ""); +} + +exports.testTBBExists = function(test) { + var options = { + id: "test-tbb", + label: "test", + toolbarID: "nav-bar", + forceMove: true + }; + + var tbb = createToolbarButton(options, test); + buttonExists($(options.id), options, test); + tbb.destroy(); + test.assertEqual(!$(options.id), true); + var tbb = createToolbarButton(options, test); + tbb.destroy(); +}; + +exports.testTBBDoesNotExist = function(test) { + var options = { + id: "test-tbb2", + label: "test" + }; + var tbb = createToolbarButton(options, test); + var tbbEle = $(options.id); + test.assertEqual(!tbbEle, true, 'toolbar button dne'); + tbb.destroy(); +}; + +exports.testTBBLabelChange = function(test) { + test.waitUntilDone(); + + var options = { + id: "test-tbb3", + label: "test", + toolbarID: "nav-bar", + forceMove: true + }; + + let tbb = createToolbarButton(options, test); + buttonExists($(options.id), options, test); + tbb.label = 'test change'; + test.assertEqual($(options.id).label, 'test change', 'the label is changed'); + test.assertEqual(tbb.label, 'test change', 'the label is changed'); + + tbb.destroy(); + test.done(); +}; + +exports.testTBBPropertyChange = function(test) { + test.waitUntilDone(); + + var options = { + id: "test-tbb4", + label: "test", + toolbarID: "nav-bar", + forceMove: true, + image: TEST_ICON_URL, + tooltiptext: 'a' + }; + + let tbb = createToolbarButton(options, test); + buttonExists($(options.id), options, test); + test.assertEqual($(options.id).image, TEST_ICON_URL, 'the image is correct'); + test.assertEqual(tbb.image, TEST_ICON_URL, 'the image is correct'); + test.assertEqual(tbb.tooltiptext, 'a', 'the tooltiptext is correct'); + tbb.setIcon({url: TEST_ICON_BLACK_URL}); + test.assertEqual($(options.id).image, TEST_ICON_BLACK_URL, 'the image is changed'); + test.assertEqual(tbb.image, TEST_ICON_BLACK_URL, 'the image is changed'); + tbb.tooltiptext = 'b'; + test.assertEqual($(options.id).getAttribute('tooltiptext'), 'b', 'the tooltiptext is changed'); + test.assertEqual(tbb.tooltiptext, 'b', 'the tooltiptext is changed'); + + tbb.destroy(); + test.done(); +}; + +exports.testTBBIteratorWithNonBrowserWindow = function(test) { + test.waitUntilDone(); + + let scratchpad = winUtils.getMostRecentBrowserWindow().Scratchpad.openScratchpad(); + let options = { + id: "test-tbb5", + label: "TEST", + toolbarID: "nav-bar", + image: TEST_ICON_URL + }; + windows.open({ + onOpen: function(window) { + let tbb = createToolbarButton(options, test); + test.assertEqual(windows.length, 2); + + scratchpad.close(); + tbb.destroy(); + window.close(function() test.done()); + } + }) +}; + +exports.testTBBIterator2 = function(test) { + test.waitUntilDone(); + + let window1 = winUtils.getMostRecentBrowserWindow(); + let options = { + id: "test-tbb6", + label: "TEST", + toolbarID: "nav-bar", + image: TEST_ICON_URL + }; + let button = window1.document.createElementNS(NS_XUL, "toolbarbutton"); + button.setAttribute('id', options.id); + window1.document.getElementById(options.toolbarID).appendChild(button); + test.assert(!!$(options.id)); + + windows.open({ + onOpen: function(window) { + let tbb = createToolbarButton(options, test); + test.assertEqual(windows.length, 2); + + tbb.destroy(); + button.parentNode.removeChild(button); + window.close(function() test.done()); + } + }) +}; diff --git a/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/test/test-unload+.js b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/test/test-unload+.js new file mode 100644 index 0000000..edb9dff --- /dev/null +++ b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/test/test-unload+.js @@ -0,0 +1,150 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +'use strict'; + +var timer = require("sdk/timers"); +var { Cc,Ci } = require("chrome"); +const windowUtils = require("sdk/deprecated/window-utils"); +const { Loader } = require('sdk/test/loader'); + +function makeEmptyWindow() { + var xulNs = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"; + var blankXul = ('<?xml version="1.0"?>' + + '<?xml-stylesheet href="chrome://global/skin/" ' + + ' type="text/css"?>' + + '<window xmlns="' + xulNs + '">' + + '</window>'); + var url = "data:application/vnd.mozilla.xul+xml," + escape(blankXul); + var features = ["chrome", "width=10", "height=10"]; + + var ww = Cc["@mozilla.org/embedcomp/window-watcher;1"] + .getService(Ci.nsIWindowWatcher); + return ww.openWindow(null, url, null, features.join(","), null); +} + +exports.testUnloading = function(assert) { + var loader = Loader(module); + var {unload} = loader.require("pathfinder/addon/unload"); + var unloadCalled = 0; + + function unloader() { + unloadCalled++; + } + unload(unloader); + + function unloader2() unloadCalled++; + var removeUnloader2 = unload(unloader2); + + function unloader3() unloadCalled++; + unload(unloader3); + + // remove unloader2 + removeUnloader2(); + + loader.unload(); + + assert.equal(unloadCalled, 2, "Unloader functions are called on unload."); +}; + +exports.testUnloadingWindow = function(assert, done) { + var loader = Loader(module); + var {unload} = loader.require("pathfinder/addon/unload"); + var unloadCalled = 0; + var finished = false; + var myWindow; + + var delegate = { + onTrack: function(window) { + if (window == myWindow) { + assert.pass("onTrack() called with our test window"); + + let unloader = function unloader() { + unloadCalled++; + } + unload(unloader, window); + unload(unloader); + + timer.setTimeout(function() { + window.close(); + + assert.equal(unloadCalled, 1, "unloader was still called."); + + if (window.closed) { + assert.pass("window closed"); + } + else { + assert.fail("window is not closed!"); + } + + timer.setTimeout(function() { + assert.equal(unloadCalled, 1, "unloader was called."); + + unload(function() { + assert.equal(unloadCalled, 2, "two unloaders called."); + + if (finished) { + assert.pass("finished"); + done(); + } + else { + assert.fail("not finished!"); + } + }); + + loader.unload(); + }, 1); + }, 1); + } + }, + onUntrack: function(window) { + if (window == myWindow) { + assert.pass("onUntrack() called with our test window"); + + if (!finished) { + finished = true; + myWindow = null; + wt.unload(); + } + else { + assert.fail("finishTest() called multiple times."); + } + } + } + }; + + var wt = new windowUtils.WindowTracker(delegate); + myWindow = makeEmptyWindow(); +}; + +exports.testUnloaderExecutionOnWindowClose = function(assert, done) { + var loader = Loader(module); + var {unload} = loader.require("pathfinder/addon/unload"); + var unloadCalled = 0; + var finished = false; + var myWindow; + var unloaderRan = false; + + var delegate = { + onTrack: function(window) { + if (window != myWindow) return; + + unload(function() unloaderRan = true, window); + window.close(); + }, + onUntrack: function(window) { + if (window != myWindow) return; + + loader.require('sdk/timers').setTimeout(function() { + assert.ok(unloaderRan, 'test complete'); + loader.unload(); + done(); + }, 0); + } + }; + + var wt = new windowUtils.WindowTracker(delegate); + myWindow = makeEmptyWindow(); +}; + +require('sdk/test').run(exports); diff --git a/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/test/test-userscripts.js b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/test/test-userscripts.js new file mode 100644 index 0000000..e43199c --- /dev/null +++ b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/test/test-userscripts.js @@ -0,0 +1,8 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +'use strict'; + + + +require('sdk/test').run(exports); diff --git a/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/test/test-userstyles.css b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/test/test-userstyles.css new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/test/test-userstyles.css diff --git a/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/test/test-userstyles.js b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/test/test-userstyles.js new file mode 100644 index 0000000..50b741e --- /dev/null +++ b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/test/test-userstyles.js @@ -0,0 +1,116 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +'use strict'; + +const { Loader } = require('sdk/test/loader'); + +const userstyles = require('userstyles'); + +const TEST_CSS_URL = module.uri.replace(/\.js$/, '.css'); +const TEST_FNF_URL = module.uri.replace(/\.js$/, '.x.css'); + +// TEST: userstyles.load +exports.testLoad = function(assert) { + assert.equal(userstyles.registered(TEST_CSS_URL), false, 'css is unregistered.'); + + userstyles.load(TEST_CSS_URL); + assert.ok(userstyles.registered(TEST_CSS_URL), 'css was registered.'); + + userstyles.unload(TEST_CSS_URL); + assert.equal(userstyles.registered(TEST_CSS_URL), false, 'css was unregistered.'); +}; + +// TEST: userstyles.load file not found +exports.testLoadFNF = function(assert) { + assert.equal(userstyles.registered(TEST_CSS_URL), false, 'css is not registered.'); + + try { + userstyles.load(TEST_FNF_URL); + assert.fail('trying to load a file that does not exist should throw an error'); + } + catch(e) { + assert.pass('trying to load a file that does not exist throws an error'); + } + + assert.equal(userstyles.registered(TEST_CSS_URL), false, 'css was not registered.'); +}; + +// TEST: userstyles.load for 'agent' type +exports.testLoadAgent = function(assert) { + assert.equal(userstyles.registered(TEST_CSS_URL), false, 'css is not registered.'); + assert.equal(userstyles.registered(TEST_CSS_URL, {type: 'agent'}), false, 'css is not registered.'); + + userstyles.load(TEST_CSS_URL, {type: 'AgeNt'}); + assert.ok(userstyles.registered(TEST_CSS_URL, {type: 'AGENT'}), 'css was registered.'); + + try { + userstyles.unload(TEST_CSS_URL); + assert.fail('unregister did not throw an error'); + } + catch(e) { + assert.pass('unregister did throw an error'); + } + assert.equal(userstyles.registered(TEST_CSS_URL, {type: 'agent'}), true, 'css was not unregistered.'); + + userstyles.unload(TEST_CSS_URL, {type: 'agent'}); + assert.equal(userstyles.registered(TEST_CSS_URL, {type: 'agent'}), false, 'css was unregistered.'); +}; + +exports.testUnload = function(assert) { + assert.equal(userstyles.registered(TEST_CSS_URL), false, 'css is unregistered.'); + let loader = Loader(module); + + loader.require('userstyles').load(TEST_CSS_URL); + assert.ok(userstyles.registered(TEST_CSS_URL), 'css was registered.'); + + loader.unload(); + assert.equal(userstyles.registered(TEST_CSS_URL), false, 'css was unregistered.'); +} + +exports.testUnloadWithMultipleLoads = function(assert) { + assert.equal(userstyles.registered(TEST_CSS_URL), false, 'css is unregistered.'); + let loader = Loader(module); + + // first load + loader.require('userstyles').load(TEST_CSS_URL); + assert.ok(userstyles.registered(TEST_CSS_URL), 'css was registered.'); + + // now unload + loader.require('userstyles').unload(TEST_CSS_URL); + assert.equal(userstyles.registered(TEST_CSS_URL), false, 'css is unregistered.'); + + // now load again + loader.require('userstyles').load(TEST_CSS_URL); + assert.ok(userstyles.registered(TEST_CSS_URL), 'css was registered.'); + + // send addon unload message and see if we fail + loader.unload(); + assert.equal(userstyles.registered(TEST_CSS_URL), false, 'css is unregistered.'); +} + +exports.testUnloadWithMultipleLoaders = function(assert) { + assert.equal(userstyles.registered(TEST_CSS_URL), false, 'css is unregistered.'); + let loader = Loader(module); + + // first load + loader.require('userstyles').load(TEST_CSS_URL); + assert.ok(userstyles.registered(TEST_CSS_URL), 'css was registered.'); + + // now unload + loader.require('userstyles').unload(TEST_CSS_URL); + assert.equal(userstyles.registered(TEST_CSS_URL), false, 'css is unregistered.'); + + // now load again + userstyles.load(TEST_CSS_URL); + assert.ok(userstyles.registered(TEST_CSS_URL), 'css was registered.'); + + // send addon unload message and see if we fail + loader.unload(); + assert.equal(userstyles.registered(TEST_CSS_URL), true, 'css is still registered.'); + + userstyles.unload(TEST_CSS_URL); + assert.equal(userstyles.registered(TEST_CSS_URL), false, 'css was unregistered.'); +} + +require('sdk/test').run(exports); diff --git a/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/test/test-web-panel.js b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/test/test-web-panel.js new file mode 100644 index 0000000..e97779a --- /dev/null +++ b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/test/test-web-panel.js @@ -0,0 +1,563 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +'use strict'; + +const { Loader } = require('sdk/test/loader'); +const { getMostRecentBrowserWindow } = require('sdk/window/utils'); +const { open, close, focus, promise: windowPromise } = require('sdk/window/helpers'); +const { setTimeout } = require('sdk/timers'); +const { isPrivate } = require('sdk/private-browsing'); +const { data } = require('sdk/self'); +const { fromIterator } = require('sdk/util/array'); +const { URL } = require('sdk/url'); + +const { WebPanel } = require('pathfinder/ui/web-panel'); +const { show, hide } = require('pathfinder/ui/sidebar/actions'); +const { isShowing } = require('pathfinder/ui/sidebar/state'); + +const BUILTIN_SIDEBAR_MENUITEMS = [ + 'menu_socialSidebar', + 'menu_historySidebar', + 'menu_bookmarksSidebar' +]; + +const WEB_PANEL_BROWSER_ID = 'web-panels-browser'; + +function isSidebarShowing(window) { + window = window || getMostRecentBrowserWindow(); + let sidebar = window.document.getElementById('sidebar-box'); + return !sidebar.hidden; +} + +function getSidebarMenuitems(window) { + window = window || getMostRecentBrowserWindow(); + return fromIterator(window.document.querySelectorAll('#viewSidebarMenu menuitem')); +} + +function getExtraSidebarMenuitems() { + let menuitems = getSidebarMenuitems(); + return menuitems.filter(function(mi) { + return BUILTIN_SIDEBAR_MENUITEMS.indexOf(mi.getAttribute('id')) < 0; + }); +} + +function makeID(id) { + return 'pathfinder-sidebar-' + id; +} + +function simulateClick(ele) { + let window = ele.ownerDocument.defaultView; + let { document } = window; + var evt = document.createEvent("XULCommandEvent"); + evt.initCommandEvent("command", true, true, window, + 0, false, false, false, false, null); + ele.dispatchEvent(evt); +} + +exports.testSidebarBasicLifeCycle = function(assert, done) { + let testName = 'testSidebarBasicLifeCycle'; + let window = getMostRecentBrowserWindow(); + assert.ok(!window.document.getElementById(makeID(testName)), 'sidebar id DNE'); + let sidebarXUL = window.document.getElementById('sidebar'); + assert.ok(sidebarXUL, 'sidebar xul element does exist'); + assert.ok(!getExtraSidebarMenuitems().length, 'there are no extra sidebar menuitems'); + + assert.equal(isSidebarShowing(window), false, 'sidebar is not showing 1'); + let sidebarDetails = { + id: testName, + title: 'test', + url: 'data:text/html;charset=utf-8,'+testName + }; + let sidebar = WebPanel(sidebarDetails); + + // test the sidebar attributes + for each(let key in Object.keys(sidebarDetails)) { + assert.equal(sidebarDetails[key], sidebar[key], 'the attributes match the input'); + } + + assert.pass('The Sidebar constructor worked'); + + let extraMenuitems = getExtraSidebarMenuitems(); + assert.equal(extraMenuitems.length, 1, 'there is one extra sidebar menuitems'); + + let ele = window.document.getElementById(makeID(testName)); + assert.equal(ele, extraMenuitems[0], 'the only extra menuitem is the one for our sidebar.') + assert.ok(ele, 'sidebar element was added'); + assert.ok(ele.getAttribute('checked'), 'false', 'the sidebar is not displayed'); + assert.equal(ele.getAttribute('label'), sidebar.title, 'the sidebar title is the menuitem label') + + assert.equal(isSidebarShowing(window), false, 'sidebar is not showing 2'); + sidebar.on('show', function() { + assert.pass('the show event was fired'); + assert.equal(isSidebarShowing(window), true, 'sidebar is not showing 3'); + assert.equal(isShowing(sidebar), true, 'the sidebar is showing'); + assert.equal(ele.getAttribute('checked'), 'true', 'the sidebar is displayed'); + + sidebar.once('hide', function() { + assert.pass('the hide event was fired'); + assert.equal(ele.getAttribute('checked'), 'false', 'the sidebar menuitem is not checked'); + assert.equal(isShowing(sidebar), false, 'the sidebar is not showing'); + assert.equal(isSidebarShowing(window), false, 'the sidebar elemnt is hidden'); + + sidebar.once('detach', function() { + sidebar.destroy(); + + let sidebarMI = getSidebarMenuitems(); + for each (let mi in sidebarMI) { + assert.ok(BUILTIN_SIDEBAR_MENUITEMS.indexOf(mi.getAttribute('id')) >= 0, 'the menuitem is for a built-in sidebar') + assert.equal(mi.getAttribute('checked'), "false", 'no sidebar menuitem is checked'); + } + + assert.ok(!window.document.getElementById(makeID(testName)), 'sidebar id DNE'); + assert.pass('calling destroy worked without error'); + + done(); + }); + }); + + sidebar.hide(); + assert.pass('hiding sidebar..'); + }); + + sidebar.show(); + assert.pass('showing sidebar..'); +} + +exports.testSideBarIsInNewWindows = function(assert, done) { + let testName = 'testSideBarOnNewWindow'; + let sidebar = WebPanel({ + id: testName, + title: testName, + url: 'data:text/html;charset=utf-8,'+testName + }); + + let startWindow = getMostRecentBrowserWindow(); + let ele = startWindow.document.getElementById(makeID(testName)); + assert.ok(ele, 'sidebar element was added'); + + open().then(function(window) { + let ele = window.document.getElementById(makeID(testName)); + assert.ok(ele, 'sidebar element was added'); + + sidebar.destroy(); + assert.ok(!window.document.getElementById(makeID(testName)), 'sidebar id DNE'); + assert.ok(!startWindow.document.getElementById(makeID(testName)), 'sidebar id DNE'); + + close(window).then(done, assert.fail); + }) +} + +exports.testSideBarIsNotInNewPrivateWindows = function(assert, done) { + let testName = 'testSideBarOnNewWindow'; + let sidebar = WebPanel({ + id: testName, + title: testName, + url: 'data:text/html;charset=utf-8,'+testName + }); + + let startWindow = getMostRecentBrowserWindow(); + let ele = startWindow.document.getElementById(makeID(testName)); + assert.ok(ele, 'sidebar element was added'); + + open(null, { features: { private: true } }).then(function(window) { + let ele = window.document.getElementById(makeID(testName)); + assert.ok(isPrivate(window), 'the new window is private'); + assert.equal(ele, null, 'sidebar element was not added'); + + sidebar.destroy(); + assert.ok(!window.document.getElementById(makeID(testName)), 'sidebar id DNE'); + assert.ok(!startWindow.document.getElementById(makeID(testName)), 'sidebar id DNE'); + + close(window).then(done, assert.fail); + }) +} + +exports.testSideBarIsShowingInNewWindows = function(assert, done) { + let testName = 'testSideBarIsShowingInNewWindows'; + let sidebar = WebPanel({ + id: testName, + title: testName, + url: URL('data:text/html;charset=utf-8,'+testName) + }); + + let startWindow = getMostRecentBrowserWindow(); + let ele = startWindow.document.getElementById(makeID(testName)); + assert.ok(ele, 'sidebar element was added'); + + let oldEle = ele; + sidebar.once('show', function() { + assert.pass('show event fired'); + + sidebar.once('attach', function() { + assert.pass('attach event fired'); + + sidebar.once('show', function() { + let window = getMostRecentBrowserWindow(); + assert.notEqual(startWindow, window, 'window is new'); + + let sb = window.document.getElementById('sidebar'); + if (sb && sb.docShell && sb.contentDocument && sb.contentDocument.getElementById('web-panels-browser')) { + end(); + } + else { + sb.addEventListener('DOMWindowCreated', end, false); + } + + function end() { + sb.removeEventListener('DOMWindowCreated', end, false); + let webPanelBrowser = sb.contentDocument.getElementById('web-panels-browser'); + + let ele = window.document.getElementById(makeID(testName)); + + assert.ok(ele, 'sidebar element was added 2'); + assert.equal(ele.getAttribute('checked'), 'true', 'the sidebar is checked'); + assert.notEqual(ele, oldEle, 'there are two different sidebars'); + + assert.equal(isShowing(sidebar), true, 'the sidebar is showing in new window'); + + webPanelBrowser.contentWindow.addEventListener('load', function onload() { + webPanelBrowser.contentWindow.addEventListener('load', onload, false); + + sidebar.destroy(); + + assert.equal(isShowing(sidebar), false, 'the sidebar is not showing'); + assert.ok(!isSidebarShowing(window), 'sidebar in most recent window is not showing'); + assert.ok(!isSidebarShowing(startWindow), 'sidebar in most start window is not showing'); + assert.ok(!window.document.getElementById(makeID(testName)), 'sidebar id DNE'); + assert.ok(!startWindow.document.getElementById(makeID(testName)), 'sidebar id DNE'); + + setTimeout(function() { + close(window).then(done, assert.fail); + }); + }, false); + } + }); + + startWindow.OpenBrowserWindow(); + }); + }); + + show(sidebar); + assert.pass('showing the sidebar'); +} + +exports.testShowingOneSidebarAfterAnother = function(assert, done) { + let testName = 'testShowingOneSidebarAfterAnother'; + + let sidebar1 = WebPanel({ + id: testName + '1', + title: testName + '1', + url: 'data:text/html;charset=utf-8,'+ testName + 1 + }); + let sidebar2 = WebPanel({ + id: testName + '2', + title: testName + '2', + url: 'data:text/html;charset=utf-8,'+ testName + 2 + }); + + let window = getMostRecentBrowserWindow(); + let IDs = [ sidebar1.id, sidebar2.id ]; + + let extraMenuitems = getExtraSidebarMenuitems(window); + assert.equal(extraMenuitems.length, 2, 'there are two extra sidebar menuitems'); + + function testShowing(sb1, sb2, sbEle) { + assert.equal(isShowing(sidebar1), sb1); + assert.equal(isShowing(sidebar2), sb2); + assert.equal(isSidebarShowing(window), sbEle); + } + testShowing(false, false, false); + + sidebar1.once('show', function() { + testShowing(true, false, true); + for each (let mi in getExtraSidebarMenuitems(window)) { + let menuitemID = mi.getAttribute('id').replace(/^pathfinder-sidebar-/, ''); + assert.ok(IDs.indexOf(menuitemID) >= 0, 'the extra menuitem is for one of our test sidebars'); + assert.equal(mi.getAttribute('checked'), menuitemID == sidebar1.id ? 'true' : 'false', 'the test sidebar menuitem has the correct checked value'); + } + + sidebar2.once('show', function() { + testShowing(false, true, true); + for each (let mi in getExtraSidebarMenuitems(window)) { + let menuitemID = mi.getAttribute('id').replace(/^pathfinder-sidebar-/, ''); + assert.ok(IDs.indexOf(menuitemID) >= 0, 'the extra menuitem is for one of our test sidebars'); + assert.equal(mi.getAttribute('checked'), menuitemID == sidebar2.id ? 'true' : 'false', 'the test sidebar menuitem has the correct checked value'); + } + + sidebar1.destroy(); + sidebar2.destroy(); + + testShowing(false, false, false); + + done(); + }); + + show(sidebar2); + assert.pass('showing sidebar 2'); + }) + show(sidebar1); + assert.pass('showing sidebar 1'); +} + +exports.testSidebarUnload = function(assert, done) { + let loader = Loader(module); + + let testName = 'testSidebarUnload'; + let window = getMostRecentBrowserWindow(); + + assert.equal(isPrivate(window), false, 'the current window is not private'); + + let sidebar = loader.require('pathfinder/ui/web-panel').WebPanel({ + id: testName, + title: testName, + url: 'data:text/html;charset=utf-8,'+ testName, + onShow: function() { + assert.pass('onShow works for Sidebar'); + loader.unload(); + + let sidebarMI = getSidebarMenuitems(); + for each (let mi in sidebarMI) { + assert.ok(BUILTIN_SIDEBAR_MENUITEMS.indexOf(mi.getAttribute('id')) >= 0, 'the menuitem is for a built-in sidebar') + assert.equal(mi.getAttribute('checked'), 'false', 'no sidebar menuitem is checked'); + } + assert.ok(!window.document.getElementById(makeID(testName)), 'sidebar id DNE'); + assert.equal(isSidebarShowing(window), false, 'the sidebar is not showing'); + + done(); + } + }) + + sidebar.show(); + assert.pass('showing the sidebar'); +} + +exports.testRemoteContent = function(assert) { + let testName = 'testRemoteContent'; + try { + let sidebar = WebPanel({ + id: testName, + title: testName, + url: 'http://dne.xyz.mozilla.org' + }); + assert.ok('the web panel was created!'); + sidebar.destroy(); + } + catch(e) { + assert.fail('sidebar was not created..'); + } +} + +exports.testInvalidURL = function(assert) { + let testName = 'testInvalidURL'; + try { + let sidebar = WebPanel({ + id: testName, + title: testName, + url: 'http:mozilla.org' + }); + assert.pass('remote uris are fine'); + sidebar.destroy(); + } + catch(e) { + assert.ok(/The option "url" must be a valid URI./.test(e), 'invalid URIs are not acceptable'); + } +} + +exports.testInvalidURLType = function(assert) { + let testName = 'testInvalidURLType'; + try { + let sidebar = WebPanel({ + id: testName, + title: testName + }); + assert.fail('a bad sidebar was created..'); + sidebar.destroy(); + } + catch(e) { + assert.ok(/The option "url" must be a valid URI./.test(e), 'invalid URIs are not acceptable'); + } +} + +exports.testInvalidTitle = function(assert) { + let testName = 'testInvalidTitle'; + try { + let sidebar = WebPanel({ + id: testName, + title: '', + url: 'data:text/html;charset=utf-8,'+testName + }); + assert.fail('a bad sidebar was created..'); + sidebar.destroy(); + } + catch(e) { + assert.equal('The option "title" must be one of the following types: string', e.message, 'invalid titles are not acceptable'); + } +} + +exports.testInvalidID = function(assert) { + let testName = 'testInvalidTitle'; + try { + let sidebar = WebPanel({ + id: '!', + title: testName, + url: 'data:text/html;charset=utf-8,'+testName + }); + assert.fail('a bad sidebar was created..'); + sidebar.destroy(); + } + catch(e) { + assert.ok(/The option "id" must be a valid alphanumeric id/.test(e), 'invalid ids are not acceptable'); + } +} + +exports.testSidebarIsNotOpenInNewPrivateWindow = function(assert, done) { + let testName = 'testSidebarIsNotOpenInNewPrivateWindow'; + let window = getMostRecentBrowserWindow(); + + let sidebar = WebPanel({ + id: testName, + title: testName, + url: 'data:text/html;charset=utf-8,'+testName + }); + + sidebar.on('show', function() { + assert.equal(isPrivate(window), false, 'the new window is not private'); + assert.equal(isSidebarShowing(window), true, 'the sidebar is showing'); + assert.equal(isShowing(sidebar), true, 'the sidebar is showing'); + + let window2 = window.OpenBrowserWindow({private: true}); + windowPromise(window2, 'load').then(focus).then(function() { + // TODO: find better alt to setTimeout... + setTimeout(function() { + assert.equal(isPrivate(window2), true, 'the new window is private'); + assert.equal(isSidebarShowing(window), true, 'the sidebar is showing in old window still'); + assert.equal(isSidebarShowing(window2), false, 'the sidebar is not showing in the new private window'); + assert.equal(isShowing(sidebar), false, 'the sidebar is not showing'); + sidebar.destroy(); + close(window2).then(done); + }, 500) + }) + }); + + sidebar.show(); +} + +// TEST: edge case where web panel is destroyed while loading +exports.testDestroyEdgeCaseBug = function(assert, done) { + let testName = 'testDestroyEdgeCaseBug'; + let window = getMostRecentBrowserWindow(); + let sidebar = WebPanel({ + id: testName, + title: testName, + url: 'data:text/html;charset=utf-8,'+testName + }); + + // NOTE: purposely not listening to show event b/c the event happens + // between now and then. + sidebar.show(); + + assert.equal(isPrivate(window), false, 'the new window is not private'); + assert.equal(isSidebarShowing(window), true, 'the sidebar is showing'); + + //assert.equal(isShowing(sidebar), true, 'the sidebar is showing'); + + open(null, { features: { private: true } }).then(focus).then(function(window2) { + assert.equal(isPrivate(window2), true, 'the new window is private'); + assert.equal(isSidebarShowing(window2), false, 'the sidebar is not showing'); + assert.equal(isShowing(sidebar), false, 'the sidebar is not showing'); + + sidebar.destroy(); + assert.pass('destroying the sidebar'); + + close(window2).then(function() focus(window)).then(function(window) { + let loader = Loader(module); + + assert.equal(window, getMostRecentBrowserWindow(), 'window is current window'); + assert.equal(isPrivate(window), false, 'the current window is not private!'); + + let sidebar = loader.require('pathfinder/ui/web-panel').WebPanel({ + id: testName, + title: testName, + url: 'data:text/html;charset=utf-8,'+ testName, + onShow: function() { + assert.pass('onShow works for Sidebar'); + loader.unload(); + + let sidebarMI = getSidebarMenuitems(); + for each (let mi in sidebarMI) { + assert.ok(BUILTIN_SIDEBAR_MENUITEMS.indexOf(mi.getAttribute('id')) >= 0, 'the menuitem is for a built-in sidebar') + assert.equal(mi.getAttribute('checked'), 'false', 'no sidebar menuitem is checked'); + } + assert.ok(!window.document.getElementById(makeID(testName)), 'sidebar id DNE'); + assert.equal(isSidebarShowing(window), false, 'the sidebar is not showing'); + + done(); + } + }) + + assert.pass('showing the sidebar1'); + sidebar.show(); + assert.pass('showing the sidebar2'); + + }); + }); +} + +exports.testClickingACheckedMenuitem = function(assert, done) { + let testName = 'testClickingACheckedMenuitem'; + let window = getMostRecentBrowserWindow(); + let sidebar = WebPanel({ + id: testName, + title: testName, + url: 'data:text/html;charset=utf-8,'+testName, + onShow: function() { + sidebar.once('hide', function() { + assert.pass('clicking the menuitem after the sidebar has shown hides it.'); + sidebar.destroy(); + done(); + }); + let menuitem = window.document.getElementById(makeID(sidebar.id)); + simulateClick(menuitem); + } + }); + + sidebar.show(); +} + +exports.testAddonGlobalDNE = function(assert, done) { + let testName = 'testAddonGlobal'; + let url = 'data:text/html;charset=utf-8,'+encodeURIComponent('<script>window.addEventListener("message", function() window.postMessage({ addon: !!window.addon }, "*"), false)</script>'); + let sidebar = WebPanel({ + id: testName, + title: testName, + url: url + }); + + sidebar.on('attach', function(worker) { + assert.pass('sidebar was attached'); + assert.ok(!!worker, 'attach event has worker'); + + let sidebarXUL = getMostRecentBrowserWindow().document.getElementById('sidebar'); + let window = sidebarXUL.contentDocument.getElementById(WEB_PANEL_BROWSER_ID).contentWindow; + + window.addEventListener('load', function() { + let count = 0; + window.addEventListener('message', function({ data: msg }) { + if (++count != 2) return; + + assert.equal(msg.addon, false, 'the addon global DNE'); + + sidebar.destroy(); + + done(); + }, false); + window.postMessage('', '*'); + }, false); + + }); + + show(sidebar); +} + +require('sdk/test').run(exports); diff --git a/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/test/test.png b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/test/test.png Binary files differnew file mode 100644 index 0000000..5469a50 --- /dev/null +++ b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/test/test.png |