diff options
Diffstat (limited to 'addon-sdk/source/test/tabs/test-firefox-tabs.js')
-rw-r--r-- | addon-sdk/source/test/tabs/test-firefox-tabs.js | 1305 |
1 files changed, 0 insertions, 1305 deletions
diff --git a/addon-sdk/source/test/tabs/test-firefox-tabs.js b/addon-sdk/source/test/tabs/test-firefox-tabs.js deleted file mode 100644 index 368ed02ba..000000000 --- a/addon-sdk/source/test/tabs/test-firefox-tabs.js +++ /dev/null @@ -1,1305 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -'use strict'; - -const { Cc, Ci } = require('chrome'); -const { Loader } = require('sdk/test/loader'); -const systemEvents = require("sdk/system/events"); -const { setTimeout, setImmediate } = require('sdk/timers'); -const { modelFor } = require('sdk/model/core'); -const { viewFor } = require('sdk/view/core'); -const { getOwnerWindow } = require('sdk/tabs/utils'); -const { windows, onFocus, getMostRecentBrowserWindow } = require('sdk/window/utils'); -const { open, focus, close } = require('sdk/window/helpers'); -const { observer: windowObserver } = require("sdk/windows/observer"); -const tabs = require('sdk/tabs'); -const { browserWindows } = require('sdk/windows'); -const { set: setPref, get: getPref, reset: resetPref } = require("sdk/preferences/service"); -const DEPRECATE_PREF = "devtools.errorconsole.deprecation_warnings"; -const OPEN_IN_NEW_WINDOW_PREF = 'browser.link.open_newwindow'; -const DISABLE_POPUP_PREF = 'dom.disable_open_during_load'; -const fixtures = require("../fixtures"); -const { base64jpeg } = fixtures; -const { cleanUI, before, after } = require("sdk/test/utils"); -const { wait } = require('../event/helpers'); - -// Bug 682681 - tab.title should never be empty -exports.testBug682681_aboutURI = function(assert, done) { - let url = 'chrome://browser/locale/tabbrowser.properties'; - let stringBundle = Cc["@mozilla.org/intl/stringbundle;1"]. - getService(Ci.nsIStringBundleService). - createBundle(url); - let emptyTabTitle = stringBundle.GetStringFromName('tabs.emptyTabTitle'); - - tabs.on('ready', function onReady(tab) { - tabs.removeListener('ready', onReady); - - assert.equal(tab.title, - emptyTabTitle, - "title of about: tab is not blank"); - - tab.close(done); - }); - - // open a about: url - tabs.open({ - url: "about:blank", - inBackground: true - }); -}; - -// related to Bug 682681 -exports.testTitleForDataURI = function(assert, done) { - tabs.open({ - url: "data:text/html;charset=utf-8,<title>tab</title>", - inBackground: true, - onReady: function(tab) { - assert.equal(tab.title, "tab", "data: title is not Connecting..."); - tab.close(done); - } - }); -}; - -// TEST: 'BrowserWindow' instance creation on tab 'activate' event -// See bug 648244: there was a infinite loop. -exports.testBrowserWindowCreationOnActivate = function(assert, done) { - let windows = require("sdk/windows").browserWindows; - let gotActivate = false; - - tabs.once('activate', function onActivate(eventTab) { - assert.ok(windows.activeWindow, "Is able to fetch activeWindow"); - gotActivate = true; - }); - - open().then(function(window) { - assert.ok(gotActivate, "Received activate event"); - return close(window); - }).then(done).then(null, assert.fail); -} - -// TEST: tab unloader -exports.testAutomaticDestroyEventOpen = function(assert, done) { - let called = false; - let loader = Loader(module); - let tabs2 = loader.require("sdk/tabs"); - tabs2.on('open', _ => called = true); - - // Fire a tab event and ensure that the destroyed tab is inactive - tabs.once('open', tab => { - setTimeout(_ => { - assert.ok(!called, "Unloaded tab module is destroyed and inactive"); - tab.close(done); - }); - }); - - loader.unload(); - tabs.open("data:text/html;charset=utf-8,testAutomaticDestroyEventOpen"); -}; - -exports.testAutomaticDestroyEventActivate = function(assert, done) { - let called = false; - let loader = Loader(module); - let tabs2 = loader.require("sdk/tabs"); - tabs2.on('activate', _ => called = true); - - // Fire a tab event and ensure that the destroyed tab is inactive - tabs.once('activate', tab => { - setTimeout(_ => { - assert.ok(!called, "Unloaded tab module is destroyed and inactive"); - tab.close(done); - }); - }); - - loader.unload(); - tabs.open("data:text/html;charset=utf-8,testAutomaticDestroyEventActivate"); -}; - -exports.testAutomaticDestroyEventDeactivate = function(assert, done) { - let called = false; - let currentTab = tabs.activeTab; - let loader = Loader(module); - let tabs2 = loader.require("sdk/tabs"); - - tabs.open({ - url: "data:text/html;charset=utf-8,testAutomaticDestroyEventDeactivate", - onActivate: _ => setTimeout(_ => { - tabs2.on('deactivate', _ => called = true); - - // Fire a tab event and ensure that the destroyed tab is inactive - tabs.once('deactivate', tab => { - setTimeout(_ => { - assert.ok(!called, "Unloaded tab module is destroyed and inactive"); - tab.close(done); - }); - }); - - loader.unload(); - currentTab.activate(); - }) - }); -}; - -exports.testAutomaticDestroyEventClose = function(assert, done) { - let called = false; - let loader = Loader(module); - let tabs2 = loader.require("sdk/tabs"); - - tabs.open({ - url: "data:text/html;charset=utf-8,testAutomaticDestroyEventClose", - onReady: tab => { - tabs2.on('close', _ => called = true); - - // Fire a tab event and ensure that the destroyed tab is inactive - tabs.once('close', tab => { - setTimeout(_ => { - assert.ok(!called, "Unloaded tab module is destroyed and inactive"); - done(); - }); - }); - - loader.unload(); - tab.close(); - } - }); -}; - -exports.testTabPropertiesInNewWindow = function(assert, done) { - const { LoaderWithFilteredConsole } = require("sdk/test/loader"); - let loader = LoaderWithFilteredConsole(module, function(type, message) { - return true; - }); - - let tabs = loader.require('sdk/tabs'); - let { viewFor } = loader.require('sdk/view/core'); - - let count = 0; - function onReadyOrLoad (tab) { - if (count++) { - close(getOwnerWindow(viewFor(tab))).then(done).then(null, assert.fail); - } - } - - let url = "data:text/html;charset=utf-8,<html><head><title>foo</title></head><body>foo</body></html>"; - tabs.open({ - inNewWindow: true, - url: url, - onReady: function(tab) { - assert.equal(tab.title, "foo", "title of the new tab matches"); - assert.equal(tab.url, url, "URL of the new tab matches"); - assert.equal(tab.favicon, undefined, "favicon of the new tab is undefined"); - assert.equal(tab.style, null, "style of the new tab matches"); - assert.equal(tab.index, 0, "index of the new tab matches"); - assert.notEqual(tab.getThumbnail(), null, "thumbnail of the new tab matches"); - assert.notEqual(tab.id, null, "a tab object always has an id property."); - - onReadyOrLoad(tab); - }, - onLoad: function(tab) { - assert.equal(tab.title, "foo", "title of the new tab matches"); - assert.equal(tab.url, url, "URL of the new tab matches"); - assert.equal(tab.favicon, undefined, "favicon of the new tab is undefined"); - assert.equal(tab.style, null, "style of the new tab matches"); - assert.equal(tab.index, 0, "index of the new tab matches"); - assert.notEqual(tab.getThumbnail(), null, "thumbnail of the new tab matches"); - assert.notEqual(tab.id, null, "a tab object always has an id property."); - - onReadyOrLoad(tab); - } - }); -}; - -exports.testTabPropertiesInSameWindow = function(assert, done) { - const { LoaderWithFilteredConsole } = require("sdk/test/loader"); - let loader = LoaderWithFilteredConsole(module, function(type, message) { - return true; - }); - - let tabs = loader.require('sdk/tabs'); - - // Get current count of tabs so we know the index of the - // new tab, bug 893846 - let tabCount = tabs.length; - let count = 0; - function onReadyOrLoad (tab) { - if (count++) { - tab.close(done); - } - } - - let url = "data:text/html;charset=utf-8,<html><head><title>foo</title></head><body>foo</body></html>"; - tabs.open({ - url: url, - onReady: function(tab) { - assert.equal(tab.title, "foo", "title of the new tab matches"); - assert.equal(tab.url, url, "URL of the new tab matches"); - assert.equal(tab.favicon, undefined, "favicon of the new tab is undefined"); - assert.equal(tab.style, null, "style of the new tab matches"); - assert.equal(tab.index, tabCount, "index of the new tab matches"); - assert.notEqual(tab.getThumbnail(), null, "thumbnail of the new tab matches"); - assert.notEqual(tab.id, null, "a tab object always has an id property."); - - onReadyOrLoad(tab); - }, - onLoad: function(tab) { - assert.equal(tab.title, "foo", "title of the new tab matches"); - assert.equal(tab.url, url, "URL of the new tab matches"); - assert.equal(tab.favicon, undefined, "favicon of the new tab is undefined"); - assert.equal(tab.style, null, "style of the new tab matches"); - assert.equal(tab.index, tabCount, "index of the new tab matches"); - assert.notEqual(tab.getThumbnail(), null, "thumbnail of the new tab matches"); - assert.notEqual(tab.id, null, "a tab object always has an id property."); - - onReadyOrLoad(tab); - } - }); -}; - -// TEST: tab properties -exports.testTabContentTypeAndReload = function(assert, done) { - open().then(focus).then(function(window) { - let url = "data:text/html;charset=utf-8,<html><head><title>foo</title></head><body>foo</body></html>"; - let urlXML = "data:text/xml;charset=utf-8,<foo>bar</foo>"; - tabs.open({ - url: url, - onReady: function(tab) { - if (tab.url === url) { - assert.equal(tab.contentType, "text/html"); - tab.url = urlXML; - } - else { - assert.equal(tab.contentType, "text/xml"); - close(window).then(done).then(null, assert.fail); - } - } - }); - }); -}; - -// TEST: tabs iterator and length property -exports.testTabsIteratorAndLength = function(assert, done) { - open(null, { features: { chrome: true, toolbar: true } }).then(focus).then(function(window) { - let startCount = 0; - for (let t of tabs) startCount++; - assert.equal(startCount, tabs.length, "length property is correct"); - let url = "data:text/html;charset=utf-8,default"; - - tabs.open(url); - tabs.open(url); - tabs.open({ - url: url, - onOpen: function(tab) { - let count = 0; - for (let t of tabs) count++; - assert.equal(count, startCount + 3, "iterated tab count matches"); - assert.equal(startCount + 3, tabs.length, "iterated tab count matches length property"); - - close(window).then(done).then(null, assert.fail); - } - }); - }); -}; - -// TEST: tab.url setter -exports.testTabLocation = function(assert, done) { - open().then(focus).then(function(window) { - let url1 = "data:text/html;charset=utf-8,foo"; - let url2 = "data:text/html;charset=utf-8,bar"; - - tabs.on('ready', function onReady(tab) { - if (tab.url != url2) - return; - tabs.removeListener('ready', onReady); - assert.pass("tab.load() loaded the correct url"); - close(window).then(done).then(null, assert.fail); - }); - - tabs.open({ - url: url1, - onOpen: function(tab) { - tab.url = url2 - } - }); - }); -}; - -// TEST: tab.close() -exports.testTabClose = function(assert, done) { - let testName = "testTabClose"; - let url = "data:text/html;charset=utf-8," + testName; - - assert.notEqual(tabs.activeTab.url, url, "tab is not the active tab"); - tabs.once('ready', function onReady(tab) { - assert.equal(tabs.activeTab.url, tab.url, "tab is now the active tab"); - assert.equal(url, tab.url, "tab url is the test url"); - let secondOnCloseCalled = false; - - // Bug 699450: Multiple calls to tab.close should not throw - tab.close(() => secondOnCloseCalled = true); - try { - tab.close(function () { - assert.notEqual(tabs.activeTab.url, url, "tab is no longer the active tab"); - assert.ok(secondOnCloseCalled, - "The immediate second call to tab.close happened"); - assert.notEqual(tabs.activeTab.url, url, "tab is no longer the active tab"); - - done(); - }); - } - catch(e) { - assert.fail("second call to tab.close() thrown an exception: " + e); - } - }); - - tabs.open(url); -}; - -// TEST: tab.move() -exports.testTabMove = function(assert, done) { - open().then(focus).then(function(window) { - let url = "data:text/html;charset=utf-8,foo"; - - tabs.open({ - url: url, - onOpen: function(tab) { - assert.equal(tab.index, 1, "tab index before move matches"); - tab.index = 0; - assert.equal(tab.index, 0, "tab index after move matches"); - close(window).then(done).then(null, assert.fail); - } - }); - }).then(null, assert.fail); -}; - -exports.testIgnoreClosing = function*(assert) { - let url = "data:text/html;charset=utf-8,foobar"; - let originalWindow = getMostRecentBrowserWindow(); - - let window = yield open().then(focus); - - assert.equal(tabs.length, 2, "should be two windows open each with one tab"); - - yield new Promise(resolve => { - tabs.once("ready", (tab) => { - let win = tab.window; - assert.equal(win.tabs.length, 2, "should be two tabs in the new window"); - assert.equal(tabs.length, 3, "should be three tabs in total"); - - tab.close(() => { - assert.equal(win.tabs.length, 1, "should be one tab in the new window"); - assert.equal(tabs.length, 2, "should be two tabs in total"); - resolve(); - }); - }); - - tabs.open(url); - }); -}; - -// TEST: open tab with default options -exports.testOpen = function(assert, done) { - let url = "data:text/html;charset=utf-8,default"; - tabs.open({ - url: url, - onReady: function(tab) { - assert.equal(tab.url, url, "URL of the new tab matches"); - assert.equal(tab.isPinned, false, "The new tab is not pinned"); - - tab.close(done); - } - }); -}; - -// TEST: opening a pinned tab -exports.testOpenPinned = function(assert, done) { - let url = "data:text/html;charset=utf-8,default"; - tabs.open({ - url: url, - isPinned: true, - onOpen: function(tab) { - assert.equal(tab.isPinned, true, "The new tab is pinned"); - tab.close(done); - } - }); -}; - -// TEST: pin/unpin opened tab -exports.testPinUnpin = function(assert, done) { - let url = "data:text/html;charset=utf-8,default"; - tabs.open({ - url: url, - inBackground: true, - onOpen: function(tab) { - tab.pin(); - assert.equal(tab.isPinned, true, "The tab was pinned correctly"); - tab.unpin(); - assert.equal(tab.isPinned, false, "The tab was unpinned correctly"); - tab.close(done); - } - }); -} - -// TEST: open tab in background -exports.testInBackground = function(assert, done) { - assert.equal(tabs.length, 1, "Should be one tab"); - - let window = getMostRecentBrowserWindow(); - let activeUrl = tabs.activeTab.url; - let url = "data:text/html;charset=utf-8,background"; - assert.equal(getMostRecentBrowserWindow(), window, "getMostRecentBrowserWindow() matches this window"); - tabs.on('ready', function onReady(tab) { - tabs.removeListener('ready', onReady); - assert.equal(tabs.activeTab.url, activeUrl, "URL of active tab has not changed"); - assert.equal(tab.url, url, "URL of the new background tab matches"); - assert.equal(getMostRecentBrowserWindow(), window, "a new window was not opened"); - assert.notEqual(tabs.activeTab.url, url, "URL of active tab is not the new URL"); - tab.close(done); - }); - - tabs.open({ - url: url, - inBackground: true - }); -} - -// TEST: open tab in new window -exports.testOpenInNewWindow = function(assert, done) { - let startWindowCount = windows().length; - - let url = "data:text/html;charset=utf-8,testOpenInNewWindow"; - tabs.open({ - url: url, - inNewWindow: true, - onReady: function(tab) { - let newWindow = getOwnerWindow(viewFor(tab)); - assert.equal(windows().length, startWindowCount + 1, "a new window was opened"); - - onFocus(newWindow).then(function() { - assert.equal(getMostRecentBrowserWindow(), newWindow, "new window is active"); - assert.equal(tab.url, url, "URL of the new tab matches"); - assert.equal(newWindow.content.location, url, "URL of new tab in new window matches"); - assert.equal(tabs.activeTab.url, url, "URL of activeTab matches"); - - return close(newWindow).then(done); - }).then(null, assert.fail); - } - }); - -} - -// Test tab.open inNewWindow + onOpen combination -exports.testOpenInNewWindowOnOpen = function(assert, done) { - let startWindowCount = windows().length; - - let url = "data:text/html;charset=utf-8,newwindow"; - tabs.open({ - url: url, - inNewWindow: true, - onOpen: function(tab) { - let newWindow = getOwnerWindow(viewFor(tab)); - - onFocus(newWindow).then(function() { - assert.equal(windows().length, startWindowCount + 1, "a new window was opened"); - assert.equal(getMostRecentBrowserWindow(), newWindow, "new window is active"); - - close(newWindow).then(done).then(null, assert.fail); - }); - } - }); -}; - -// TEST: onOpen event handler -exports.testTabsEvent_onOpen = function(assert, done) { - open().then(focus).then(window => { - let url = "data:text/html;charset=utf-8,1"; - let eventCount = 0; - - // add listener via property assignment - function listener1(tab) { - eventCount++; - }; - tabs.on('open', listener1); - - // add listener via collection add - tabs.on('open', function listener2(tab) { - assert.equal(++eventCount, 2, "both listeners notified"); - tabs.removeListener('open', listener1); - tabs.removeListener('open', listener2); - close(window).then(done).then(null, assert.fail); - }); - - tabs.open(url); - }).then(null, assert.fail); -}; - -// TEST: onClose event handler -exports.testTabsEvent_onClose = function*(assert) { - let window = yield open().then(focus); - let url = "data:text/html;charset=utf-8,onclose"; - let eventCount = 0; - - // add listener via property assignment - function listener1(tab) { - eventCount++; - } - tabs.on("close", listener1); - - yield new Promise(resolve => { - // add listener via collection add - tabs.on("close", function listener2(tab) { - assert.equal(++eventCount, 2, "both listeners notified"); - tabs.removeListener("close", listener2); - resolve(); - }); - - tabs.on('ready', function onReady(tab) { - tabs.removeListener('ready', onReady); - tab.close(); - }); - - tabs.open(url); - }); - - tabs.removeListener("close", listener1); - assert.pass("done test!"); - - yield close(window); - assert.pass("window was closed!"); -}; - -// TEST: onClose event handler when a window is closed -exports.testTabsEvent_onCloseWindow = function(assert, done) { - let closeCount = 0; - let individualCloseCount = 0; - - open().then(focus).then(window => { - assert.pass('opened a new window'); - - tabs.on("close", function listener() { - if (++closeCount == 4) { - tabs.removeListener("close", listener); - } - }); - - function endTest() { - if (++individualCloseCount < 3) { - assert.pass('tab closed ' + individualCloseCount); - return; - } - - assert.equal(closeCount, 4, "Correct number of close events received"); - assert.equal(individualCloseCount, 3, - "Each tab with an attached onClose listener received a close " + - "event when the window was closed"); - - done(); - } - - // One tab is already open with the window - let openTabs = 1; - function testCasePossiblyLoaded() { - if (++openTabs == 4) { - window.close(); - } - assert.pass('tab opened ' + openTabs); - } - - tabs.open({ - url: "data:text/html;charset=utf-8,tab2", - onOpen: testCasePossiblyLoaded, - onClose: endTest - }); - - tabs.open({ - url: "data:text/html;charset=utf-8,tab3", - onOpen: testCasePossiblyLoaded, - onClose: endTest - }); - - tabs.open({ - url: "data:text/html;charset=utf-8,tab4", - onOpen: testCasePossiblyLoaded, - onClose: endTest - }); - }).then(null, assert.fail); -} - -// TEST: onReady event handler -exports.testTabsEvent_onReady = function(assert, done) { - open().then(focus).then(window => { - let url = "data:text/html;charset=utf-8,onready"; - let eventCount = 0; - - // add listener via property assignment - function listener1(tab) { - eventCount++; - }; - tabs.on('ready', listener1); - - // add listener via collection add - tabs.on('ready', function listener2(tab) { - assert.equal(++eventCount, 2, "both listeners notified"); - tabs.removeListener('ready', listener1); - tabs.removeListener('ready', listener2); - close(window).then(done); - }); - - tabs.open(url); - }).then(null, assert.fail); -}; - -// TEST: onActivate event handler -exports.testTabsEvent_onActivate = function(assert, done) { - open().then(focus).then(window => { - let url = "data:text/html;charset=utf-8,onactivate"; - let eventCount = 0; - - // add listener via property assignment - function listener1(tab) { - eventCount++; - }; - tabs.on('activate', listener1); - - // add listener via collection add - tabs.on('activate', function listener2(tab) { - assert.equal(++eventCount, 2, "both listeners notified"); - tabs.removeListener('activate', listener1); - tabs.removeListener('activate', listener2); - close(window).then(done).then(null, assert.fail); - }); - - tabs.open(url); - }).then(null, assert.fail); -}; - -// onDeactivate event handler -exports.testTabsEvent_onDeactivate = function*(assert) { - let window = yield open().then(focus); - - let url = "data:text/html;charset=utf-8,ondeactivate"; - let eventCount = 0; - - // add listener via property assignment - function listener1(tab) { - eventCount++; - assert.pass("listener1 was called " + eventCount); - }; - tabs.on('deactivate', listener1); - - yield new Promise(resolve => { - // add listener via collection add - tabs.on('deactivate', function listener2(tab) { - assert.equal(++eventCount, 2, "both listeners notified"); - tabs.removeListener('deactivate', listener2); - resolve(); - }); - - tabs.on('open', function onOpen(tab) { - assert.pass("tab opened"); - tabs.removeListener('open', onOpen); - tabs.open("data:text/html;charset=utf-8,foo"); - }); - - tabs.open(url); - }); - - tabs.removeListener('deactivate', listener1); - assert.pass("listeners were removed"); -}; - -// pinning -exports.testTabsEvent_pinning = function(assert, done) { - open().then(focus).then(window => { - let url = "data:text/html;charset=utf-8,1"; - - tabs.on('open', function onOpen(tab) { - tabs.removeListener('open', onOpen); - tab.pin(); - }); - - tabs.on('pinned', function onPinned(tab) { - tabs.removeListener('pinned', onPinned); - assert.ok(tab.isPinned, "notified tab is pinned"); - tab.unpin(); - }); - - tabs.on('unpinned', function onUnpinned(tab) { - tabs.removeListener('unpinned', onUnpinned); - assert.ok(!tab.isPinned, "notified tab is not pinned"); - close(window).then(done).then(null, assert.fail); - }); - - tabs.open(url); - }).then(null, assert.fail); -}; - -// TEST: per-tab event handlers -exports.testPerTabEvents = function*(assert) { - let window = yield open().then(focus); - let eventCount = 0; - - let tab = yield new Promise(resolve => { - tabs.open({ - url: "data:text/html;charset=utf-8,foo", - onOpen: (tab) => { - assert.pass("the tab was opened"); - - // add listener via property assignment - function listener1() { - eventCount++; - }; - tab.on('ready', listener1); - - // add listener via collection add - tab.on('ready', function listener2() { - assert.equal(eventCount, 1, "listener1 called before listener2"); - tab.removeListener('ready', listener1); - tab.removeListener('ready', listener2); - assert.pass("removed listeners"); - eventCount++; - resolve(); - }); - } - }); - }); - - assert.equal(eventCount, 2, "both listeners were notified."); -}; - -exports.testAttachOnMultipleDocuments = function (assert, done) { - // Example of attach that process multiple tab documents - open().then(focus).then(window => { - let firstLocation = "data:text/html;charset=utf-8,foobar"; - let secondLocation = "data:text/html;charset=utf-8,bar"; - let thirdLocation = "data:text/html;charset=utf-8,fox"; - let onReadyCount = 0; - let worker1 = null; - let worker2 = null; - let detachEventCount = 0; - - tabs.open({ - url: firstLocation, - onReady: function (tab) { - onReadyCount++; - if (onReadyCount == 1) { - worker1 = tab.attach({ - contentScript: 'self.on("message", ' + - ' function () { return self.postMessage(document.location.href); }' + - ');', - onMessage: function (msg) { - assert.equal(msg, firstLocation, - "Worker url is equal to the 1st document"); - tab.url = secondLocation; - }, - onDetach: function () { - detachEventCount++; - assert.pass("Got worker1 detach event"); - assert.throws(function () { - worker1.postMessage("ex-1"); - }, - /Couldn't find the worker/, - "postMessage throw because worker1 is destroyed"); - checkEnd(); - } - }); - worker1.postMessage("new-doc-1"); - } - else if (onReadyCount == 2) { - - worker2 = tab.attach({ - contentScript: 'self.on("message", ' + - ' function () { return self.postMessage(document.location.href); }' + - ');', - onMessage: function (msg) { - assert.equal(msg, secondLocation, - "Worker url is equal to the 2nd document"); - tab.url = thirdLocation; - }, - onDetach: function () { - detachEventCount++; - assert.pass("Got worker2 detach event"); - assert.throws(function () { - worker2.postMessage("ex-2"); - }, - /Couldn't find the worker/, - "postMessage throw because worker2 is destroyed"); - checkEnd(); - } - }); - worker2.postMessage("new-doc-2"); - } - else if (onReadyCount == 3) { - tab.close(); - } - } - }); - - function checkEnd() { - if (detachEventCount != 2) - return; - - assert.pass("Got all detach events"); - - close(window).then(done).then(null, assert.fail); - } - }).then(null, assert.fail); -} - - -exports.testAttachWrappers = function (assert, done) { - // Check that content script has access to wrapped values by default - open().then(focus).then(window => { - let document = "data:text/html;charset=utf-8,<script>var globalJSVar = true; " + - " document.getElementById = 3;</script>"; - let count = 0; - - tabs.open({ - url: document, - onReady: function (tab) { - let worker = tab.attach({ - contentScript: 'try {' + - ' self.postMessage(!("globalJSVar" in window));' + - ' self.postMessage(typeof window.globalJSVar == "undefined");' + - '} catch(e) {' + - ' self.postMessage(e.message);' + - '}', - onMessage: function (msg) { - assert.equal(msg, true, "Worker has wrapped objects ("+count+")"); - if (count++ == 1) - close(window).then(done).then(null, assert.fail); - } - }); - } - }); - }).then(null, assert.fail); -} - -/* -// We do not offer unwrapped access to DOM since bug 601295 landed -// See 660780 to track progress of unwrap feature -exports.testAttachUnwrapped = function (assert, done) { - // Check that content script has access to unwrapped values through unsafeWindow - openBrowserWindow(function(window, browser) { - let document = "data:text/html;charset=utf-8,<script>var globalJSVar=true;</script>"; - let count = 0; - - tabs.open({ - url: document, - onReady: function (tab) { - let worker = tab.attach({ - contentScript: 'try {' + - ' self.postMessage(unsafeWindow.globalJSVar);' + - '} catch(e) {' + - ' self.postMessage(e.message);' + - '}', - onMessage: function (msg) { - assert.equal(msg, true, "Worker has access to javascript content globals ("+count+")"); - close(window).then(done); - } - }); - } - }); - - }); -} -*/ - -exports['test window focus changes active tab'] = function(assert, done) { - let url1 = "data:text/html;charset=utf-8," + encodeURIComponent("test window focus changes active tab</br><h1>Window #1"); - - let win1 = openBrowserWindow(function() { - assert.pass("window 1 is open"); - - let win2 = openBrowserWindow(function() { - assert.pass("window 2 is open"); - - focus(win2).then(function() { - tabs.on("activate", function onActivate(tab) { - tabs.removeListener("activate", onActivate); - - if (tab.readyState === 'uninitialized') { - tab.once('ready', whenReady); - } - else { - whenReady(tab); - } - - function whenReady(tab) { - assert.pass("activate was called on windows focus change."); - assert.equal(tab.url, url1, 'the activated tab url is correct'); - - return close(win2).then(function() { - assert.pass('window 2 was closed'); - return close(win1); - }).then(done).then(null, assert.fail); - } - }); - - win1.focus(); - }); - }, "data:text/html;charset=utf-8,test window focus changes active tab</br><h1>Window #2"); - }, url1); -}; - -exports['test ready event on new window tab'] = function(assert, done) { - let uri = encodeURI("data:text/html;charset=utf-8,Waiting for ready event!"); - - require("sdk/tabs").on("ready", function onReady(tab) { - if (tab.url === uri) { - require("sdk/tabs").removeListener("ready", onReady); - assert.pass("ready event was emitted"); - close(window).then(done).then(null, assert.fail); - } - }); - - let window = openBrowserWindow(function(){}, uri); -}; - -exports['test unique tab ids'] = function(assert, done) { - var windows = require('sdk/windows').browserWindows; - var { all, defer } = require('sdk/core/promise'); - - function openWindow() { - let deferred = defer(); - let win = windows.open({ - url: "data:text/html;charset=utf-8,<html>foo</html>", - }); - - win.on('open', function(window) { - assert.ok(window.tabs.length); - assert.ok(window.tabs.activeTab); - assert.ok(window.tabs.activeTab.id); - deferred.resolve({ - id: window.tabs.activeTab.id, - win: win - }); - }); - - return deferred.promise; - } - - var one = openWindow(), two = openWindow(); - all([one, two]).then(function(results) { - assert.notEqual(results[0].id, results[1].id, "tab Ids should not be equal."); - results[0].win.close(function() { - results[1].win.close(function () { - done(); - }); - }); - }); -} - -// related to Bug 671305 -exports.testOnLoadEventWithDOM = function(assert, done) { - let count = 0; - let title = 'testOnLoadEventWithDOM'; - - // open a about: url - tabs.open({ - url: 'data:text/html;charset=utf-8,<title>' + title + '</title>', - inBackground: true, - onLoad: function(tab) { - assert.equal(tab.title, title, 'tab passed in as arg, load called'); - - if (++count > 1) { - assert.pass('onLoad event called on reload'); - tab.close(done); - } - else { - assert.pass('first onLoad event occured'); - tab.reload(); - } - } - }); -}; - -// related to Bug 671305 -exports.testOnLoadEventWithImage = function(assert, done) { - let count = 0; - - tabs.open({ - url: base64jpeg, - inBackground: true, - onLoad: function(tab) { - if (++count > 1) { - assert.pass('onLoad event called on reload with image'); - tab.close(done); - } - else { - assert.pass('first onLoad event occured'); - tab.reload(); - } - } - }); -}; - -exports.testNoDeadObjects = function(assert, done) { - let loader = Loader(module); - let myTabs = loader.require("sdk/tabs"); - - // Load a tab, unload our modules, and navigate the tab to trigger an event - // on it. This would throw a dead object exception if our modules didn't - // clean up their event handlers on unload. - tabs.open({ - url: "data:text/html;charset=utf-8,one", - onLoad: function(tab) { - // 2. Arrange to nuke the sandboxes and then trigger the load event - // on the tab once the loader is kaput. - systemEvents.on("sdk:loader:destroy", function onUnload() { - systemEvents.off("sdk:loader:destroy", onUnload, true); - // Defer this carnage till the end of the event queue, to avoid nuking - // the sandboxes from under the modules as they're being cleaned up. - setTimeout(function() { - // 3. Arrange to close the tab once the second page loads. - tab.on("load", function() { - tab.close(function() { - let { viewFor } = loader.require("sdk/view/core"); - assert.equal(viewFor(tab), undefined, "didn't retain the closed tab"); - done(); - }); - }); - - // Trigger a load event on the tab, to give the now-unloaded - // myTabs a chance to choke on it. - tab.url = "data:text/html;charset=utf-8,two"; - }, 0); - }, true); - - // 1. Start unloading the modules. Defer till the end of the event - // queue, in case myTabs is attaching its own handlers here too. - // We want it to latch on before we pull the rug from under it. - setTimeout(function() { - loader.unload(); - }, 0); - } - }); -}; - -exports.testTabDestroy = function(assert, done) { - let loader = Loader(module); - let myTabs = loader.require("sdk/tabs"); - let { modelFor: myModelFor } = loader.require("sdk/model/core"); - let { viewFor: myViewFor } = loader.require("sdk/view/core"); - let myFirstTab = myTabs.activeTab; - - myTabs.open({ - url: "data:text/html;charset=utf-8,destroy", - onReady: (myTab) => setImmediate(() => { - let tab = modelFor(myViewFor(myTab)); - - function badListener(event, tab) { - // Ignore events for the other tabs - if (tab != myTab) - return; - assert.fail("Should not have seen the " + event + " listener called"); - } - - assert.ok(myTab, "Should have a tab in the test loader."); - assert.equal(myViewFor(myTab), viewFor(tab), "Should have the right view."); - assert.equal(myTabs.length, 2, "Should have the right number of global tabs."); - assert.equal(myTab.window.tabs.length, 2, "Should have the right number of window tabs."); - assert.equal(myTabs.activeTab, myTab, "Globally active tab is correct."); - assert.equal(myTab.window.tabs.activeTab, myTab, "Window active tab is correct."); - - assert.equal(myTabs[1], myTab, "Global tabs list contains tab."); - assert.equal(myTab.window.tabs[1], myTab, "Window tabs list contains tab."); - - myTab.once("ready", badListener.bind(null, "tab ready")); - myTab.once("deactivate", badListener.bind(null, "tab deactivate")); - myTab.once("activate", badListener.bind(null, "tab activate")); - myTab.once("close", badListener.bind(null, "tab close")); - - myTab.destroy(); - - myTab.once("ready", badListener.bind(null, "new tab ready")); - myTab.once("deactivate", badListener.bind(null, "new tab deactivate")); - myTab.once("activate", badListener.bind(null, "new tab activate")); - myTab.once("close", badListener.bind(null, "new tab close")); - - myTabs.once("ready", badListener.bind(null, "tabs ready")); - myTabs.once("deactivate", badListener.bind(null, "tabs deactivate")); - myTabs.once("activate", badListener.bind(null, "tabs activate")); - myTabs.once("close", badListener.bind(null, "tabs close")); - - assert.equal(myViewFor(myTab), viewFor(tab), "Should have the right view."); - assert.equal(myModelFor(viewFor(tab)), myTab, "Can still reach the tab object."); - assert.equal(myTabs.length, 2, "Should have the right number of global tabs."); - assert.equal(myTab.window.tabs.length, 2, "Should have the right number of window tabs."); - assert.equal(myTabs.activeTab, myTab, "Globally active tab is correct."); - assert.equal(myTab.window.tabs.activeTab, myTab, "Window active tab is correct."); - - assert.equal(myTabs[1], myTab, "Global tabs list still contains tab."); - assert.equal(myTab.window.tabs[1], myTab, "Window tabs list still contains tab."); - - assert.equal(myTab.url, undefined, "url property is not usable"); - assert.equal(myTab.contentType, undefined, "contentType property is not usable"); - assert.equal(myTab.title, undefined, "title property is not usable"); - assert.equal(myTab.id, undefined, "id property is not usable"); - assert.equal(myTab.index, undefined, "index property is not usable"); - - myTab.pin(); - assert.ok(!tab.isPinned, "pin method shouldn't work"); - - tabs.once("activate", () => setImmediate(() => { - assert.equal(myTabs.activeTab, myFirstTab, "Globally active tab is correct."); - assert.equal(myTab.window.tabs.activeTab, myFirstTab, "Window active tab is correct."); - - let sawActivate = false; - tabs.once("activate", () => setImmediate(() => { - sawActivate = true; - - assert.equal(myTabs.activeTab, myTab, "Globally active tab is correct."); - assert.equal(myTab.window.tabs.activeTab, myTab, "Window active tab is correct."); - - // This shouldn't have any effect - myTab.close(); - - tab.once("ready", () => setImmediate(() => { - tab.close(() => { - loader.unload(); - done(); - }); - })); - tab.url = "data:text/html;charset=utf-8,destroy2"; - })); - - myTab.activate(); - setImmediate(() => { - assert.ok(!sawActivate, "activate method shouldn't have done anything"); - - tab.activate(); - }); - })); - myFirstTab.activate(); - }) - }) -}; - -// related to bug 942511 -// https://bugzilla.mozilla.org/show_bug.cgi?id=942511 -exports['test active tab properties defined on popup closed'] = function (assert, done) { - setPref(OPEN_IN_NEW_WINDOW_PREF, 2); - setPref(DISABLE_POPUP_PREF, false); - - let tabID = ""; - let popupClosed = false; - - tabs.open({ - url: 'about:blank', - onReady: function (tab) { - tabID = tab.id; - tab.attach({ - contentScript: 'var popup = window.open("about:blank");' + - 'popup.close();' - }); - - windowObserver.once('close', () => { - popupClosed = true; - }); - - windowObserver.on('activate', () => { - // Only when the 'activate' event is fired after the popup was closed. - if (popupClosed) { - popupClosed = false; - let activeTabID = tabs.activeTab.id; - if (activeTabID) { - assert.equal(tabID, activeTabID, 'ActiveTab properties are correct'); - } - else { - assert.fail('ActiveTab properties undefined on popup closed'); - } - tab.close(done); - } - }); - } - }); -}; - -// related to bugs 922956 and 989288 -// https://bugzilla.mozilla.org/show_bug.cgi?id=922956 -// https://bugzilla.mozilla.org/show_bug.cgi?id=989288 -exports["test tabs ready and close after window.open"] = function*(assert, done) { - // ensure popups open in a new window and disable popup blocker - setPref(OPEN_IN_NEW_WINDOW_PREF, 2); - setPref(DISABLE_POPUP_PREF, false); - - // open windows to trigger observers - tabs.activeTab.attach({ - contentScript: "window.open('about:blank');" + - "window.open('about:blank', '', " + - "'width=800,height=600,resizable=no,status=no,location=no');" - }); - - let tab1 = yield wait(tabs, "ready"); - assert.pass("first tab ready has occured"); - - let tab2 = yield wait(tabs, "ready"); - assert.pass("second tab ready has occured"); - - tab1.close(); - yield wait(tabs, "close"); - assert.pass("first tab close has occured"); - - tab2.close(); - yield wait(tabs, "close"); - assert.pass("second tab close has occured"); -}; - -// related to bug #939496 -exports["test tab open event for new window"] = function(assert, done) { - // ensure popups open in a new window and disable popup blocker - setPref(OPEN_IN_NEW_WINDOW_PREF, 2); - setPref(DISABLE_POPUP_PREF, false); - - tabs.once('open', function onOpen(window) { - assert.pass("tab open has occured"); - window.close(done); - }); - - // open window to trigger observers - browserWindows.open("about:logo"); -}; - -after(exports, function*(name, assert) { - resetPopupPrefs(); - yield cleanUI(); -}); - -const resetPopupPrefs = () => { - resetPref(OPEN_IN_NEW_WINDOW_PREF); - resetPref(DISABLE_POPUP_PREF); -}; - -/******************* helpers *********************/ - -// Utility function to open a new browser window. -function openBrowserWindow(callback, url) { - let ww = Cc["@mozilla.org/embedcomp/window-watcher;1"]. - getService(Ci.nsIWindowWatcher); - let urlString = Cc["@mozilla.org/supports-string;1"]. - createInstance(Ci.nsISupportsString); - urlString.data = url; - let window = ww.openWindow(null, "chrome://browser/content/browser.xul", - "_blank", "chrome,all,dialog=no", urlString); - - if (callback) { - window.addEventListener("load", function onLoad(event) { - if (event.target && event.target.defaultView == window) { - window.removeEventListener("load", onLoad, true); - let browsers = window.document.getElementsByTagName("tabbrowser"); - try { - setTimeout(function () { - callback(window, browsers[0]); - }, 10); - } - catch (e) { - console.exception(e); - } - } - }, true); - } - - return window; -} - -require("sdk/test").run(exports); |