Converting a test to be e10s compatible
I was working on another bug the other day when I came across a disabled test. The comment for why it was disabled seemed like it might be low-hanging fruit for conversion to be e10s
-compatible, so I took a look.
A couple of things leapt out to me immediately: the test isn’t using BrowserTestUtils
and it isn’t using promises. So, the first step is to convert it to use BrowserTestUtils
and Promise
. Here’s the diff.
Now that we’re using promises and the nice helpers, let’s see why the test isn’t compatible. The first load is of a chrome://
URL. This is guaranteed to load in the parent, meaning that our first test, testXFOFrameInChrome
can remain untouched. We can use its contentWindow
with impunity.
The second test, testXFOFrameInContent
is the reason this blog post exists. It loads a content document, meaning that its browser will be a remote browser and the contentWindow
would be a CPOW. Instead of using it directly, we can use another helper: ContentTask
. This will let us perform an operation in a given browser
‘s associated child process and fulfill a Promise
when it finishes. Here’s that change.
We’re almost done! However, if we run this version, we’ll still fail due to a small difference between the function is
in browser-chrome tests and in ContentTask.jsm
. The version in ContentTask.jsm
is stricter than that of the normal tests, so when we check the return value of document.getElementById
against undefined
we get a test failure. We fix that by checking against the correct value (null
). Another thing to note is that ContentTask
decompiles and recompiles the callback function in the child process. That means that you can’t use any global variables or functions. You can pass a single parameter to the function, though, as long as it can be structured cloned. The content window is available through the content
global in frame scripts.
One last note about this test. When I was writing it, I used BrowserTestUtils.loadURI
function which returns a Promise
. However, that promise doesn’t resolve when the URI is loaded, only when the load starts. So I ended up wasting a bunch of time before realizing that I needed to use BrowserTestUtils.browserLoaded
after it to ensure the second test runs at the right time.
Now, our test passes and we can get it reviewed and checked in!
Comments are off for this post