function swapTabsAndCloseOther(a, b) { gBrowser.swapBrowsersAndCloseOther(gBrowser.tabs[b], gBrowser.tabs[a]); } var getClicks = function(tab) { return ContentTask.spawn(tab.linkedBrowser, {}, function() { return content.wrappedJSObject.clicks; }); } var clickTest = Task.async(function*(tab) { let clicks = yield getClicks(tab); yield ContentTask.spawn(tab.linkedBrowser, {}, function() { let target = content.document.body; let rect = target.getBoundingClientRect(); let left = (rect.left + rect.right) / 2; let top = (rect.top + rect.bottom) / 2; let utils = content.QueryInterface(Components.interfaces.nsIInterfaceRequestor) .getInterface(Components.interfaces.nsIDOMWindowUtils); utils.sendMouseEvent("mousedown", left, top, 0, 1, 0, false, 0, 0); utils.sendMouseEvent("mouseup", left, top, 0, 1, 0, false, 0, 0); }); let newClicks = yield getClicks(tab); is(newClicks, clicks + 1, "adding 1 more click on BODY"); }); function loadURI(tab, url) { tab.linkedBrowser.loadURI(url); return BrowserTestUtils.browserLoaded(tab.linkedBrowser); } // Creates a framescript which caches the current object value from the plugin // in the page. checkObjectValue below verifies that the framescript is still // active for the browser and that the cached value matches that from the plugin // in the page which tells us the plugin hasn't been reinitialized. function* cacheObjectValue(browser) { yield ContentTask.spawn(browser, null, function*() { let plugin = content.document.wrappedJSObject.body.firstChild; info(`plugin is ${plugin}`); let win = content.document.defaultView; info(`win is ${win}`); win.objectValue = plugin.getObjectValue(); info(`got objectValue: ${win.objectValue}`); win.checkObjectValueListener = () => { let result; let exception; try { result = plugin.checkObjectValue(win.objectValue); } catch (e) { exception = e.toString(); } info(`sending plugin.checkObjectValue(objectValue): ${result}`); sendAsyncMessage("Test:CheckObjectValueResult", { result, exception }); }; addMessageListener("Test:CheckObjectValue", win.checkObjectValueListener); }); } // Note, can't run this via registerCleanupFunction because it needs the // browser to still be alive and have a messageManager. function* cleanupObjectValue(browser) { info("entered cleanupObjectValue") yield ContentTask.spawn(browser, null, function*() { info("in cleanup function"); let win = content.document.defaultView; info(`about to delete objectValue: ${win.objectValue}`); delete win.objectValue; removeMessageListener("Test:CheckObjectValue", win.checkObjectValueListener); info(`about to delete checkObjectValueListener: ${win.checkObjectValueListener}`); delete win.checkObjectValueListener; info(`deleted objectValue (${win.objectValue}) and checkObjectValueListener (${win.checkObjectValueListener})`); }); info("exiting cleanupObjectValue") } // See the notes for cacheObjectValue above. function checkObjectValue(browser) { let mm = browser.messageManager; return new Promise((resolve, reject) => { let listener = ({ data }) => { mm.removeMessageListener("Test:CheckObjectValueResult", listener); if (data.result === null) { ok(false, "checkObjectValue threw an exception: " + data.exception); reject(data.exception); } else { resolve(data.result); } }; mm.addMessageListener("Test:CheckObjectValueResult", listener); mm.sendAsyncMessage("Test:CheckObjectValue"); }); } add_task(function*() { let embed = '' setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED); // create a few tabs let tabs = [ gBrowser.tabs[0], gBrowser.addTab("about:blank", {skipAnimation: true}), gBrowser.addTab("about:blank", {skipAnimation: true}), gBrowser.addTab("about:blank", {skipAnimation: true}), gBrowser.addTab("about:blank", {skipAnimation: true}) ]; // Initially 0 1 2 3 4 yield loadURI(tabs[1], "data:text/html;charset=utf-8,tab1tab1