summaryrefslogtreecommitdiffstats
path: root/gfx/layers/apz/test/mochitest/FissionTestHelperChild.sys.mjs
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/layers/apz/test/mochitest/FissionTestHelperChild.sys.mjs')
-rw-r--r--gfx/layers/apz/test/mochitest/FissionTestHelperChild.sys.mjs157
1 files changed, 157 insertions, 0 deletions
diff --git a/gfx/layers/apz/test/mochitest/FissionTestHelperChild.sys.mjs b/gfx/layers/apz/test/mochitest/FissionTestHelperChild.sys.mjs
new file mode 100644
index 0000000000..c0695b7abb
--- /dev/null
+++ b/gfx/layers/apz/test/mochitest/FissionTestHelperChild.sys.mjs
@@ -0,0 +1,157 @@
+// This code runs in the content process that holds the window to which
+// this actor is attached. There is one instance of this class for each
+// "inner window" (i.e. one per content document, including iframes/nested
+// iframes).
+// There is a 1:1 relationship between instances of this class and
+// FissionTestHelperParent instances, and the pair are entangled such
+// that they can communicate with each other regardless of which process
+// they live in.
+
+export class FissionTestHelperChild extends JSWindowActorChild {
+ constructor() {
+ super();
+ this._msgCounter = 0;
+ this._oopifResponsePromiseResolvers = [];
+ }
+
+ cw() {
+ return this.contentWindow.wrappedJSObject;
+ }
+
+ initialize() {
+ // This exports a bunch of things into the content window so that
+ // the test can access them. Most things are scoped inside the
+ // FissionTestHelper object on the window to avoid polluting the global
+ // namespace.
+
+ let cw = this.cw();
+ Cu.exportFunction(
+ (cond, msg) => this.sendAsyncMessage("ok", { cond, msg }),
+ cw,
+ { defineAs: "ok" }
+ );
+ Cu.exportFunction(
+ (a, b, msg) => this.sendAsyncMessage("is", { a, b, msg }),
+ cw,
+ { defineAs: "is" }
+ );
+
+ let FissionTestHelper = Cu.createObjectIn(cw, {
+ defineAs: "FissionTestHelper",
+ });
+ FissionTestHelper.startTestPromise = new cw.Promise(
+ Cu.exportFunction(resolve => {
+ this._startTestPromiseResolver = resolve;
+ }, cw)
+ );
+
+ Cu.exportFunction(this.subtestDone.bind(this), FissionTestHelper, {
+ defineAs: "subtestDone",
+ });
+
+ Cu.exportFunction(this.subtestFailed.bind(this), FissionTestHelper, {
+ defineAs: "subtestFailed",
+ });
+
+ Cu.exportFunction(this.sendToOopif.bind(this), FissionTestHelper, {
+ defineAs: "sendToOopif",
+ });
+ Cu.exportFunction(this.fireEventInEmbedder.bind(this), FissionTestHelper, {
+ defineAs: "fireEventInEmbedder",
+ });
+ }
+
+ // Called by the subtest to indicate completion to the top-level browser-chrome
+ // mochitest.
+ subtestDone() {
+ let cw = this.cw();
+ if (cw.ApzCleanup) {
+ cw.ApzCleanup.execute();
+ }
+ this.sendAsyncMessage("Test:Complete", {});
+ }
+
+ // Called by the subtest to indicate subtest failure. Only one of subtestDone
+ // or subtestFailed should be called.
+ subtestFailed(msg) {
+ this.sendAsyncMessage("ok", { cond: false, msg });
+ this.subtestDone();
+ }
+
+ // Called by the subtest to eval some code in the OOP iframe. This returns
+ // a promise that resolves to the return value from the eval.
+ sendToOopif(iframeElement, stringToEval) {
+ let browsingContextId = iframeElement.browsingContext.id;
+ let msgId = ++this._msgCounter;
+ let cw = this.cw();
+ let responsePromise = new cw.Promise(
+ Cu.exportFunction(resolve => {
+ this._oopifResponsePromiseResolvers[msgId] = resolve;
+ }, cw)
+ );
+ this.sendAsyncMessage("EmbedderToOopif", {
+ browsingContextId,
+ msgId,
+ stringToEval,
+ });
+ return responsePromise;
+ }
+
+ // Called by OOP iframes to dispatch an event in the embedder window. This
+ // can be used by the OOP iframe to asynchronously notify the embedder of
+ // things that happen. The embedder can use promiseOneEvent from
+ // helper_fission_utils.js to listen for these events.
+ fireEventInEmbedder(eventType, data) {
+ this.sendAsyncMessage("OopifToEmbedder", { eventType, data });
+ }
+
+ handleEvent(evt) {
+ switch (evt.type) {
+ case "FissionTestHelper:Init":
+ this.initialize();
+ break;
+ }
+ }
+
+ receiveMessage(msg) {
+ switch (msg.name) {
+ case "Test:Start":
+ this._startTestPromiseResolver();
+ delete this._startTestPromiseResolver;
+ break;
+ case "FromEmbedder":
+ let evalResult = this.contentWindow.eval(msg.data.stringToEval);
+ this.sendAsyncMessage("OopifToEmbedder", {
+ msgId: msg.data.msgId,
+ evalResult,
+ });
+ break;
+ case "FromOopif":
+ if (typeof msg.data.msgId == "number") {
+ if (!(msg.data.msgId in this._oopifResponsePromiseResolvers)) {
+ dump(
+ "Error: FromOopif got a message with unknown numeric msgId in " +
+ this.contentWindow.location.href +
+ "\n"
+ );
+ }
+ this._oopifResponsePromiseResolvers[msg.data.msgId](
+ msg.data.evalResult
+ );
+ delete this._oopifResponsePromiseResolvers[msg.data.msgId];
+ } else if (typeof msg.data.eventType == "string") {
+ let cw = this.cw();
+ let event = new cw.Event(msg.data.eventType);
+ event.data = Cu.cloneInto(msg.data.data, cw);
+ this.contentWindow.dispatchEvent(event);
+ } else {
+ dump(
+ "Warning: Unrecognized FromOopif message received in " +
+ this.contentWindow.location.href +
+ "\n"
+ );
+ }
+ break;
+ }
+ }
+}