Bug 878003 - Test for getScreenshot transparency. r=smaug
authorTim Chien <timdream@gmail.com>
Mon, 13 Jan 2014 08:55:15 -0500
changeset 163133 9c97bd22aab277f55feb3c212e6ff8d4338126cd
parent 163132 8fc3d2e02f478e1c80a83ef1c405bf2cda476892
child 163134 1f13f7342ceba01cf2495781bf62767bd144f173
push id25982
push userryanvm@gmail.com
push dateMon, 13 Jan 2014 22:30:39 +0000
treeherdermozilla-central@d524c4b2cbb8 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs878003
milestone29.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 878003 - Test for getScreenshot transparency. r=smaug
dom/browser-element/mochitest/browserElement_GetScreenshot.js
dom/browser-element/mochitest/test_browserElement_oop_GetScreenshot.html
--- a/dom/browser-element/mochitest/browserElement_GetScreenshot.js
+++ b/dom/browser-element/mochitest/browserElement_GetScreenshot.js
@@ -10,85 +10,145 @@ browserElementTestHelpers.addPermission(
 
 function runTest() {
   var iframe1 = document.createElement('iframe');
   SpecialPowers.wrap(iframe1).mozbrowser = true;
   document.body.appendChild(iframe1);
   iframe1.src = 'data:text/html,<html>' +
     '<body style="background:green">hello</body></html>';
 
-  var screenshotArrayBuffers = [];
+  var screenshotImageDatas = [];
   var numLoaded = 0;
 
-  function screenshotTaken(screenshotArrayBuffer) {
-    screenshotArrayBuffers.push(screenshotArrayBuffer);
-    if (screenshotArrayBuffers.length === 1) {
+  function screenshotTaken(screenshotImageData) {
+    screenshotImageDatas.push(screenshotImageData);
+    if (screenshotImageDatas.length === 1) {
       ok(true, 'Got initial non blank screenshot');
+
+      var view = screenshotImageData.data;
+      if (view[3] !== 255) {
+        ok(false, 'The first pixel of initial screenshot is not opaque');
+        SimpleTest.finish();
+        return;
+      }
+      ok(true, 'Verified the first pixel of initial screenshot is opaque');
+
       iframe1.src = 'data:text/html,<html>' +
-        '<body style="background:blue">hello</body></html>';
+        '<body style="background:transparent">hello</body></html>';
 
-      // Wait until screenshotArrayBuffer !== screenshotArrayBuffers[0].
-      waitForScreenshot(function(screenshotArrayBuffer) {
-        var view1 = new Int8Array(screenshotArrayBuffer);
-        var view2 = new Int8Array(screenshotArrayBuffers[0]);
+      // Wait until screenshotImageData !== screenshotImageDatas[0].
+      waitForScreenshot(function(screenshotImageData) {
+        var view1 = screenshotImageData.data;
+        var view2 = screenshotImageDatas[0].data;
+
         if (view1.length != view2.length) {
           return true;
         }
 
         for (var i = 0; i < view1.length; i++) {
           if (view1[i] != view2[i]) {
             return true;
           }
         }
 
         return false;
-      });
+      }, 'image/png');
     }
-    else if (screenshotArrayBuffers.length === 2) {
+    else if (screenshotImageDatas.length === 2) {
       ok(true, 'Got updated screenshot after source page changed');
+
+      var view = screenshotImageData.data;
+      if (view[3] !== 0) {
+        // The case here will always fail when oop'd on Firefox Desktop,
+        // but not on B2G Emulator
+        // See https://bugzil.la/878003#c20
+
+        var isB2G = (navigator.platform === '');
+        info('navigator.platform: ' + navigator.platform);
+        if (!isB2G && browserElementTestHelpers.getOOPByDefaultPref()) {
+          todo(false, 'The first pixel of updated screenshot is not transparent');
+        } else {
+          ok(false, 'The first pixel of updated screenshot is not transparent');
+        }
+        SimpleTest.finish();
+        return;
+      }
+
+      ok(true, 'Verified the first pixel of updated screenshot is transparent');
       SimpleTest.finish();
     }
   }
 
   // We continually take screenshots until we get one that we are
   // happy with.
-  function waitForScreenshot(filter) {
-    function gotScreenshotArrayBuffer() {
-      // |this| is the FileReader whose result contains the screenshot as an
-      // ArrayBuffer.
+  function waitForScreenshot(filter, mimeType) {
+    function gotImage(e) {
+      // |this| is the Image.
 
-      if (filter(this.result)) {
-        screenshotTaken(this.result);
+      URL.revokeObjectURL(this.src);
+
+      if (e.type === 'error' || !this.width || !this.height) {
+        tryAgain();
+
         return;
       }
+
+      var canvas = document.createElement('canvas');
+      canvas.width = canvas.height = 1000;
+      var ctx = canvas.getContext('2d');
+      ctx.drawImage(this, 0, 0);
+      var imageData = ctx.getImageData(0, 0, 1000, 1000);
+
+      if (filter(imageData)) {
+        screenshotTaken(imageData);
+        return;
+      }
+      tryAgain();
+    }
+
+    function tryAgain() {
       if (--attempts === 0) {
         ok(false, 'Timed out waiting for correct screenshot');
         SimpleTest.finish();
       } else {
         setTimeout(function() {
-          iframe1.getScreenshot(1000, 1000).onsuccess = getScreenshotArrayBuffer;
+          iframe1.getScreenshot(1000, 1000, mimeType).onsuccess =
+            getScreenshotImageData;
         }, 200);
       }
     }
 
-    function getScreenshotArrayBuffer(e) {
-      var fr = new FileReader();
-      fr.onloadend = gotScreenshotArrayBuffer;
-      fr.readAsArrayBuffer(e.target.result);
+    function getScreenshotImageData(e) {
+      var blob = e.target.result;
+      if (blob.type !== mimeType) {
+        ok(false, 'MIME type of screenshot taken incorrect');
+        SimpleTest.finish();
+      }
+
+      if (blob.size === 0) {
+        tryAgain();
+
+        return;
+      }
+
+      var img = new Image();
+      img.src = URL.createObjectURL(blob);
+      img.onload = img.onerror = gotImage;
     }
 
     var attempts = 10;
-    iframe1.getScreenshot(1000, 1000).onsuccess = getScreenshotArrayBuffer;
+    iframe1.getScreenshot(1000, 1000, mimeType).onsuccess =
+      getScreenshotImageData;
   }
 
   function iframeLoadedHandler() {
     numLoaded++;
     if (numLoaded === 2) {
-      waitForScreenshot(function(screenshotArrayBuffer) {
-        return screenshotArrayBuffer.byteLength != 0;
-      });
+      waitForScreenshot(function(screenshotImageData) {
+        return true;
+      }, 'image/jpeg');
     }
   }
 
   iframe1.addEventListener('mozbrowserloadend', iframeLoadedHandler);
 }
 
 addEventListener('testready', runTest);
--- a/dom/browser-element/mochitest/test_browserElement_oop_GetScreenshot.html
+++ b/dom/browser-element/mochitest/test_browserElement_oop_GetScreenshot.html
@@ -6,14 +6,15 @@ https://bugzilla.mozilla.org/show_bug.cg
 <head>
   <title>Test for Bug 753595</title>
   <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <script type="application/javascript" src="browserElementTestHelpers.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
 </head>
 <body>
 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=753595">Mozilla Bug 753595</a>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=878003">Mozilla Bug 878003</a>
 
 <script type="application/javascript;version=1.7" src='browserElement_GetScreenshot.js'>
 </script>
 
 </body>
 </html>