Bug 1176019 - Fix browser_tabswitchbetweenplugins.js r?mconley draft
authorDoug Thayer <dothayer@mozilla.com>
Tue, 08 May 2018 15:26:15 -0700
changeset 797871 fcdefab4f1d545c9140cd803bd0023fb0b182616
parent 797870 79e9917b4096119ee713002dccfd359b53499d5f
child 797872 0fdf7dc2df032dad489bc4c9dc58ede3b48513f0
child 797878 a7f61dc64a71250f448f8d7e1f8e6c28a71c88a9
push id110611
push userbmo:dothayer@mozilla.com
push dateMon, 21 May 2018 22:29:47 +0000
reviewersmconley
bugs1176019
milestone62.0a1
Bug 1176019 - Fix browser_tabswitchbetweenplugins.js r?mconley After digging into this, I'm still not entirely sure why the timing has changed such that the checks don't work immediately. I have a strong suspicion though that it's simply because our tab switch is now instant, resulting in the necessary messages just being a little bit behind. Hopefully this is an acceptable bandaid. MozReview-Commit-ID: H1wKW1UQBxp
dom/plugins/test/mochitest/browser_tabswitchbetweenplugins.js
--- a/dom/plugins/test/mochitest/browser_tabswitchbetweenplugins.js
+++ b/dom/plugins/test/mochitest/browser_tabswitchbetweenplugins.js
@@ -1,10 +1,38 @@
 var gTestRoot = getRootDirectory(gTestPath).replace("chrome://mochitests/content/", "http://127.0.0.1:8888/");
 
+function waitForPluginVisibility(browser, shouldBeVisible, errorMessage) {
+  return new Promise((resolve, reject) => {
+    let windowUtils = window.QueryInterface(Ci.nsIInterfaceRequestor)
+                            .getInterface(Ci.nsIDOMWindowUtils);
+    let lastTransactionId = windowUtils.lastTransactionId;
+    let listener = async (event) => {
+      let visibility = await ContentTask.spawn(browser, null, async function() {
+        let doc = content.document;
+        let plugin = doc.getElementById("testplugin");
+        return XPCNativeWrapper.unwrap(plugin).nativeWidgetIsVisible();
+      });
+
+      if (visibility == shouldBeVisible) {
+        window.removeEventListener("MozAfterPaint", listener);
+        resolve();
+      } else if (event && event.transactionId > lastTransactionId) {
+        // We want to allow for one failed check since we call listener
+        // directly, but if we get a MozAfterPaint notification and we
+        // still don't have the correct visibility, that's likely a
+        // problem.
+        reject(new Error("MozAfterPaint had a mismatched plugin visibility"));
+      }
+    };
+    window.addEventListener("MozAfterPaint", listener);
+    listener(null);
+  });
+}
+
 // tests that we get plugin updates when we flip between tabs that
 // have the same plugin in the same position in the page.
 
 add_task(async function() {
   let result, tabSwitchedPromise;
 
   setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Test Plug-in");
 
@@ -24,82 +52,50 @@ add_task(async function() {
     let plugin = doc.getElementById("testplugin");
     return !!plugin;
   });
   is(result, true, "plugin2 is loaded");
 
   // plugin tab 2 should be selected
   is(gBrowser.selectedTab == pluginTab2, true, "plugin2 is selected");
 
-  result = await ContentTask.spawn(pluginTab1.linkedBrowser, null, async function() {
-    let doc = content.document;
-    let plugin = doc.getElementById("testplugin");
-    return XPCNativeWrapper.unwrap(plugin).nativeWidgetIsVisible();
-  });
-  is(result, false, "plugin1 is hidden");
+  await waitForPluginVisibility(pluginTab1.linkedBrowser,
+                                false, "plugin1 should be hidden");
 
-  result = await ContentTask.spawn(pluginTab2.linkedBrowser, null, async function() {
-    let doc = content.document;
-    let plugin = doc.getElementById("testplugin");
-    return XPCNativeWrapper.unwrap(plugin).nativeWidgetIsVisible();
-  });
-  is(result, true, "plugin2 is visible");
+  await waitForPluginVisibility(pluginTab2.linkedBrowser,
+                                true, "plugin2 should be visible");
 
   // select plugin1 tab
   tabSwitchedPromise = waitTabSwitched();
   gBrowser.selectedTab = pluginTab1;
   await tabSwitchedPromise;
 
-  result = await ContentTask.spawn(pluginTab1.linkedBrowser, null, async function() {
-    let doc = content.document;
-    let plugin = doc.getElementById("testplugin");
-    return XPCNativeWrapper.unwrap(plugin).nativeWidgetIsVisible();
-  });
-  is(result, true, "plugin1 is visible");
+  await waitForPluginVisibility(pluginTab1.linkedBrowser,
+                                true, "plugin1 should be visible");
 
-  result = await ContentTask.spawn(pluginTab2.linkedBrowser, null, async function() {
-    let doc = content.document;
-    let plugin = doc.getElementById("testplugin");
-    return XPCNativeWrapper.unwrap(plugin).nativeWidgetIsVisible();
-  });
-  is(result, false, "plugin2 is hidden");
+  await waitForPluginVisibility(pluginTab2.linkedBrowser,
+                                false, "plugin2 should be hidden");
 
   // select plugin2 tab
   tabSwitchedPromise = waitTabSwitched();
   gBrowser.selectedTab = pluginTab2;
   await tabSwitchedPromise;
 
-  result = await ContentTask.spawn(pluginTab1.linkedBrowser, null, async function() {
-    let doc = content.document;
-    let plugin = doc.getElementById("testplugin");
-    return XPCNativeWrapper.unwrap(plugin).nativeWidgetIsVisible();
-  });
-  is(result, false, "plugin1 is hidden");
+  await waitForPluginVisibility(pluginTab1.linkedBrowser,
+                                false, "plugin1 should be hidden");
 
-  result = await ContentTask.spawn(pluginTab2.linkedBrowser, null, async function() {
-    let doc = content.document;
-    let plugin = doc.getElementById("testplugin");
-    return XPCNativeWrapper.unwrap(plugin).nativeWidgetIsVisible();
-  });
-  is(result, true, "plugin2 is visible");
+  await waitForPluginVisibility(pluginTab2.linkedBrowser,
+                                true, "plugin2 should be visible");
 
   // select test tab
   tabSwitchedPromise = waitTabSwitched();
   gBrowser.selectedTab = testTab;
   await tabSwitchedPromise;
 
-  result = await ContentTask.spawn(pluginTab1.linkedBrowser, null, async function() {
-    let doc = content.document;
-    let plugin = doc.getElementById("testplugin");
-    return XPCNativeWrapper.unwrap(plugin).nativeWidgetIsVisible();
-  });
-  is(result, false, "plugin1 is hidden");
+  await waitForPluginVisibility(pluginTab1.linkedBrowser,
+                                false, "plugin1 should be hidden");
 
-  result = await ContentTask.spawn(pluginTab2.linkedBrowser, null, async function() {
-    let doc = content.document;
-    let plugin = doc.getElementById("testplugin");
-    return XPCNativeWrapper.unwrap(plugin).nativeWidgetIsVisible();
-  });
-  is(result, false, "plugin2 is hidden");
+  await waitForPluginVisibility(pluginTab2.linkedBrowser,
+                                false, "plugin2 should be hidden");
 
   gBrowser.removeTab(pluginTab1);
   gBrowser.removeTab(pluginTab2);
 });