None draft
authorKris Maglione <maglione.k@gmail.com>
Mon, 25 Nov 2019 19:36:27 +0000
changeset 2496015 9ae8782cf83c5afb0a3c4bfafda8a1153fb260cb
parent 2496014 16be811da4fb99048ea5d9b08f81f887038cc10b
child 2496016 70f1902211995a9efc72ff36b5f9985014d52c95
push id455265
push userreviewbot
push dateMon, 25 Nov 2019 19:36:52 +0000
treeherdertry@7df9e6addf62 [default view] [failures only]
milestone72.0a1
None Differential Diff: PHID-DIFF-rp7dphnr2l3fqmwj73jf
testing/specialpowers/content/SpecialPowersChild.jsm
testing/specialpowers/content/SpecialPowersEventUtils.jsm
testing/specialpowers/content/SpecialPowersSandbox.jsm
testing/specialpowers/moz.build
--- a/testing/specialpowers/content/SpecialPowersChild.jsm
+++ b/testing/specialpowers/content/SpecialPowersChild.jsm
@@ -1704,22 +1704,27 @@ class SpecialPowersChild extends JSWindo
       data => {
         this.sendAsyncMessage("ProxiedAssert", { taskId, data });
       },
       { imports }
     );
 
     sb.sandbox.SpecialPowers = this;
     sb.sandbox.ContentTaskUtils = ContentTaskUtils;
-    Object.defineProperty(sb.sandbox, "content", {
-      get: () => {
-        return this.contentWindow;
-      },
-      enumerable: true,
-    });
+    for (let [global, prop] of Object.entries({
+      content: "contentWindow",
+      docShell: "docShell",
+    })) {
+      Object.defineProperty(sb.sandbox, global, {
+        get: () => {
+          return this[prop];
+        },
+        enumerable: true,
+      });
+    }
 
     return sb.execute(task, args, caller);
   }
 
   /**
    * Automatically imports the given symbol from the given JSM for any
    * task spawned by this SpecialPowers instance.
    */
new file mode 100644
--- /dev/null
+++ b/testing/specialpowers/content/SpecialPowersEventUtils.jsm
@@ -0,0 +1,48 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+"use strict";
+
+var EXPORTED_SYMBOLS = ["EventUtils"];
+
+/**
+ * Loads a stub copy of EventUtils.js which can be used by things like
+ * content tasks without holding any direct references to windows.
+ */
+
+const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
+
+let EventUtils = {};
+
+EventUtils.window = {};
+EventUtils.parent = EventUtils.window;
+EventUtils._EU_Ci = Ci;
+EventUtils._EU_Cc = Cc;
+
+EventUtils.synthesizeClick = element =>
+  new Promise(resolve => {
+    element.addEventListener(
+      "click",
+      function() {
+        resolve();
+      },
+      { once: true }
+    );
+
+    EventUtils.synthesizeMouseAtCenter(
+      element,
+      { type: "mousedown", isSynthesized: false },
+      element.ownerGlobal
+    );
+    EventUtils.synthesizeMouseAtCenter(
+      element,
+      { type: "mouseup", isSynthesized: false },
+      element.ownerGlobal
+    );
+  });
+
+Services.scriptloader.loadSubScript(
+  "chrome://mochikit/content/tests/SimpleTest/EventUtils.js",
+  EventUtils
+);
--- a/testing/specialpowers/content/SpecialPowersSandbox.jsm
+++ b/testing/specialpowers/content/SpecialPowersSandbox.jsm
@@ -13,16 +13,24 @@
 var EXPORTED_SYMBOLS = ["SpecialPowersSandbox"];
 
 ChromeUtils.defineModuleGetter(
   this,
   "Assert",
   "resource://testing-common/Assert.jsm"
 );
 
+const SANDBOX_GLOBALS = [
+  "Blob",
+  "ChromeUtils",
+  "TextDecoder",
+  "TextEncoder",
+  "URL",
+];
+
 let expectFail = false;
 function expectingFail(fn) {
   try {
     expectFail = true;
     fn();
   } finally {
     expectFail = false;
   }
@@ -33,36 +41,42 @@ class SpecialPowersSandbox {
     this.name = name;
     this.reportCallback = reportCallback;
 
     this._Assert = null;
 
     this.sandbox = Cu.Sandbox(
       Cu.getGlobalForObject({}),
       Object.assign(
-        { wantGlobalProperties: ["ChromeUtils"] },
+        { wantGlobalProperties: SANDBOX_GLOBALS },
         opts.sandboxOptions
       )
     );
 
     for (let prop of ["assert", "Assert"]) {
       Object.defineProperty(this.sandbox, prop, {
         get: () => {
           return this.Assert;
         },
         enumerable: true,
         configurable: true,
       });
     }
 
-    for (let [symbol, url] of Object.entries(opts.imports || {})) {
+    let imports = {
+      EventUtils: "resource://specialpowers/SpecialPowersEventUtils.jsm",
+      Services: "resource://gre/modules/Services.jsm",
+      ...opts.imports,
+    };
+    for (let [symbol, url] of Object.entries(imports)) {
       ChromeUtils.defineModuleGetter(this.sandbox, symbol, url);
     }
 
     Object.assign(this.sandbox, {
+      BrowsingContext,
       ok: (...args) => {
         this.Assert.ok(...args);
       },
       is: (...args) => {
         this.Assert.equal(...args);
       },
       isnot: (...args) => {
         this.Assert.notEqual(...args);
--- a/testing/specialpowers/moz.build
+++ b/testing/specialpowers/moz.build
@@ -15,15 +15,16 @@ FINAL_TARGET_FILES += [
 ]
 
 FINAL_TARGET_FILES.content += [
     '../modules/Assert.jsm',
     'content/MockColorPicker.jsm',
     'content/MockFilePicker.jsm',
     'content/MockPermissionPrompt.jsm',
     'content/SpecialPowersChild.jsm',
+    'content/SpecialPowersEventUtils.jsm',
     'content/SpecialPowersParent.jsm',
     'content/SpecialPowersSandbox.jsm',
     'content/WrapPrivileged.jsm',
 ]
 
 with Files("**"):
     BUG_COMPONENT = ("Testing", "Mochitest")