// Swaps the content of tab a into tab b and then closes tab a. function swapTabsAndCloseOther(a, b) { gBrowser.swapBrowsersAndCloseOther(gBrowser.tabs[b], gBrowser.tabs[a]); } // Mirrors the effect of the above function on an array. function swapArrayContentsAndRemoveOther(arr, a, b) { arr[b] = arr[a]; arr.splice(a, 1); } function checkBrowserIds(expected) { is( gBrowser.tabs.length, expected.length, "Should have the right number of tabs." ); for (let [i, tab] of gBrowser.tabs.entries()) { is( tab.linkedBrowser.browserId, expected[i], `Tab ${i} should have the right browser ID.` ); is( tab.linkedBrowser.browserId, tab.linkedBrowser.browsingContext.browserId, `Browser for tab ${i} has the same browserId as its BrowsingContext` ); } } var getClicks = function (tab) { return SpecialPowers.spawn(tab.linkedBrowser, [], function () { return content.wrappedJSObject.clicks; }); }; var clickTest = async function (tab) { let clicks = await getClicks(tab); await SpecialPowers.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.windowUtils; utils.sendMouseEvent("mousedown", left, top, 0, 1, 0, false, 0, 0); utils.sendMouseEvent("mouseup", left, top, 0, 1, 0, false, 0, 0); }); let newClicks = await getClicks(tab); is(newClicks, clicks + 1, "adding 1 more click on BODY"); }; function loadURI(tab, url) { BrowserTestUtils.loadURIString(tab.linkedBrowser, 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. async function cacheObjectValue(browser) { await SpecialPowers.spawn(browser, [], () => { let plugin = content.document.getElementById("p").wrappedJSObject; info(`plugin is ${plugin}`); let win = content.document.defaultView; info(`win is ${win}`); win.objectValue = plugin.getObjectValue(); info(`got objectValue: ${win.objectValue}`); }); } // Note, can't run this via registerCleanupFunction because it needs the // browser to still be alive and have a messageManager. async function cleanupObjectValue(browser) { info("entered cleanupObjectValue"); await SpecialPowers.spawn(browser, [], () => { info("in cleanup function"); let win = content.document.defaultView; info(`about to delete objectValue: ${win.objectValue}`); delete win.objectValue; }); info("exiting cleanupObjectValue"); } // See the notes for cacheObjectValue above. async function checkObjectValue(browser) { let data = await SpecialPowers.spawn(browser, [], () => { let plugin = content.document.getElementById("p").wrappedJSObject; let win = content.document.defaultView; let result, exception; try { result = plugin.checkObjectValue(win.objectValue); } catch (e) { exception = e.toString(); } return { result, exception, }; }); if (data.result === null) { ok(false, "checkObjectValue threw an exception: " + data.exception); throw new Error(data.exception); } else { return data.result; } } add_task(async function () { // create a few tabs let tabs = [ gBrowser.tabs[0], BrowserTestUtils.addTab(gBrowser, "about:blank", { skipAnimation: true }), BrowserTestUtils.addTab(gBrowser, "about:blank", { skipAnimation: true }), BrowserTestUtils.addTab(gBrowser, "about:blank", { skipAnimation: true }), BrowserTestUtils.addTab(gBrowser, "about:blank", { skipAnimation: true }), ]; // Initially 0 1 2 3 4 await loadURI( tabs[1], "data:text/html;charset=utf-8,tab1tab1