Wed, 31 Dec 2014 06:55:50 +0100
Added tag UPSTREAM_283F7C6 for changeset ca08bd8f51b2
michael@0 | 1 | // Utilities for running tests in an e10s environment. |
michael@0 | 2 | |
michael@0 | 3 | // There are some tricks/shortcuts that test code takes that we don't see |
michael@0 | 4 | // in the real browser code. These include setting content.location.href |
michael@0 | 5 | // (which doesn't work in test code with e10s enabled as the document object |
michael@0 | 6 | // is yet to be created), waiting for certain events the main browser doesn't |
michael@0 | 7 | // care about and so doesn't normally get special support, eg, the "pageshow" |
michael@0 | 8 | // or "load" events). |
michael@0 | 9 | // So we make some hacks to pretend these work in the test suite. |
michael@0 | 10 | |
michael@0 | 11 | // Ideally all these hacks could be removed, but this can only happen when |
michael@0 | 12 | // the tests are refactored to not use these tricks. But this would be a huge |
michael@0 | 13 | // amount of work and is unlikely to happen anytime soon... |
michael@0 | 14 | |
michael@0 | 15 | const CONTENT_URL = "chrome://mochikit/content/mochitest-e10s-utils-content.js"; |
michael@0 | 16 | |
michael@0 | 17 | // This is an object that is used as the "location" on a remote document or |
michael@0 | 18 | // window. It will be overwritten as the real document and window are made |
michael@0 | 19 | // available. |
michael@0 | 20 | let locationStub = function(browser) { |
michael@0 | 21 | this.browser = browser; |
michael@0 | 22 | }; |
michael@0 | 23 | locationStub.prototype = { |
michael@0 | 24 | get href() { |
michael@0 | 25 | return this.browser.webNavigation.currentURI.spec; |
michael@0 | 26 | }, |
michael@0 | 27 | set href(val) { |
michael@0 | 28 | this.browser.loadURI(val); |
michael@0 | 29 | }, |
michael@0 | 30 | assign: function(url) { |
michael@0 | 31 | this.href = url; |
michael@0 | 32 | } |
michael@0 | 33 | }; |
michael@0 | 34 | |
michael@0 | 35 | // This object is used in place of contentWindow while we wait for it to be |
michael@0 | 36 | // overwritten as the real window becomes available. |
michael@0 | 37 | let TemporaryWindowStub = function(browser) { |
michael@0 | 38 | this._locationStub = new locationStub(browser); |
michael@0 | 39 | }; |
michael@0 | 40 | |
michael@0 | 41 | TemporaryWindowStub.prototype = { |
michael@0 | 42 | // save poor developers from getting confused about why the window isn't |
michael@0 | 43 | // working like a window should.. |
michael@0 | 44 | toString: function() { |
michael@0 | 45 | return "[Window Stub for e10s tests]"; |
michael@0 | 46 | }, |
michael@0 | 47 | get location() { |
michael@0 | 48 | return this._locationStub; |
michael@0 | 49 | }, |
michael@0 | 50 | set location(val) { |
michael@0 | 51 | this._locationStub.href = val; |
michael@0 | 52 | }, |
michael@0 | 53 | get document() { |
michael@0 | 54 | // so tests can say: document.location.... |
michael@0 | 55 | return this; |
michael@0 | 56 | } |
michael@0 | 57 | }; |
michael@0 | 58 | |
michael@0 | 59 | // An observer called when a new remote browser element is created. We replace |
michael@0 | 60 | // the _contentWindow in new browsers with our TemporaryWindowStub object. |
michael@0 | 61 | function observeNewFrameloader(subject, topic, data) { |
michael@0 | 62 | let browser = subject.QueryInterface(Ci.nsIFrameLoader).ownerElement; |
michael@0 | 63 | browser._contentWindow = new TemporaryWindowStub(browser); |
michael@0 | 64 | } |
michael@0 | 65 | |
michael@0 | 66 | function e10s_init() { |
michael@0 | 67 | // Use the global message manager to inject a content script into all browsers. |
michael@0 | 68 | let globalMM = Cc["@mozilla.org/globalmessagemanager;1"] |
michael@0 | 69 | .getService(Ci.nsIMessageListenerManager); |
michael@0 | 70 | globalMM.loadFrameScript(CONTENT_URL, true); |
michael@0 | 71 | globalMM.addMessageListener("Test:Event", function(message) { |
michael@0 | 72 | let event = document.createEvent('HTMLEvents'); |
michael@0 | 73 | event.initEvent(message.data.name, true, true, {}); |
michael@0 | 74 | message.target.dispatchEvent(event); |
michael@0 | 75 | }); |
michael@0 | 76 | |
michael@0 | 77 | // We add an observer so we can notice new <browser> elements created |
michael@0 | 78 | Services.obs.addObserver(observeNewFrameloader, "remote-browser-shown", false); |
michael@0 | 79 | |
michael@0 | 80 | // Listen for an 'oop-browser-crashed' event and log it so people analysing |
michael@0 | 81 | // test logs have a clue about what is going on. |
michael@0 | 82 | window.addEventListener("oop-browser-crashed", (event) => { |
michael@0 | 83 | let uri = event.target.currentURI; |
michael@0 | 84 | Cu.reportError("remote browser crashed while on " + |
michael@0 | 85 | (uri ? uri.spec : "<unknown>") + "\n"); |
michael@0 | 86 | }, true); |
michael@0 | 87 | } |