1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/testing/mochitest/mochitest-e10s-utils.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,87 @@ 1.4 +// Utilities for running tests in an e10s environment. 1.5 + 1.6 +// There are some tricks/shortcuts that test code takes that we don't see 1.7 +// in the real browser code. These include setting content.location.href 1.8 +// (which doesn't work in test code with e10s enabled as the document object 1.9 +// is yet to be created), waiting for certain events the main browser doesn't 1.10 +// care about and so doesn't normally get special support, eg, the "pageshow" 1.11 +// or "load" events). 1.12 +// So we make some hacks to pretend these work in the test suite. 1.13 + 1.14 +// Ideally all these hacks could be removed, but this can only happen when 1.15 +// the tests are refactored to not use these tricks. But this would be a huge 1.16 +// amount of work and is unlikely to happen anytime soon... 1.17 + 1.18 +const CONTENT_URL = "chrome://mochikit/content/mochitest-e10s-utils-content.js"; 1.19 + 1.20 +// This is an object that is used as the "location" on a remote document or 1.21 +// window. It will be overwritten as the real document and window are made 1.22 +// available. 1.23 +let locationStub = function(browser) { 1.24 + this.browser = browser; 1.25 +}; 1.26 +locationStub.prototype = { 1.27 + get href() { 1.28 + return this.browser.webNavigation.currentURI.spec; 1.29 + }, 1.30 + set href(val) { 1.31 + this.browser.loadURI(val); 1.32 + }, 1.33 + assign: function(url) { 1.34 + this.href = url; 1.35 + } 1.36 +}; 1.37 + 1.38 +// This object is used in place of contentWindow while we wait for it to be 1.39 +// overwritten as the real window becomes available. 1.40 +let TemporaryWindowStub = function(browser) { 1.41 + this._locationStub = new locationStub(browser); 1.42 +}; 1.43 + 1.44 +TemporaryWindowStub.prototype = { 1.45 + // save poor developers from getting confused about why the window isn't 1.46 + // working like a window should.. 1.47 + toString: function() { 1.48 + return "[Window Stub for e10s tests]"; 1.49 + }, 1.50 + get location() { 1.51 + return this._locationStub; 1.52 + }, 1.53 + set location(val) { 1.54 + this._locationStub.href = val; 1.55 + }, 1.56 + get document() { 1.57 + // so tests can say: document.location.... 1.58 + return this; 1.59 + } 1.60 +}; 1.61 + 1.62 +// An observer called when a new remote browser element is created. We replace 1.63 +// the _contentWindow in new browsers with our TemporaryWindowStub object. 1.64 +function observeNewFrameloader(subject, topic, data) { 1.65 + let browser = subject.QueryInterface(Ci.nsIFrameLoader).ownerElement; 1.66 + browser._contentWindow = new TemporaryWindowStub(browser); 1.67 +} 1.68 + 1.69 +function e10s_init() { 1.70 + // Use the global message manager to inject a content script into all browsers. 1.71 + let globalMM = Cc["@mozilla.org/globalmessagemanager;1"] 1.72 + .getService(Ci.nsIMessageListenerManager); 1.73 + globalMM.loadFrameScript(CONTENT_URL, true); 1.74 + globalMM.addMessageListener("Test:Event", function(message) { 1.75 + let event = document.createEvent('HTMLEvents'); 1.76 + event.initEvent(message.data.name, true, true, {}); 1.77 + message.target.dispatchEvent(event); 1.78 + }); 1.79 + 1.80 + // We add an observer so we can notice new <browser> elements created 1.81 + Services.obs.addObserver(observeNewFrameloader, "remote-browser-shown", false); 1.82 + 1.83 + // Listen for an 'oop-browser-crashed' event and log it so people analysing 1.84 + // test logs have a clue about what is going on. 1.85 + window.addEventListener("oop-browser-crashed", (event) => { 1.86 + let uri = event.target.currentURI; 1.87 + Cu.reportError("remote browser crashed while on " + 1.88 + (uri ? uri.spec : "<unknown>") + "\n"); 1.89 + }, true); 1.90 +}